First, declare a class inherited from ISampleGrabberCB:
class CMyCB : public ISampleGrabberCB {
public:
STDMETHODIMP QueryInterface(REFIID riid, void **ppv) {
if (NULL == ppv) return E_POINTER;
if (riid == __uuidof(IUnknown))
{
*ppv = static_cast<IUnknown*>(this);
return S_OK;
}
if (riid == __uuidof(ISampleGrabberCB))
{
*ppv = static_cast<ISampleGrabberCB*>(this);
return S_OK;
}
return E_NOINTERFACE;
};
STDMETHODIMP_(ULONG) AddRef() {
return S_OK;
};
STDMETHODIMP_(ULONG) Release() {
return S_OK;
};
//ISampleGrabberCB
STDMETHODIMP SampleCB(double SampleTime, IMediaSample *pSample);
STDMETHODIMP BufferCB(double SampleTime, BYTE *pBuffer, long BufferLen) { return S_OK; };
};
Then add drawing logic to SampleCB method:
STDMETHODIMP CMyCB::SampleCB(double SampleTime, IMediaSample *pSample)
{
if (!pSample) return E_POINTER;
long sz = pSample->GetActualDataLength();
BYTE *pBuf = NULL;
pSample->GetPointer(&pBuf);
//draw to pBuf here...
return NOERROR;
}
Create an object of that class, let's name it pMyCB;
When you build your graph add a Sample Grabber:
CComPtr<IBaseFilter> pGrabber;
pGrabber.CoCreateInstance(CLSID_SampleGrabber);
pGraph->AddFilter(pGrabber, L"Grabber");
CComQIPtr<ISampleGrabber> pSG( pGrabber );
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB32; //or what colorspace you work in
pSG->SetMediaType(&mt);
pSG->SetCallback(pMyCB, 0);
Then connect decoder to sample grabber and sample grabber to video renderer.
After you run the graph for each video frame SampleCB method will be called and pBuf will point to array of width * height * 4 bytes: blue, green, red and alpha (unused) for each pixel. If your device provides video in another colorspace (like YUY2) and you don't want to waste time on conversion then change mt.subtype accordingly and learn how pixels are stored in YUY2 (a bit more complicated than RGB32).
No worries about timing. Your callback receives sample time (elapsed since starting the graph) in seconds as a double. You can also query pSample for additional info like its mediatype, including width and height.
Just one note: only the first sample will contain mediatype, so if you need this info get it from the first one and remember.