Date

ここで作成したソースフィルタに対して独自のインターフェイスを追加する。具体的には、出力される色の明るさを変更するインターフェイス IColor を定義する。それをCMySource クラスに実装する。分かりやすくするためクラス名を CMySourceEx と変更する。

インターフェイスを定義

IColorインターフェイスを定義する。IUnknown を派生する。これにより他のインターフェイスと同様に参照カウンタによる生存管理ができる。

インターフェイスは C++ では純粋仮想関数だけで構成したクラスだが、Visual C++ の拡張で__interfaceがあるので、それを使う。

1
2
3
4
5
6
7
8
// 色設定インターフェイス
__interface
__declspec(uuid("{86A96761-8CA0-4d6a-94F7-F73DF2D5F0D6}"))
    IColor : public IUnknown {
public:
    STDMETHODIMP SetColor(DWORD color);
    STDMETHODIMP GetColor(DWORD *pColor);
};

__declspec(uuid(...)) はインターフェイスやクラスに ID を割り当てられる。参照するときは __uuidofを使う。

ソースフィルタへの実装

IColor を実装

ソースフィルタにIColorインターフェイスを実装する。

ソースフィルタクラス CMySourceExIColor を派生するように定義を修正する。

1
2
3
4
5
6
7
8
9
// ソースフィルタクラス
class CMySourceEx : CSource, public IColor {
  // ...
  //IColor
  STDMETHODIMP SetColor(DWORD color);
  STDMETHODIMP GetColor(DWORD *pColor);
private:
  DWORD m_Color;
};
1
2
3
4
5
6
7
8
STDMETHODIMP CMySourceEx::SetColor(DWORD color) {
    m_Color=color;
    return S_OK;
}
STDMETHODIMP CMySourceEx::GetColor(DWORD *pColor) {
    *pColor=m_Color;
    return S_OK;
}

インターフェイスの問い合わせに対応する

CMySourceExCUnknown::NonDelegatingQueryInterface メソッドを追加し、IColorインターフェイスの問い合わせに対応する。

1
2
3
4
5
6
STDMETHODIMP CMySourceEx::NonDelegatingQueryInterface(REFIID riid, void **ppv) {
    if (riid == __uuidof(IColor)) {
        return GetInterface(static_cast<IColor*>(this), ppv);
    }
    return CSource::NonDelegatingQueryInterface(riid, ppv);
}

NonDelegatingQueryInterface は、指定したインターフェイス ID が、クラスに実装されている場合、そのポインタを返すメソッドである。IUnknown::QueryInterface と役割は同じだが、こちらはCUnknownという DirectShow の基底クラスライブラリの実装である。

出力画像を色の変更に対応させる

今までは青色一色(0x0000ff)のみ対応していたので、これを可変にするようCPushPin::FillBufferを書き換える。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
HRESULT CPushPin::FillBuffer(IMediaSample *pSample){
    HRESULT hr;
    CheckPointer(pSample,E_POINTER);
// 中略
    DWORD value;
    IColor *pColor=NULL;
    hr=m_pFilter->QueryInterface(__uuidof(IColor),(void**)&pColor);
    pColor->GetColor(&value);
    pColor->Release();
    for(int x=0;x<640;x++){
        for(int y=0;y<480;y++){
            *pWrite++=value;
        }
    }

フィルタのインスタンスを作成したらQueryInterfaceで問い合わせるとインターフェイスを取得できる。引数のインターフェイス ID は __uuidof(IColor) とする。


Comments

comments powered by Disqus