フィルタクラスの実装
クラス定義
フィルタクラスAudioChSplitterFilterをCBaseFilterから派生して定義します。その際 GetPinCountとGetPinの 2つのメソッドが基底クラスにおいて純粋仮想メソッドとして定義されているので、このクラスで実装しなければなりません(表3)。加えて、フィルタロックを宣言する必要があります。
| メソッド名 | 説明 |
| GetPinCount | ピンの数を取得する。 |
| GetPin | ピンへのポインタを取得する。 |
class AudioChSplitterFilter : CBaseFilter
{
CCritSec m_FilterLock; // フィルタロック
AudioInPin *m_InPin;
AudioOutPin *m_OutPins[2];
public:
static CUnknown * WINAPI
CreateInstance(LPUNKNOWN pUnk, HRESULT *phr);
AudioChSplitterFilter(LPUNKNOWN pUnk, HRESULT *phr);
virtual ~AudioChSplitterFilter();
AudioInPin *GetInPin() { return m_InPin; }
AudioOutPin *GetOutPin(int n) { return m_OutPins[n]; }
// CBaseFilter
int GetPinCount(void);
CBasePin *GetPin(int n);
};
フィルタグラフを実行するとき、それを制御するアプリケーションスレッドの他に、サンプルを流すための1つ以上のストリーミングスレッドが作成されます。そのためフィルタ状態の整合性を保つ必要があります。これをクリティカルセクションで実現します。基底クラスライブラリのCCritSecを使うとスマートポインタのようにコンストラクタでロック、デストラクタでアンロックされるので便利です。
コンストラクタ・デストラクタ
コンストラクタでは、派生元であるCBaseFilterを初期化し、入出力ピンのインスタンスを作成・初期化します。入出力ピンには、このフィルタのインスタンスへのポインタとフィルタロックを渡しておきます。
AudioChSplitterFilter::AudioChSplitterFilter
(LPUNKNOWN pUnk, HRESULT *phr) :
m_FilterLock(),
CBaseFilter(FILTER_NAME, pUnk,
&m_FilterLock, __uuidof(AudioChSplitterFilter))
{
NOTE1("%S", __FUNCTION__);
DbgLockTrace(&m_FilterLock, TRUE);
m_InPin=new AudioInPin(this, &m_FilterLock, phr);
m_OutPins[0]=new AudioOutPin(
LOUT_PIN_NAME, this, &m_FilterLock, phr, 0);
m_OutPins[1]=new AudioOutPin(
ROUT_PIN_NAME, this, &m_FilterLock, phr, 1);
}
デストラクタは、入出力ピンのインスタンスをdeleteで解放するだけです(本稿添付ソースコードを参照)。
ピン数を取得できるようにする
フィルタクラスからピンの数を取得するメソッドGetPinCountを実装します。今回は数が固定なので常に3を返します。ちなみに、可変の場合は現在もっているピンの数を返すようにします。
int AudioChSplitterFilter::GetPinCount(void) {
return 3;
}
ピンへのポインタを取得できるようにする
ピンへのポインタを取得するメソッドGetPinを実装します。引数として0から始まるインデックス値が渡されるので、それに対応したピンへのポインタを返します。
CBasePin *AudioChSplitterFilter::GetPin(int n) {
switch(n) {
case 0:
return m_InPin;
case 1:
return m_OutPins[0];
case 2:
return m_OutPins[1];
}
return NULL;
}
