控制擷取圖形
[與此頁面相關的功能 DirectShow是舊版功能。 它已被 MediaPlayer、 IMFMediaEngine和 Media Foundation 中的音訊/視訊擷取取代。 這些功能已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用 MediaPlayer、 IMFMediaEngine 和 音訊/視訊擷取 ,而不是 DirectShow。 Microsoft 建議使用舊版 API 的現有程式碼盡可能重寫為使用新的 API。
Filter Graph Manager 的 IMediaControl 介面具有執行、停止和暫停整個圖表的方法。 不過,如果篩選圖表有擷取和預覽資料流程,您可能想要獨立控制這兩個數據流。 例如,您可能想要預覽影片,而不擷取影片。 您可以透過 ICaptureGraphBuilder2::ControlStream 方法執行此動作。
注意
當擷取至進階系統格式 (ASF) 檔案時,此方法無法運作。
控制擷取資料流程
下列程式碼會將影片擷取資料流程設定為執行四秒,並在圖表執行之後啟動一秒:
// 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。 第二個參數會提供媒體類型。 第三個參數是擷取篩選的指標。 若要控制圖形中的所有擷取資料流程,請將第二個和第三個參數設定為 Null。
接下來的兩個參數會定義資料流程開始和停止的時間,相對於圖形開始執行的時間。 呼叫 IMediaControl::Run 以執行圖形。 在您執行圖形之前, ControlStream 方法不會有任何作用。 如果圖表已在執行中,則設定會立即生效。
最後兩個參數用於在資料流程啟動和停止時取得事件通知。 針對您使用此方法控制的每個資料流程,篩選圖表會傳送一組事件:在資料流程啟動時 EC_STREAM_CONTROL_STARTED ,並在資料流程停止時 EC_STREAM_CONTROL_STOPPED 。 wStartCookie和wStopCookie的值會當做第二個事件參數使用。 因此,start 事件中的 lParam2 等於 wStartCookie,而停止事件中的 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方法可透過任一方式運作。
不過,對於視訊埠針腳,此方法將會失敗。 在此情況下,另一種方法是隱藏視訊視窗。 查詢 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_CAPTURE 呼叫 ControlStream ,但不呼叫 PIN_CATEGORY_PREVIEW。 當您執行圖形時,預覽資料流程會立即執行,而擷取資料流程會在 您在 ControlStream中指定的時間執行。
如果您要擷取多個資料流程,並將其傳送至多工篩選器,例如,如果您要將音訊和視訊擷取至 AVI 檔案,您應該同時控制這兩個串流。 否則,多工篩選器可能會封鎖等候一個資料流程,因為它嘗試交錯兩個數據流。 在執行圖形之前,請在所有擷取資料流程上設定相同的開始和停止時間:
pBuild->ControlStream(&PIN_CATEGORY_CAPTURE,
NULL, NULL, // All capture streams.
&rtStart, rtStop,
wStartCookie, wStopCookie);
在內部,ControlStream 方法會使用IAMStreamControl介面,此介面會在擷取篩選的針腳上公開、Smart Tee 篩選 (如果存在) ,也可能是多工篩選器。 您可以直接使用此介面,而不是呼叫 ControlStream,雖然沒有特別的優點。
相關主題