通知処理の実装
今回はストリーム終了通知のみ実装します。ストリーム終了通知を受け取るとAudioInPin::EndOfStream
が呼ばれます。ここでm_EOS
をtrue
に設定します。「サンプルの受信」で説明したように、true
に設定すると、それ以降のサンプルの受信を拒否します。2つの入力ピンが通知を受け取ったらダウンストリームフィルタへ通知を転送します。AudioInPin::Active
でfalse
に設定します。
HRESULT AudioInPin::Active(void) { m_EOS=false; return __super::Active(); } STDMETHODIMP AudioInPin::EndOfStream(void) { CAutoLock my_lock(m_pLock); m_EOS=true; HRESULT hr=CheckStreaming(); if(hr!=S_OK) { return hr; } AudioChMuxerFilter *filter=(AudioChMuxerFilter*)m_pFilter; // 2つの入力ピンとも通知を受け取っている? if (filter->GetInPin(0)->GetEOS() && filter->GetInPin(1)->GetEOS()) { AudioOutPin *out=filter->GetOutPin(); out->DeliverEndOfStream(); } return S_OK; }
今回はフラッシュ通知と新セグメント通知の処理を実装していないのでシークはできません。結合処理を行うフィルタは、主にAVIなど何らかのファイルを書き出すときに使われます。この場合、ユーザーはシーク操作を行いませんから、実装不要です。もしシークをサポートする必要がある場合は、2つの入力ピンから異なるタイミングで通知が来ることを考慮して実装する必要があります。
動作確認
GraphEditを使って動作確認を行いましょう。あらかじめ、周波数、サンプルあたりのビット数、記録されているサンプル数が全て同じモノラルのWAVファイルを用意し、フィルタに入力します(図5)。
まとめ
今回は2つのモノラルオーディオストリームを結合するフィルタを作成しました。 これでDirectShowフィルタの中では実装が難しい分離、結合を行うフィルタが作れるようになったと思います。
入力ピン、出力ピンが複数あるフィルタでは、ストリーミングスレッドがフィルタ内部に複数存在することを常に意識する必要があります。また、各種通知処理をどのように処理するのか、仕様をきちんと決めておくことが大切です。
参考文献
- MSDN『DirectShow』
- Windows SDK のサンプルコード