c++windowswebcamdirectshowsamplegrabber

DirectShow Sample Grabber being called but 'this' in callback is NULL


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


Solution

  • 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.