Хорошо. Итак, у меня есть метод обратного вызова isamplegrabber, и я могу получить данные в opencv. Но из-за того, что это абсолютно ново для меня, я просто хочу получить некоторую обратную связь, если код «правильный», потому что он не кажется хорошим ..
Сначала в моем коде (из интернета) я получил:
#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
И позже, с большой помощью из Интернета, я вставил это:
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;
И я использую:
pSampleGrabber->SetCallback(&callbackF,0);
Все работает, но мне интересно.
Нужно ли создавать новый класс для метода обратного вызова? Я вижу все методы в «#pragma region …». Разве я не могу использовать эти методы для обратного вызова?
вопросы):
один: Нужно ли иметь этот класс «fakeCallback» для метода sampleCB / bufferCB? Или я могу каким-то образом использовать методы в первой части кода?
два: «виртуальный» — метод, означает, что этот метод можно «перезаписать»? это то, что я делаю при создании класса fakeCallback, с методами sampleCB & bufferCB?
Спасибо!
Если вы просто хотите получить кадр из графа фильтра с помощью обратного вызова, вам необходимо реализовать интерфейс ISampleGrabberCB.
Вы уже реализовали CFakeCallback, который требуется для использования интерфейса ISampleGrabberCB. Вы можете получить образец, используя BufferCB или SampleCB. Поэтому, когда вы реализуете CFakeCallback, вам нужно переопределить как SampleCB, так и BufferCB. Один из них будет содержать ваш собственный код для выборки, а другой вернет просто S_OK (0). В вашем коде вы используете SampleCB, что правильно.
Однако, если вы не хотите использовать метод обратного вызова, то SampleGrabber уже присутствует в Windows SDK. Вам просто нужно включить qedit.h в ваше приложение, и все готово.
Других решений пока нет …