B
Builder
Hello,
I created a DirectShow filter which detects faces from video. Filter
exposes interface, which enables to set a callback, which is called
when a face is detected. I made an application in C# which creates a
DirectShow graph with mentioned face detector filter and calls its
interface.
Excerpt of the face detector interface declaration is as follows
(method SetCallback is important):
/// Interface for callbacks
DECLARE_INTERFACE(IFaceCB)
{
STDMETHOD(BufferCB)
(
LONGLONG FaceTime,
BYTE * pBuffer,
long BufferLen
) PURE;
};
DEFINE_GUID(IID_IFaceDetectorFilter, 0x5e3fa349, 0x566e, 0x49f7, 0x99,
0xfe, 0xb9, 0x91, 0x9b, 0xb7, 0xc4, 0x14);
DECLARE_INTERFACE_(IFaceDetectorFilter, IUnknown)
{
...
// Listener (Callback)
STDMETHOD(SetCallback)(IFaceCB * pCallback) PURE;
};
Interface IFaceDetectorFilter is implemented in the class
CFaceDetectorFilter:
class CFaceDetectorFilter : public CTransInPlaceFilter,
public IFaceDetectorFilter,
public ISpecifyPropertyPages,
public CPersistStream
{
public:
...
STDMETHODIMP SetCallback(IFaceCB * pCallback);
void DetectFace();
private:
IFaceCB* m_pCallback;
}
And implementation of the SetCallback method looks like this:
STDMETHODIMP CFaceDetectorFilter::SetCallback(IFaceCB * pCallback)
{
m_pCallback = pCallback;
return NOERROR;
}
and implementation of the method DetectFace looks like this:
void CFaceDetectorFilter:etectFace()
{
LONGLONG timestamp; // time, when face was detected
BYTE* data; // image data of the detected face
long data_lenght; // size of the image data
...
if (m_pCallback != NULL)
m_pCallback->BufferCB(timestamp, data, data_lenght);
}
OK, and now follows code in the C# application, which calls interface
of the Face detector filter. First I had to import filter's
interfaces:
public interface IFaceCB
{
int BufferCB(long FaceTime, IntPtr pBuffer, int BufferLen);
}
[ComImport,
Guid("5E3FA349-566E-49F7-99FE-B9919BB7C414"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IFaceDetectorFilter
{
...
[PreserveSig]
int SetCallback(IFaceCB pCallback);
}
Of course, I implemented IFaceCB interface (and its method BufferCB)
and register it with method SetCallback():
public class FaceDetector : IFaceCB
{
public int BufferCB(long theStartTime, IntPtr theDstBuffer,
int theSize)
{
...
return 0;
}
...
public int Init()
{
int hr;
IBaseFilter ibfFaceDetector = null;
IFaceDetectorFilter faceDetectorFilter = null;
...
// create face detector filter
ibfFaceDetector = (IBaseFilter) new FaceDetectorFilter();
faceDetectorFilter = (IFaceDetectorFilter)ibfFaceDetector;
// register callback
hr = faceDetectorFilter.SetCallback(this);
}
public int Run()
{
// start the DirectShow grapg, start face detection
}
...
}
After running the DirectShow graph (after call Run method), face
detection started. But when first face was detected, callback BufferCB
was called from native code and application freeze. I don't know the
reason. Can anybody help me? Did you already encounter a similar
problem when imported calleback to C# is called from native code?
I created a DirectShow filter which detects faces from video. Filter
exposes interface, which enables to set a callback, which is called
when a face is detected. I made an application in C# which creates a
DirectShow graph with mentioned face detector filter and calls its
interface.
Excerpt of the face detector interface declaration is as follows
(method SetCallback is important):
/// Interface for callbacks
DECLARE_INTERFACE(IFaceCB)
{
STDMETHOD(BufferCB)
(
LONGLONG FaceTime,
BYTE * pBuffer,
long BufferLen
) PURE;
};
DEFINE_GUID(IID_IFaceDetectorFilter, 0x5e3fa349, 0x566e, 0x49f7, 0x99,
0xfe, 0xb9, 0x91, 0x9b, 0xb7, 0xc4, 0x14);
DECLARE_INTERFACE_(IFaceDetectorFilter, IUnknown)
{
...
// Listener (Callback)
STDMETHOD(SetCallback)(IFaceCB * pCallback) PURE;
};
Interface IFaceDetectorFilter is implemented in the class
CFaceDetectorFilter:
class CFaceDetectorFilter : public CTransInPlaceFilter,
public IFaceDetectorFilter,
public ISpecifyPropertyPages,
public CPersistStream
{
public:
...
STDMETHODIMP SetCallback(IFaceCB * pCallback);
void DetectFace();
private:
IFaceCB* m_pCallback;
}
And implementation of the SetCallback method looks like this:
STDMETHODIMP CFaceDetectorFilter::SetCallback(IFaceCB * pCallback)
{
m_pCallback = pCallback;
return NOERROR;
}
and implementation of the method DetectFace looks like this:
void CFaceDetectorFilter:etectFace()
{
LONGLONG timestamp; // time, when face was detected
BYTE* data; // image data of the detected face
long data_lenght; // size of the image data
...
if (m_pCallback != NULL)
m_pCallback->BufferCB(timestamp, data, data_lenght);
}
OK, and now follows code in the C# application, which calls interface
of the Face detector filter. First I had to import filter's
interfaces:
public interface IFaceCB
{
int BufferCB(long FaceTime, IntPtr pBuffer, int BufferLen);
}
[ComImport,
Guid("5E3FA349-566E-49F7-99FE-B9919BB7C414"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IFaceDetectorFilter
{
...
[PreserveSig]
int SetCallback(IFaceCB pCallback);
}
Of course, I implemented IFaceCB interface (and its method BufferCB)
and register it with method SetCallback():
public class FaceDetector : IFaceCB
{
public int BufferCB(long theStartTime, IntPtr theDstBuffer,
int theSize)
{
...
return 0;
}
...
public int Init()
{
int hr;
IBaseFilter ibfFaceDetector = null;
IFaceDetectorFilter faceDetectorFilter = null;
...
// create face detector filter
ibfFaceDetector = (IBaseFilter) new FaceDetectorFilter();
faceDetectorFilter = (IFaceDetectorFilter)ibfFaceDetector;
// register callback
hr = faceDetectorFilter.SetCallback(this);
}
public int Run()
{
// start the DirectShow grapg, start face detection
}
...
}
After running the DirectShow graph (after call Run method), face
detection started. But when first face was detected, callback BufferCB
was called from native code and application freeze. I don't know the
reason. Can anybody help me? Did you already encounter a similar
problem when imported calleback to C# is called from native code?