1

わかった。これで、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...」ですべてのメソッドを確認できます。それらのメソッドをコールバックに使用できませんか?

質問:

1: sampleCB/bufferCB メソッドにそのクラス「fakeCallback」が必要ですか? または、最初のコード部分のメソッドを何らかの方法で使用できますか?

2:「仮想」 - メソッド。このメソッドは「上書き」できることを意味しますか? メソッド sampleCB と bufferCB を使用して、クラス fakeCallback を作成するときに私が行っていることは何ですか?

ありがとう!

4

1 に答える 1

1

コールバックを使用してフィルター グラフからフレームを取得するだけの場合は、ISampleGrabberCB インターフェイスを実装する必要があります。ISampleGrabberCB インターフェイスを使用するために必要な CFakeCallback を既に実装しています。BufferCB または SampleCB を使用してサンプルを取得できます。したがって、CFakeCallback を実装するときは、SampleCB と BufferCB の両方をオーバーライドする必要があります。そのうちの 1 つはサンプルを取得するためのカスタム コードを含み、もう 1 つは S_OK (0) だけを返します。あなたのコードでは、正しいSampleCBを使用しています。

ただし、コールバック メソッドを使用したくない場合は、SampleGrabber が Windows SDK に既に存在します。アプリケーションに qedit.h をインクルードするだけで完了です。

于 2013-05-15T11:37:43.777 に答える