次の方法で共有


キャプチャ グラフ ビルダーを使用したグラフの作成

[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayerIMFMediaEngine、および Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayerIMFMediaEngineAudio/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 つのフィルターすべてを接続します。 たとえば、 ABC がフィルターであるとします。 ここでは、各フィルターに 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();
}

ビデオ キャプチャ