Share via


範例和配置器

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

當針腳將媒體資料傳遞至另一個針腳時,它不會將直接指標傳遞至記憶體緩衝區。 相反地,它會將指標傳遞給管理記憶體的 COM 物件。 這個物件稱為 媒體範例,會公開 IMediaSample 介面。 接收針腳會呼叫IMediaSample方法來存取記憶體緩衝區,例如IMediaSample::GetPointerIMediaSample::GetSize 和 IMediaSample::GetActualDataLength

範例一律會移動下游,從輸出釘選到輸入針腳。 在推送模型中,輸出針腳會在輸入針腳上呼叫 IMemInputPin::Receive 來傳遞範例。 輸入針腳會同步處理資料 (,也就是在 Receive 方法內完全) ,或在背景工作執行緒上以非同步方式處理。 如果輸入針腳需要等候資源,則允許在 Receive 方法內封鎖。

另一個稱為 配置器的COM 物件負責建立和管理媒體範例。 配置器會公開 IMemAllocator 介面。 每當篩選需要具有空白緩衝區的媒體範例時,它會呼叫 IMemAllocator::GetBuffer 方法,此方法會傳回範例的指標。 每個針腳連線都會共用一個配置器。 當兩個針腳連接時,他們會決定哪一個篩選會提供配置器。 針腳也會在配置器上設定屬性,例如緩衝區數目和每個緩衝區的大小。 (如需詳細資訊,請參閱 Filters Connect交涉 Allocators.)

下圖顯示配置器、媒體範例和篩選之間的關聯性。

媒體範例和配置器

媒體範例參考計數

配置器會建立有限的樣本集區。 某些範例隨時可能正在使用中,而其他範例則可供 GetBuffer 呼叫使用。 配置器會使用參考計數來追蹤樣本。 GetBuffer方法會傳回參考計數為 1 的範例。 如果參考計數變成零,則範例會回到配置器的集區,您可以在下一個 GetBuffer 呼叫中使用。 只要參考計數維持在零以上, GetBuffer將無法使用樣本。 如果屬於配置器的每個樣本都正在使用中, GetBuffer 方法會封鎖直到樣本可供使用為止。

例如,假設輸入針腳收到範例。 如果它會同步處理樣本,請在 Receive 方法內,不會遞增參考計數。 在 Receive 傳回之後,輸出針腳會釋放樣本、參考計數會移至零,而樣本會返回配置器的集區。 另一方面,如果輸入針腳處理背景工作執行緒上的範例,它會在離開 Receive 方法之前遞增參考計數。 參考計數現在是 2。 當輸出針腳釋放範例時,計數會移至 1;範例尚未返回集區。 使用範例完成背景工作執行緒之後,它會呼叫 Release 以釋放範例。 現在範例會返回集區。

當針腳收到樣本時,可以將資料複製到另一個樣本,也可以修改原始樣本,並將該樣本傳遞給下一個篩選。 範例可能會移動圖形的整個長度,每個篩選會接著呼叫 AddRefRelease 。 因此,輸出針腳絕對不能在呼叫 Receive之後重複使用範例,因為下游篩選準則可能會使用範例。 輸出針腳必須一律呼叫 GetBuffer 以取得新的範例。

此機制可減少記憶體配置的數量,因為篩選會重複使用相同的緩衝區。 它也會防止篩選意外寫入尚未處理的資料,因為配置器會維護可用的範例清單。

篩選準則可以使用個別配置器進行輸入和輸出。 例如,如果它展開輸入資料 (,則會將其解壓縮) ,則可能會這麼做。 如果輸出不大於輸入,篩選準則可能會就地處理資料,而不需將其複製到新的範例。 在此情況下,兩個或多個針腳連線可以共用一個配置器。

認可和取消認可配置器

當篩選第一次建立配置器時,配置器並未保留任何記憶體緩衝區。 此時, 對 GetBuffer 方法的任何呼叫都會失敗。 串流啟動時,輸出針腳會呼叫 IMemAllocator::Commit,這會認可配置器,導致它配置記憶體。 釘選現在可以呼叫 GetBuffer

串流停止時,針腳會呼叫 IMemAllocator::D ecommit,這會取消認可配置器。 所有對 GetBuffer的後續呼叫都會失敗,直到配置器再次認可為止。 此外,如果目前封鎖對 GetBuffer 的任何呼叫等候範例,它們就會立即傳回失敗碼。 Decommit方法可能會或可能不會釋放記憶體,視實作而定。 例如, CMemAllocator 類別會等到其解構函式方法釋放記憶體為止。

篩選圖形中的資料流程