Share via


動態重新連線

[與此頁面 相關的功能 DirectShow是舊版功能。 它已被 MediaPlayerIMFMediaEngineMedia Foundation 中的音訊/視訊擷取取代。 這些功能已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用 MediaPlayerIMFMediaEngine音訊/視訊擷取 ,而不是 DirectShow。 Microsoft 建議盡可能重寫使用舊版 API 的現有程式碼,以使用新的 API。]

在大部分的 DirectShow 篩選中,當圖形主動串流資料時,無法重新連接針腳。 應用程式必須在重新連接針腳之前停止圖形。 不過,有些篩選準則在圖形執行時支援針腳重新連線,這是稱為動態重新連線的進程。 這可以透過應用程式或圖形中的篩選來完成。

例如,請考慮下圖中的圖表。

動態圖表建置圖表

動態重新連線的其中一個案例可能是從圖形中移除 Filter 2,而圖形正在執行,並將它取代為另一個篩選。 若要讓此案例正常運作,下列條件必須為 true:

  • 篩選 3 (針腳 D) 上的輸入針腳必須支援 IPinConnection 介面。 此介面可讓針腳重新連線,而不需要停止篩選準則。
  • 篩選 1 上的輸出釘選 (針腳 A) 必須能夠在重新連線發生時封鎖媒體資料的流程。 在重新連線期間,無法在針腳 A 與針腳 D 之間移動任何資料。 一般而言,這表示輸出針腳必須支援 IPinFlowControl 介面。 不過,如果 Filter 1 是起始重新連線的篩選準則,它可能會有一些內部機制來封鎖自己的資料流程。

動態重新連線將涉及下列步驟:

  1. 禁止資料流程釘選 A。
  2. 重新連接釘選 A 到針腳 D,可能透過新的中繼篩選器。
  3. 解除封鎖釘選 A,讓資料再次開始流動。

步驟 1: 封鎖資料流程

若要封鎖資料流程,請在釘選 A 上呼叫 IPinFlowControl::Block 。這個方法可以非同步或同步呼叫。 若要 以非同步方式呼叫 方法,請建立 Win32 事件物件,並將事件控制碼傳遞至 Block 方法。 方法會立即傳回。 使用 WaitForSingleObject之類的函式,等候事件發出訊號。 針腳會在事件封鎖資料流程時發出訊號。 例如:

// Create an event
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (hEvent != NULL)
{
    // Block the data flow.
    hr = pFlowControl->Block(AM_PIN_FLOW_CONTROL_BLOCK, hEvent); 
    if (SUCCEEDED(hr))
    {
        // Wait for the pin to finish.
        DWORD dwRes = WaitForSingleObject(hEvent, dwMilliseconds);
    }
}

若要 同步呼叫 方法,只要傳遞 Null 值,而不是事件控制碼即可。 現在方法會封鎖,直到作業完成為止。 在針腳準備好提供新的樣本之前,可能不會發生這種情況。 如果篩選已暫停,這可能需要任意的時間長度。 因此,請勿從主要應用程式執行緒進行同步呼叫。 使用背景工作執行緒,或以非同步方式呼叫 方法。

步驟 2: 重新連線釘選

若要重新連接針腳,請查詢 IGraphConfig 介面的 Filter Graph 管理員,並呼叫 IGraphConfig::ReconnectIGraphConfig::Reconfigure重新連線方法比較容易使用;它會執行下列動作:

  • 停止範例中的中繼篩選 (Filter 2) ,並從圖形中移除它們。
  • 視需要加入新的中繼篩選。
  • 連接所有針腳。
  • 暫停或執行任何新的篩選準則,以符合圖形的狀態。

Reconnect方法有數個選擇性參數,可用來指定針腳連接的媒體類型,以及要使用的中繼篩選器。 例如:

pGraph->AddFilter(pNewFilter, L"New Filter for the Graph");
pConfig->Reconnect(
    pPinA,      // Reconnect this output pin...
    pPinD,      // ... to this input pin.
    pMediaType, // Use this media type.
    pNewFilter, // Connect them through this filter.
    NULL, 
    0);     

如需詳細資訊,請參閱參考頁面。 如果 Reconnect 方法不夠彈性,您可以使用 Reconfigure 方法,呼叫應用程式定義的回呼方法以重新連接針腳。 若要使用此方法,請在應用程式中實作 IGraphConfigCallback 介面。

在呼叫 Reconfigure之前,請從輸出釘選封鎖資料流程,如先前所述。 然後,推送仍在您要重新連線之圖形區段中擱置的任何資料,如下所示:

  1. 在) 範例中,重新連線鏈結最遠下游的輸入針腳上呼叫 IPinConnection::NotifyEndOfStream (針腳 D。 傳入 Win32 事件的控制碼。
  2. 在輸入針腳上呼叫 IPin::EndOfStream ,該接點會緊接在封鎖資料流程的輸出針腳下游。 (在此範例中,資料流程在釘選 A 遭到封鎖,因此您會在釘選 B.) 上呼叫EndOfStream
  3. 等候事件發出訊號。 輸入針腳 (針腳 D) 收到串流結束通知時發出訊號。 這表示沒有資料在針腳之間移動,而且呼叫端可以安全地重新連接針腳。

請注意 ,IGraphConfig::Reconnect 方法會自動處理先前的步驟。 如果您使用 Reconfigure 方法,您只需要執行這些步驟。

透過圖形推送資料之後,請呼叫 Reconfigure 並將指標傳遞至 IGraphConfigCallback 回 呼介面。 Filter Graph 管理員會呼叫您提供的 IGraphConfigCallback::Reconfigure 方法。

步驟 3: 解除封鎖資料流程

重新連接針腳之後,呼叫 IPinFlowControl::Block ,並針對第一個參數呼叫值為零的資料流程,以解除封鎖資料流程。

注意

如果動態重新連線是由篩選所執行,您必須注意一些執行緒問題。 如果 Filter Graph 管理員嘗試停止篩選,它可能會死結,因為圖表會等候篩選停止,同時篩選可能會等待資料透過圖形推送。 為避免可能的死結,本節所述的一些方法會處理 Win32 事件。 如果 Filter Graph Manager 嘗試停止篩選,篩選準則應該會發出事件訊號。 如需詳細資訊,請參閱 IGraphConfigIPinConnection

 

動態圖表建置