キャプチャ グラフ ビルダーを使用したグラフの作成
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、および Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]
その名前にもかかわらず、Capture Graph Builder は、グラフをキャプチャするだけでなく、さまざまな種類のカスタム フィルター グラフを構築するのに役立ちます。 この記事では、このオブジェクトの使用方法の概要について説明します。
Capture Graph Builder は 、ICaptureGraphBuilder2 インターフェイスを公開します。 まず 、CoCreateInstance を呼び出して、キャプチャ グラフ ビルダーとフィルター グラフ マネージャーを作成します。 次に、次のようにフィルター グラフ マネージャーへのポインターを使用して ICaptureGraphBuilder2::SetFiltergraph を呼び出して、Capture Graph Builder を初期化します。
IGraphBuilder *pGraph = NULL;
ICaptureGraphBuilder2 *pBuilder = NULL;
// Create the Filter Graph Manager.
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);
if (SUCCEEDED(hr))
{
// Create the Capture Graph Builder.
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
(void **)&pBuilder);
if (SUCCEEDED(hr))
{
pBuilder->SetFiltergraph(pGraph);
}
};
フィルターの接続
ICaptureGraphBuilder2::RenderStream メソッドは、チェーン内の 2 つまたは 3 つのフィルターを接続します。 一般に、この方法は、各フィルターに同じ種類の入力ピンまたは出力ピンが 1 つ以上ない場合に最適です。 ここでは、まず RenderStream の最初の 2 つのパラメーターを無視し、最後の 3 つのパラメーターに注目します。 3 番目のパラメーターは IUnknown ポインターであり、フィルター ( IBaseFilter インターフェイス ポインターとして) または出力ピン ( IPin インターフェイス ポインターとして) を指定できます。 4 番目と 5 番目のパラメーターは 、IBaseFilter ポインターを指定します。 RenderStream メソッドは、チェーン内の 3 つのフィルターすべてを接続します。 たとえば、 A、 B、 C がフィルターであるとします。 ここでは、各フィルターに 1 つの入力ピンと 1 つの出力ピンがあるとします。 次の呼び出しは、A を B に接続し、B を C に接続します。
- 'RenderStream(NULL, NULL, A, B, C)'
すべての接続は "インテリジェント" です。つまり、必要に応じて追加のフィルターがグラフに追加されます。 詳細については、「 インテリジェント接続」を参照してください。 2 つのフィルターのみを接続するには、中央の値を NULL に設定します。 たとえば、この呼び出しは A を C に接続します。
- 'RenderStream(NULL, NULL, A, NULL, C)'
メソッドを 2 回呼び出すことで、より長いチェーンを作成できます。
- 'RenderStream(NULL, NULL, A, B, C)' 'RenderStream(NULL, NULL, C, D, E)'
最後のパラメーターが NULL の場合、メソッドは既定のレンダラーを自動的に検索します。 ビデオにはビデオ レンダラーを使用し、オーディオには DirectSound レンダラーを使用します。 したがって:
- 'RenderStream(NULL, NULL, A, NULL, NULL)'
上記の式は、次の式と同じです。
- 'RenderStream(NULL, NULL, A, NULL, R)'
ここで、R は適切なレンダラーです。 ただし、Video Renderer の代わりに Video Mixing Renderer フィルターを接続するには、明示的に指定する必要があります。
ピンではなく 3 番目のパラメーターでフィルターを指定する場合は、接続に使用する出力ピンを指定する必要がある場合があります。 これが、メソッドの最初の 2 つのパラメーターの目的です。 最初のパラメーターは、キャプチャ フィルターにのみ適用されます。 ピン カテゴリを示す GUID を指定します。 カテゴリの完全な一覧については、「 プロパティ セットをピン留めする」を参照してください。 次の 2 つのカテゴリは、すべてのキャプチャ フィルターに対して有効です。
- PIN_CATEGORY_CAPTURE
- PIN_CATEGORY_PREVIEW
キャプチャ フィルターでキャプチャとプレビュー用に個別のピンが提供されない場合、 RenderStream メソッドは Smart Tee フィルターを挿入します。これにより、ストリームがキャプチャ ストリームとプレビュー ストリームに分割されます。 アプリケーションの観点から、すべてのキャプチャ フィルターを個別のピンとして扱い、グラフの基になるトポロジを無視することができます。
ファイル キャプチャの場合は、キャプチャ ピンを mux フィルターに接続します。 ライブ プレビューの場合は、プレビュー ピンをレンダラーに接続します。 2 つのカテゴリを切り替えると、ファイル キャプチャ中にグラフに過剰な数のフレームがドロップされる可能性があります。ただし、グラフが正しく接続されている場合は、キャプチャ ストリームのスループットを維持するために、必要に応じてプレビュー フレームが削除されます。
次の例は、両方のストリームを接続する方法を示しています。
// Capture to file:
pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, NULL, pCapFilter, NULL, pMux);
// Preview:
pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, NULL, pCapFilter, NULL, NULL);
一部のキャプチャ フィルターでは、 PIN_CATEGORY_VBIで示されるクローズド キャプションもサポートされています。 クローズド キャプションをファイルにキャプチャするには、このカテゴリを mux フィルターにレンダリングします。 プレビュー ウィンドウでクローズド キャプションを表示するには、レンダラーに接続します。
// Capture to file:
pBuilder->RenderStream(&PIN_CATEGORY_VBI, NULL, pCapFilter, NULL, pMux);
// Preview on screen:
pBuilder->RenderStream(&PIN_CATEGORY_VBI, NULL, pCapFilter, NULL, NULL);
RenderStream の 2 番目のパラメーターはメディアの種類を識別し、通常は次のいずれかです。
- MEDIATYPE_Audio
- MEDIATYPE_Video
- MEDIATYPE_Interleaved (DV)
フィルターの出力ピンで優先メディアの種類の列挙がサポートされている場合は常に、このパラメーターを使用できます。 ファイル ソースの場合、Capture Graph Builder は必要に応じてパーサー フィルターを自動的に追加し、パーサーのメディアの種類に対してクエリを実行します。 (例については、「 AVI ファイルの再圧縮」を参照してください)。また、チェーン内の最後のフィルターに複数の入力ピンがある場合、メソッドはメディアの種類を列挙しようとします。 ただし、すべてのフィルターがこの機能をサポートしているわけではありません。
フィルターとピンのインターフェイスの検索
グラフを作成した後は、通常、グラフ内のフィルターとピンによって公開されるさまざまなインターフェイスを見つける必要があります。 たとえば、キャプチャ フィルターは IAMDroppedFrames インターフェイスを公開し、フィルターの出力ピンは IAMStreamConfig インターフェイスを公開する場合があります。
インターフェイスを見つける最も簡単な方法は、 ICaptureGraphBuilder2::FindInterface メソッドを使用することです。 このメソッドは、目的のインターフェイスが見つかるまでグラフ (フィルターとピン) をウォークします。 検索の開始点を指定でき、検索を制限して、開始点から上流または下流にフィルターを適用できます。
次の例では、ビデオ プレビュー ピンで IAMStreamConfig インターフェイスを検索します。
IAMStreamConfig *pConfig = NULL;
HRESULT hr = pBuild->FindInterface(
&PIN_CATEGORY_PREVIEW,
&MEDIATYPE_Video,
pVCap,
IID_IAMStreamConfig,
(void**)&pConfig
);
if (SUCCESSFUL(hr))
{
/* ... */
pConfig->Release();
}
注意
「フィルターまたはピンでインターフェイスを検索する」トピックでは、ICaptureGraphBuilder2 の代わりに IGraphBuilder インターフェイスを使用する別の方法を示します。 どの方法を使用するかは、アプリケーションによって異なります。 アプリケーションで既に ICaptureGraphBuilder2 を使用してグラフを作成している場合は、 ICaptureGraphBuilder2::FindInterface を使用することをお勧めします。 それ以外の場合は、 IGraphBuilder メソッドの使用を検討してください。
ピンの検索
あまり一般的ではありませんが、フィルターで個々のピンを見つける必要がある場合がありますが、ほとんどの場合、 RenderStream メソッドと FindInterface メソッドを使用すると問題が解決します。 フィルターで特定のピンを見つける必要がある場合は、 ICaptureGraphBuilder2::FindPin ヘルパー メソッドが役立ちます。 カテゴリ、メディアの種類 (ビデオまたはオーディオ)、方向、およびピンを接続解除する必要があるかどうかを指定します。
たとえば、次のコードでは、キャプチャ フィルターで未接続のビデオ プレビュー ピンを検索します。
IPin *pPin = NULL;
hr = pBuild->FindPin(
pCap, // Pointer to the filter to search.
PINDIR_OUTPUT, // Search for an output pin.
&PIN_CATEGORY_PREVIEW, // Search for a preview pin.
&MEDIATYPE_Video, // Search for a video pin.
TRUE, // The pin must be unconnected.
0, // Return the first matching pin (index 0).
&pPin); // This variable receives the IPin pointer.
if (SUCCESSFUL(hr))
{
/* ... */
pPin->Release();
}
関連トピック