フィルターの状態

フィルターには、停止、一時停止、実行の3つの状態があります。 一時停止状態の目的は、graph でデータをキューに置いて、run コマンドが直ちに応答するようにすることです。 フィルターグラフマネージャーは、すべての状態遷移を制御します。 アプリケーションが Imediacontrol:: Runi:P medi、または Imediacontrol:: Stopを呼び出すと、フィルターグラフマネージャーは、すべてのフィルターに対応する imediacontrol メソッドを呼び出します。 停止中と実行中の間の遷移は常に一時停止状態になります。そのため、停止したグラフでアプリケーション を呼び出すと、実行前 にグラフが一時停止されます。

ほとんどのフィルターでは、実行中と一時停止中の状態は同一です。 次のフィルターグラフについて考えてみましょう。

ソース > 変換 > レンダラー

ソースフィルターがライブキャプチャソースではないことを前提としています。 ソースフィルターが一時停止すると、新しいデータを生成するスレッドが作成され、できるだけ早くメディアサンプルに書き込まれます。 スレッドは、変換フィルターの入力ピンで Imeminputpin:: Receive を呼び出すことにより、サンプルを下流に "プッシュ" します。 変換フィルターは、ソースフィルターのスレッドでサンプルを受け取ります。 このサンプルは、ワーカースレッドを使用してレンダラーに配信することができますが、通常は同じスレッドに配布します。 レンダラーは一時停止中に、サンプルの受信を待機します。 受信した後は、そのサンプルをブロックして無期限に保持します。 ビデオレンダラーの場合は、サンプルをポスター画像として表示し、必要に応じてイメージを再描画します。

この時点で、ストリームは完全にキューに入れられ、レンダリングの準備ができています。 グラフが一時停止状態のままになっている場合、各フィルターが Receive または Imemallocator:: GetBufferでブロックされるまで、サンプルは最初のサンプルの背後にあるグラフに "山アップ" します。 ただし、データは失われません。 ソーススレッドのブロックが解除されると、ブロックされた時点から再開されます。

ソースフィルターと変換フィルターでは、一時停止から実行中への移行は無視されます。データはできるだけ高速に処理されます。 しかし、レンダラーを実行すると、レンダリングのサンプルが開始されます。 まず、一時停止中に保持されていたサンプルをレンダリングします。 次に、新しいサンプルを受け取るたびに、サンプルのプレゼンテーション時間を計算します。 (詳細については、「 DirectShow の時刻とクロック」を参照してください)。レンダラーは、各サンプルをプレゼンテーション時間まで保持します。この時点で、サンプルがレンダリングされます。 プレゼンテーション時間を待機している間は、 Receive メソッドをブロックするか、キューを使用してワーカースレッドで新しいサンプルを受信します。 レンダラーからの上流のフィルターは、スケジュール設定には関係しません。

キャプチャデバイスなどのライブソースは、この一般的なアーキテクチャの例外です。 ライブソースを使用する場合、事前にデータをキューに置いておくのは適切ではありません。 アプリケーションは、グラフを一時停止し、実行する前に長い時間待機することがあります。 グラフで "古い" サンプルをレンダリングすることはできません。 したがって、ライブソースは、の実行中にのみ、一時停止中にサンプルを生成しません。 この事実をフィルターグラフマネージャーに通知するために、ソースフィルターの Imediafilter:: GetState メソッドは VFW のキューを返し _ _ _ ません。 このリターンコードは、レンダラーによってデータが受信されなかった場合でも、フィルターが一時停止状態に切り替わったことを示します。

フィルターが停止すると、それ以上のサンプルが配信されなくなります。 ソースフィルターは、ストリーミングスレッドをシャットダウンします。他のフィルターは、作成したすべてのワーカースレッドをシャットダウンします。 ピンは、アロケーターをデコミットします。

状態遷移

フィルターグラフマネージャーは、すべての状態遷移をアップストリームの順序で実行します。これはレンダラーから開始し、ソースフィルターに戻るために使用されます。 この順序は、サンプルが削除されないようにしたり、グラフがデッドロックしたりしないようにするために必要です。 最も重大な状態遷移は、一時停止と停止の間です。

  • 一時停止に停止: 各フィルターが一時停止すると、次のフィルターからサンプルを受信できるようになります。 ソースフィルターは最後に一時停止します。 ストリーミングスレッドが作成され、サンプルの配信が開始されます。 すべてのダウンストリームフィルターが一時停止されているため、どのフィルターもサンプルを拒否します。 フィルターグラフマネージャーでは、グラフ内のすべてのレンダラーがサンプルを受信するまで、移行は完了しません (前述のようにライブソースを除きます)。
  • 停止するまで一時停止: フィルターが停止すると、そのフィルターで保持されているすべてのサンプルが解放され、 GetBufferで待機している上流フィルターのブロックが解除されます。 フィルターが receive メソッド内のリソースを待機している場合は、待機を停止し、呼び出し元のフィルターのブロックを解除する receive から戻ります。 そのため、フィルターグラフマネージャーが次のアップストリームフィルターを停止すると、そのフィルターは GetBuffer または Receive でブロックされないため、stop コマンドに応答できます。 アップストリームフィルターでは、stop コマンドを取得する前にいくつかの追加のサンプルが提供される場合がありますが、ダウンストリームフィルターは既に停止しているため、単純に拒否されます。

フィルターグラフのデータフロー