共用方式為


樣本和分配器

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

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

樣本總是從輸出針腳流向輸入針腳。 在推送模型中,輸出接點透過在輸入接點上調用 IMemInputPin::Receive 來傳遞範例。 輸入引腳會同步處理數據(亦即,完全在 Receive 方法內),或於工作線程上以異步方式處理數據。 如果輸入引腳需要等候資源,則允許在 Receive 方法內阻塞。

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

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

媒體範例和配置器

媒體樣本參考計數

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

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

當接腳收到樣本時,可以將數據複製到另一個樣本,或者可以修改原始樣本,並將該樣本傳遞給下一個過濾器。 樣本可能會遍歷整個圖表的長度,每個篩選器依次呼叫 AddRefRelease。 因此,輸出針腳絕對不能在呼叫 Receive後再次使用樣本,因為下游過濾器可能會使用該樣本。 輸出針腳必須一律呼叫 GetBuffer,才能取得新的樣本。

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

過濾器可以對輸入和輸出使用不同的配置器。 如果它展開輸入數據,它可能會執行此動作(例如,藉由解壓縮它)。 如果輸出不大於輸入,過濾器可能會就地處理數據,而不需將其複製到新的樣本。 在此情況下,兩個以上的針腳連線可以共用一個分配器。

認可和取消認可配置器

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

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

篩選圖表中的 數據流