AVStream のパイプと回路
パイプは、共通のアロケーターを共有する AVStream フィルターのセットです。
次の図は、ソース フィルター、インプレース変換フィルター、レンダラー フィルターの 3 つの AVStream フィルターで構成されるパイプを示しています。
この例では、KSProxy (図示せず) は、図の Alloc ブロックで表されるアロケーターを選択しています。
AVStream は、ソース フィルターに関連付けられた内部リクエスター オブジェクトを作成します。 この図では、リクエスターは Req として表示されます。ミニドライバーは、メモリの種類とフレームに割り当てる連続メモリの量 KSPIN_DESCRIPTOR_EX の AllocatorFraming メンバーで指定します。 したがって、リクエスターはアロケーターからフレームを取得し、それらを回線内の次のコンポーネントに渡します。
ソース フィルターからのデータは、別の AVStream ドライバーによって実装された変換フィルターに流れます。
最後に、データは、3 番目の AVStream フィルターによって実装されたレンダラー フィルターに流れます。
このグラフ内のすべてのピンは AVStream ピンであるため、AVStream は IoCallDriver を使用して IRP を送信する代わりに独自の内部トランスポート インターフェイスを使用し、待機時間を短縮し、パフォーマンスを向上させます。
具体的には、アプリケーションによってグラフが KSSTATE_ACQUIRE に遷移する場合 (たとえば、ユーザーが GraphEdit で [再生] をクリックした場合)、AVStream は上記のようにフィルター キューに直接接続します。
そのため、ダウンストリームに送信されたフレームは要求元に戻り、レンダリングが完了したときにリサイクルできます。 この AVStream データ パスは回線です。
次の図に示す 2 つ目の例を考えてみましょう。変換フィルターは AVStream フィルターではなく、カーネル モード フィルターのままです。
最初の例と同様に、この例には、AVStream ソース、KS 変換 (KS を直接使用するドライバー、ストリーム クラスのミニドライバーなど)、AVStream レンダラーの 3 つのフィルターが含まれています。
最初の図のように、ピンは最初に相互接続されています。 ただし、フィルター グラフが KSSTATE_ACQUIRE に移行した場合、カーネル ストリーミング 1.0 フィルターは AVStream トランスポート インターフェイスをサポートしません。 その結果、AVStream はピンをバイパスしません。代わりに、I/O を使用してフィルター間でデータを移動する必要があります。
具体的には、フレームがソース フィルターのキューから離れると、AVStream は IoCallDriver を呼び出します。 この呼び出しでは、Irp パラメーターには、変換フィルターにソースの出力ピンから渡すフレームが含まれています。
レンダラーの入力ピンが IRP を受け取ると、ピンは IRP をキューに配置します。 レンダラー ドライバーは、フレームを完了すると、2 番目の例に示すように、レンダラーの入力ピンにフレームを返します。
AVStream が IoCompleteRequest を呼び出してフレーム アップストリームを返すようになりました。 ソース フィルターの出力ピンは完了通知を受け取ります。 ミニドライバーのピン プロセス コールバックルーチンは、KsStreamPointerUnlock を呼び出し、フレームをリクエスターに戻して回線にリサイクルできます。
フレーム ソースがユーザー モードになっている最後の例を考えてみましょう。 (または、最終的なフレームの宛先がユーザー モードである可能性があります)。
次の図では、カーネル モードの非インプレース変換フィルターは、ユーザー モードの DirectShow フィルターからフレームを受信し、変換されたフレームをカーネル モード AVStream レンダラーに送信します。
フレームがユーザー モードから到着すると、AVStream ピン オブジェクトは入力パイプ セクションのキューにフレームを配置します。
非インプレース変換フィルターは、変換されたフレームをカーネル モードで割り当ててから、これらのフレームの回線として 2 番目のパイプを使用します。 レンダラーは AVStream フィルターであるため、AVStream はピンをバイパスし、AVStream トランスポート インターフェイスを使用して、レンダリング フィルターのキューにフレームを直接配置します。
ミニドライバーは、KsPinSubmitFrame または KsPinSubmitFrameMdl を呼び出すことによって、回線にフレームに挿入挿入できます。 ミニドライバーがこのメソッドを使用する場合、AVStream リクエスターは、カーネル モード アロケーターからではなく、これらの呼び出しの結果としてフレームを受信します。