共用方式為


控制擷取圖形

[與此頁面相關的功能 DirectShow是舊版功能。 它已被 MediaPlayerIMFMediaEngineMedia Foundation 中的音訊/視訊擷取取代。 這些功能已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用 MediaPlayerIMFMediaEngine音訊/視訊擷取 ,而不是 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_STOPPEDwStartCookiewStopCookie的值會當做第二個事件參數使用。 因此,start 事件中的 lParam2 等於 wStartCookie,而停止事件中的 lParam2 等於 wStopCookie。 下列程式碼示範如何取得這些事件:

while (hr = pEvent->GetEvent(&evCode, &param1, &param2, 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,雖然沒有特別的優點。

影片擷