DirectShow のData Flowの概要

[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayerIMFMediaEngine、および Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayerIMFMediaEngineAudio/Video Capture を使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]

このセクションでは、DirectShow でのデータ フローのしくみの概要について説明します。 詳細については、ドキュメントの他のセクションを参照してください。

データは、単にバイトの配列であるバッファーに保持されます。 各バッファーは、IMediaSample インターフェイスを実装するメディア サンプルと呼ばれる COM オブジェクトによってラップされます。 サンプルは、 IMemAllocator インターフェイスを実装するアロケーターと呼ばれる別の種類のオブジェクトによって作成されます。 アロケーターはピン接続ごとに割り当てられますが、2 つ以上のピン接続で同じアロケーターを共有する場合があります。 次の図は、このプロセスを示しています。

バッファー、サンプル、アロケーター

各アロケーターは、メディア サンプルのプールを作成し、各サンプルのバッファーを割り当てます。 フィルターは、バッファーにデータを入力する必要がある場合は常に、 IMemAllocator::GetBuffer を呼び出してアロケーターにサンプルを要求します。 アロケーターに別のフィルターで現在使用されていないサンプルがある場合、 GetBuffer メソッドはサンプルへのポインターを使用してすぐにを返します。 アロケーターのすべてのサンプルが使用されている場合、メソッドはサンプルが使用可能になるまでブロックします。 メソッドがサンプルを返す場合、フィルターはデータをバッファーに格納し、サンプルに適切なフラグ (通常はタイム スタンプを含む) を設定して、サンプルをダウンストリームに配信します。

レンダラー フィルターは、サンプルを受け取ると、タイム スタンプをチェックし、フィルター グラフの参照クロックがデータをレンダリングする必要があることを示すまで、サンプルを保持します。 フィルターは、データをレンダリングした後、サンプルを解放します。 サンプルの参照カウントが 0 になるまで、サンプルはアロケーターのサンプル プールに戻りません。つまり、すべてのフィルターによってサンプルが解放されています。 次の図は、このプロセスを示しています。

無料のメディア サンプルを待機しているデコーダー

アップストリーム フィルターはレンダラーの前に実行される可能性があります。つまり、レンダラーがバッファーを使用するよりも高速にバッファーを埋める可能性があります。 それでも、レンダラーはプレゼンテーション時間までそれぞれを保持するため、サンプルは早期にレンダリングされません。 さらに、 GetSample はそれ以外の方法で使用されていないサンプルのみを返すので、アップストリーム フィルターはバッファーを誤って上書きしません。 アップストリーム フィルターを先に実行できる量は、アロケーターのプール内のサンプルの数によって決まります。

前の図は 1 つのアロケーターのみを示していますが、通常はストリームごとに複数のアロケーターがあります。 したがって、レンダラーがサンプルを解放すると、カスケード効果が得られます。 次の図は、レンダラーがサンプルを解放するのを待機している間にデコーダーが圧縮されたビデオ フレームを保持する状況を示しています。 パーサー フィルターは、デコーダーがサンプルを解放するのを待機しています。

サンプルを待機している 2 つのフィルター

レンダラーがそのサンプルを解放すると、デコーダーの GetBuffer の保留中の呼び出しが返されます。 その後、デコーダーは圧縮されたビデオ フレームをデコードし、保持していたサンプルを解放して、パーサーの保留中の GetBuffer 呼び出しのブロックを解除できます。

フィルター グラフのData Flow