Okay. So I've got my isamplegrabber callback method to work, and I am able to get the data into opencv. But due to the fact that this is totally new to me, I just want to get some feedback if the code is "correct", cause it doesn't seem to be a good one..
At first in my code (from internet) I've got:
#pragma region Formerly located in qedit.h in Windows SDK, now obsoleted and defined within project
void createDirectShowGraph(void);
struct __declspec(uuid("0579154a-2b53-4994-b0d0-e773148eff85"))
ISampleGrabberCB : IUnknown
{
//
// Raw methods provided by interface
//
virtual HRESULT __stdcall SampleCB (double SampleTime, struct IMediaSample * pSample ) = 0;
virtual HRESULT __stdcall BufferCB (double SampleTime, unsigned char * pBuffer, long BufferLen ) = 0;
};
static const IID IID_ISampleGrabberCB = { 0x0579154A, 0x2B53, 0x4994, { 0xB0, 0xD0, 0xE7, 0x73, 0x14, 0x8E, 0xFF, 0x85 } };
struct __declspec(uuid("6b652fff-11fe-4fce-92ad-0266b5d7c78f"))
ISampleGrabber : IUnknown
{
//
// Raw methods provided by interface
//
virtual HRESULT __stdcall SetOneShot (long OneShot ) = 0;
virtual HRESULT __stdcall SetMediaType (struct _AMMediaType * pType ) = 0;
virtual HRESULT __stdcall GetConnectedMediaType (struct _AMMediaType * pType ) = 0;
virtual HRESULT __stdcall SetBufferSamples (long BufferThem ) = 0;
virtual HRESULT __stdcall GetCurrentBuffer (/*[in,out]*/ long * pBufferSize,
/*[out]*/ long * pBuffer ) = 0;
virtual HRESULT __stdcall GetCurrentSample (/*[out,retval]*/ struct IMediaSample * * ppSample ) = 0;
virtual HRESULT __stdcall SetCallback (struct ISampleGrabberCB * pCallback,long WhichMethodToCallback ) = 0;
};
struct __declspec(uuid("c1f400a0-3f08-11d3-9f0b-006008039e37"))
SampleGrabber;
// [ default ] interface ISampleGrabber
#pragma endregion
And later, with much help from the internet, I inserted this:
class CFakeCallback : public ISampleGrabberCB
{
public:
//some variables and stuff...
STDMETHODIMP_(ULONG) AddRef() { return 2; }
STDMETHODIMP_(ULONG) Release() { return 1; }
STDMETHODIMP QueryInterface(REFIID riid, void ** ppv)
{
//CheckPointer(ppv, E_POINTER);
if (riid == IID_ISampleGrabberCB || riid == IID_IUnknown)
{
*ppv = (void *) static_cast<ISampleGrabberCB *>(this);
return NOERROR;
}
return E_NOINTERFACE;
}
STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample )
{
//The data for grabbing the frames.
}
STDMETHODIMP BufferCB( double SampleTime, BYTE * pBuffer, long BufferLen )
{
return 0;
}
};
CFakeCallback callbackF;
And I use:
pSampleGrabber->SetCallback(&callbackF,0);
Everything works, but I wonder. Do i need to create a new class for the callback method? I can see the all the methods in the "#pragma region..." Can't I use those methods for the callback?
question(s):
one: Do I need to have that class "fakeCallback" for the sampleCB/bufferCB method? Or can I in some way use the methods in the first code-part?
two: "virtual" - method, means that this method can be "overwritten"? is that what I am doing when creating the class fakeCallback, with methods sampleCB & bufferCB?
Thanks!
If you are just want to grab a frame from the filter graph by using callback then you need to implement ISampleGrabberCB interface. You have already implemented CFakeCallback which is required to use ISampleGrabberCB interface. You can grab the sample either using BufferCB or SampleCB. So when you are implementing CFakeCallback you will need to override both SampleCB and BufferCB. One of them will contain you custom code to grab sample while the other will return just S_OK (0). In you code you are using SampleCB which is correct.
However if you don't want to use callback method then SampleGrabber is already present in Windows SDK. You will just need to include qedit.h in your application and you are done.