I'm working on a basic implementation of a DirectShow filtergraph to get images from my webcam in my application. I've read the documentation and created a simple implementation. I create this graph: device --> samplegrabber -> nullrenderer.
I'm checking all the result values I possibly can and I get no errors form the SDK.
The problem:
Somehow my callback is being called correctly, but whenever I add any code inside the callback functions (this counts for both SampleCB and BufferCB) my application crashes silently.
I've added a breakpoint in my BufferCB and I see that 'this' is 0x0000000 / NULL. Because I check all the result values when I create my graph, my guess is that my graph setup is correct and that this problem could be related to COM.. but this is just a wild guess.
Because the Windows 7.0 SDK does not provide a qedit.h, which contains the interface for the ISampleGrabber interface, I created this file myself and added the relevant interface (I found the contents somewhere on a post while googling).
I copied the saveGraph function from the documentation so I could test the graph in GraphEdit. When I add a render node, I see that automatically a color conversion node is edit by GraphEdit. When I run the graph with a renderer I can see the images from the webcam (in graphedit).
I've pasted all relevat code in this gist (with a callstack trace + variables)
Does someone have any idea how I can debug this or what this error might be? Could it be COM related?
Update: callstack when trying to access a member in my ISampleGrabberCB
ntdll.dll!_ZwRaiseException@12() + 0x12 bytes
ntdll.dll!_ZwRaiseException@12() + 0x12 bytes
msvcr100d.dll!__lock_fhandle(int fh) Line 467 C
qedit.dll!CSampleGrabber::Receive() + 0x18c bytes
qedit.dll!CTransformInputPin::Receive() + 0x33 bytes
quartz.dll!CBaseOutputPin::Deliver() + 0x22 bytes
quartz.dll!CVideoTransformFilter::Receive() + 0x1aa bytes
quartz.dll!CTransformInputPin::Receive() + 0x33 bytes
quartz.dll!CBaseInputPin::ReceiveMultiple() + 0x33 bytes
qcap.dll!COutputQueue::ThreadProc() + 0x103 bytes
qcap.dll!COutputQueue::InitialThreadProc() + 0x16 bytes
kernel32.dll!@BaseThreadInitThunk@12() + 0x12 bytes
ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes
ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes
Thanks
Since qedit.h is no longer on Windows SDK you have to get definition of Sample Grabber related interfaces. One method is to use older SDK with all headers still on it. Another method is to #import
the interfaces from type library. And you can always re-defined them right in code.
You can grab the correct definition from there:
struct __declspec(uuid("0579154a-2b53-4994-b0d0-e773148eff85"))
ISampleGrabberCB : IUnknown
{
virtual HRESULT __stdcall SampleCB (double SampleTime, struct IMediaSample * pSample ) = 0;
virtual HRESULT __stdcall BufferCB (double SampleTime, unsigned char * pBuffer, long BufferLen ) = 0;
};
Because you did not have __stdcall
on yours, the wrong calling convention was used and your this
was NULL
.