フィルタ チェーン
"フィルタ チェーン" とは、以下の条件に合致するフィルタの集まりである。
- チェーン内の各フィルタは、最大で、接続された入力ピンを 1 つと、接続された出力ピンを 1 つ持つ。
- チェーンの外部のフィルタを通らなくても、チェーン内のすべてのフィルタを通ることができる。
たとえば、次の図のフィルタ A-B、C-D、および F-G-H がフィルタ チェーンである。F-G-H 内のサブチェーン (F-G および G-H) もフィルタ チェーンである。フィルタ チェーンは 1 つのフィルタで構成してもよいので、フィルタ A、B、C、D、F、G、および H も別々のフィルタ チェーンである。フィルタ E には入力接続が 2 つあるので、フィルタ E を含むフィルタの集まりはフィルタ チェーンではない。
IFilterChain インターフェイスは、フィルタ チェーンを制御するために以下のメソッドを提供している。
IFilterChain::StartChain | チェーンを開始する。 |
IFilterChain::StopChain | チェーンを停止する。 |
IFilterChain::PauseChain | チェーンをポーズする。 |
IFilterChain::RemoveChain | チェーンをグラフから削除する。 |
チェーンを追加するための専用のメソッドはない。チェーンを追加するには、IFilterGraph::AddFilter メソッドを使って新しいフィルタを挿入し、IGraphBuilder::Connect、IGraphBuilder::Render、または同様なメソッドを呼び出してそれらのフィルタを接続する。
グラフの実行中、フィルタ チェーンは実行と停止の間で切り替え可能である。グラフがポーズしているとき、フィルタ チェーンはポーズと停止の間で切り替え可能である。フィルタ チェーンで可能な状態の変化はこれだけである。
フィルタ チェーンのガイドライン
IFilterChain メソッドを使うときは、グラフ内のフィルタがフィルタ チェーンの操作をサポートしていることを確認しなければならない。サポートしていない場合、デッドロックやグラフ エラーが発生することがある。チェーンに接続されたフィルタは、チェーンの状態が変化しても正しく機能しなければならない。
IFilterChain を使う場合は、チェーン処理専用にデザインしたフィルタを使うのが最良である。以下のガイドラインを使って、フィルタ チェーン処理の間にフィルタが安全であることを確実にすること。それらのポイントを次の図に示す。
- フィルタ チェーンの状態が変わる前に、フィルタ チェーンの境界にあるデータ処理の呼び出しがすべて完了していなければならない。この規則は、IMemInputPin::Receive、IPin::NewSegment、および IPin::EndOfStream メソッドに当てはまる。チェーン内のフィルタは、チェーン外部のフィルタによって行われたこれらのメソッドへの呼び出しから戻っていなければならず、チェーン外部のフィルタは、チェーン内のフィルタによって行われた呼び出しから戻っていなければならない。
たとえば、上の図のフィルタ B は、フィルタ A からのデータ処理の呼び出しを完了しなければならず、フィルタ E は、フィルタ D からの呼び出しを完了しなければならない。ピンが IPinFlowControl および IPinConnection インターフェイスを公開している場合は、「動的再接続」で説明したように、IPinFlowControl::Block および IGraphConfig::PushThroughData メソッドを呼び出してデータをグラフに送り出すことができる。フィルタが、データを送り出すためのプライベート メソッドをサポートしている場合もある。
- アップストリーム フィルタは、チェーンの状態が変化することを予測していなければならない。たとえば、上の図で、チェーンが停止しているのにフィルタ A が IMemInputPin::Receive を呼び出したとする。この呼び出しは失敗し、フィルタ A の応答はストリームを停止することである。フィルタ A がデータを流さないので、アプリケーションがチェーンを再起動しても効果がない。
- ダウンストリーム フィルタも、チェーンの状態が変化することを予測していなければならない。そうでなければ、決して到着しないサンプルを待っている間に、ダウンストリーム フィルタはブロックしてしまうかもしれない。たとえば、マルチプレクサ (MUX) フィルタは、そのすべての入力ピンからのデータを必要とすることが多い。ある入力ピンからのデータ フローが停止すると、他のストリームの処理がブロックされる可能性がある。これによって、グラフがデッドロックに陥ることがある。
- チェーン外部のフィルタからチェーン内部のフィルタへのピン接続には、それぞれ他の接続と共有しない独自のアロケータを持たせるべきである。チェーンの状態が変化したり、チェーンがグラフから削除されたりすると、アロケータはデコミットされる場合があるからからだ。他の接続が同じアロケータを使っていた場合、それらの接続はサンプルを処理できなくなる。
- チェーンに接続されたフィルタが動的接続解除をサポートしていない限り、チェーンを削除してはいけない。通常、接続されたフィルタは、IPinConnection または IPinFlowControl インターフェイスをサポートする、しかしプライベート インターフェイスをサポートする場合もある。