キャプチャ グラフの制御
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、および Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]
Filter Graph Manager の IMediaControl インターフェイスには、グラフ全体を実行、停止、一時停止するためのメソッドがあります。 ただし、フィルター グラフにキャプチャ ストリームとプレビュー ストリームがある場合は、2 つのストリームを個別に制御する必要があります。 たとえば、ビデオをキャプチャせずにプレビューすることができます。 これを行うには、 ICaptureGraphBuilder2::ControlStream メソッドを使用します。
注意
このメソッドは、Advanced Systems Format (ASF) ファイルにキャプチャする場合は機能しません。
キャプチャ ストリームの制御
次のコードでは、ビデオ キャプチャ ストリームを 4 秒間実行し、グラフの実行後 1 秒後に開始するように設定します。
// Control the video capture stream.
REFERENCE_TIME rtStart = 10000000, rtStop = 50000000;
const WORD wStartCookie = 1, wStopCookie = 2; // Arbitrary values.
hr = pBuild->ControlStream(
&PIN_CATEGORY_CAPTURE, // Pin category.
&MEDIATYPE_Video, // Media type.
pCap, // Capture filter.
&rtStart, &rtStop, // Start and stop times.
wStartCookie, wStopCookie // Values for the start and stop events.
);
pControl->Run();
最初のパラメーターは、コントロールするストリームをピン カテゴリ GUID として指定します。 2 番目のパラメーターは、メディアの種類を指定します。 3 番目のパラメーターは、キャプチャ フィルターへのポインターです。 グラフ内のすべてのキャプチャ ストリームを制御するには、2 番目と 3 番目のパラメーターを NULL に設定します。
次の 2 つのパラメーターは、グラフの実行を開始する時間を基準にして、ストリームが開始および停止する時間を定義します。 IMediaControl::Run を呼び出してグラフを実行します。 グラフを実行するまで、 ControlStream メソッドは無効になります。 グラフが既に実行されている場合、設定はすぐに有効になります。
最後の 2 つのパラメーターは、ストリームの開始と停止時にイベント通知を取得するために使用されます。 このメソッドを使用して制御するストリームごとに、フィルター グラフは、ストリームの開始時 にEC_STREAM_CONTROL_STARTED し、ストリームが停止したときに EC_STREAM_CONTROL_STOPPED するイベントのペアを送信します。 2 番目のイベント パラメーターとして 、wStartCookie と wStopCookie の値が使用されます。 したがって、開始イベントの lParam2 は wStartCookie と等しく、stop イベントの lParam2 は wStopCookie と等しくなります。 次のコードは、これらのイベントを取得する方法を示しています。
while (hr = pEvent->GetEvent(&evCode, ¶m1, ¶m2, 0), SUCCEEDED(hr))
{
switch (evCode)
{
case EC_STREAM_CONTROL_STARTED:
// param2 == wStartCookie
break;
case EC_STREAM_CONTROL_STOPPED:
// param2 == wStopCookie
break;
}
pEvent->FreeEventParams(evCode, param1, param2);
}
ControlStream メソッドは、開始時刻と停止時刻に特別な値を定義します。
値 | 開始 | Stop |
---|---|---|
MAXLONGLONG | このストリームを開始しないでください。 | グラフが停止するまで停止しないでください。 |
NULL | グラフの実行時にすぐに開始します。 | すぐに停止します。 |
たとえば、次のコードはキャプチャ ストリームを直ちに停止します。
pBuild->ControlStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pCap,
0, 0, // Start and stop times.
wStartCookie, wStopCookie);
キャプチャ ストリームを停止して後で再起動することはできますが、タイムスタンプにギャップが生じる可能性があります。 再生時に、(ファイル形式に応じて) ギャップ中にビデオが停止しているように見えます。
プレビュー ストリームの制御
プレビュー ピンを制御するには、 ControlStream を呼び出しますが、最初のパラメーターを PIN_CATEGORY_PREVIEW に設定します。 これは、PIN_CATEGORY_CAPTUREの場合と同様に機能しますが、プレビュー フレームにはタイム スタンプがないため、開始と停止を指定するために参照時刻を使用することはできません。 したがって、NULL または MAXLONGLONG を 使用する必要があります。 プレビュー ストリームを開始するには 、NULL を 使用します。
pBuild->ControlStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap,
NULL, // Start now.
0, // (Don't care.)
wStartCookie, wStopCookie);
MAXLONGLONG を使用してプレビュー ストリームを停止します。
pBuild->ControlStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap,
0, // (Don't care.)
MAXLONGLONG, // Stop now.
wStartCookie, wStopCookie);
プレビュー ストリームがキャプチャ フィルターのプレビュー ピンからのものか、Smart Tee フィルターからのものかは関係ありません。 ControlStream メソッドはどちらの方法でも機能します。
ただし、ビデオ ポート ピンの場合、 メソッドは失敗します。 その場合、もう 1 つの方法は、ビデオ ウィンドウを非表示にすることです。 IVideoWindow のグラフに対してクエリを実行し、IVideoWindow::p ut_Visible メソッドを使用してウィンドウを表示または非表示にします。
// Hide the video window.
IVideoWindow *pVidWin = 0;
hr = pGraph->QueryInterface(IID_IVideoWindow, (void**)&pVidWin);
if (SUCCEEDED(hr))
{
pVidWin->put_Visible(OAFALSE);
pVidWin->Release();
}
また、グラフを実行する前に値 OAFALSE を指定 して IVideoWindow::p ut_AutoShow を呼び出すと、ビデオ レンダラー フィルターは、それ以外の場合に指定するまでウィンドウを非表示にします。 既定では、グラフを実行すると、ビデオ レンダラーにウィンドウが表示されます。
ストリーム コントロールに関する解説
ピンの既定の動作は、グラフの実行時にサンプルを配信することです。 たとえば、PIN_CATEGORY_PREVIEWではなく、PIN_CATEGORY_CAPTUREを使用して ControlStream を呼び出すとします。 グラフを実行すると、プレビュー ストリームはすぐに実行され、キャプチャ ストリームは ControlStream で指定した任意の時点で実行されます。
複数のストリームをキャプチャし、それらを多重化フィルターに送信する場合 (たとえば、オーディオとビデオを AVI ファイルにキャプチャする場合)、両方のストリームを同時に制御する必要があります。 それ以外の場合、mux フィルターは 2 つのストリームをインターリーブしようとするため、1 つのストリームの待機をブロックする可能性があります。 グラフを実行する前に、すべてのキャプチャ ストリームで同じ開始時刻と停止時刻を設定します。
pBuild->ControlStream(&PIN_CATEGORY_CAPTURE,
NULL, NULL, // All capture streams.
&rtStart, rtStop,
wStartCookie, wStopCookie);
内部的には、 ControlStream メソッドは IAMStreamControl インターフェイスを使用します。これは、キャプチャ フィルター、Smart Tee フィルター (存在する場合)、場合によっては mux フィルターのピンで公開されます。 ControlStream を呼び出す代わりに、このインターフェイスを直接使用できますが、これを行うことに特に利点はありません。
関連トピック