3. DirectShow-深入理解filter概念

基本名詞:filter、pin、filter Graph

DirectShow 使用模塊化體系結(jié)構(gòu),其中每個處理階段都由名為filter 的 COM 對象完成。 DirectShow 提供了一組標準filter 供應用程序使用,開發(fā)人員可以編寫自己的自定義filter 來擴展 DirectShow 的功能。每個filter 都連接到一個或多個其他filter 。 連接點也是 COM 對象,稱為 pinfilter 使用pin 把數(shù)據(jù)從一個filter 移動到下一個filter 中。在 DirectShow 中,一組filter 稱為 filter Graph 。

filter的狀態(tài)

filter 有三種可能的狀態(tài):運行、停止和暫停。 filter 運行時,它會處理媒體數(shù)據(jù)。 停止時,它將停止處理數(shù)據(jù)。 暫停狀態(tài)用于在運行前提示數(shù)據(jù)。
filter關系圖管理器按上游順序執(zhí)行所有狀態(tài)轉(zhuǎn)換,從呈現(xiàn)器開始,然后向后工作到源filter。 必須進行此排序,以防止刪除MediaSample并防止圖形死鎖。 最重要的狀態(tài)轉(zhuǎn)換是在暫停和停止之間轉(zhuǎn)換:
已停止-->暫停:當每個filter暫停時,它便準備好從下一個filter接收MediaSample。 源filter是最后一個暫停的filter。 它創(chuàng)建流式處理線程并開始傳送MediaSample。 由于所有下游filter都已暫停,因此沒有filter會拒絕任何MediaSamplefilter圖形管理器不會完成轉(zhuǎn)換,直到圖形中的每個呈現(xiàn)器都收到MediaSample ((實時源除外),如前面) 所述。

暫停-->停止:當filter停止時,它會釋放它保存的任何MediaSample,從而取消阻塞在 GetBuffer 中等待的任何上游filter。 如果filter正在等待 Receive 方法中的資源,它將停止等待并從 Receive 返回,這會取消阻塞調(diào)用filter。 因此,當 Filter Graph 管理器停止下一個上游filter時,該filter不會在 GetBuffer 或 Receive 中被阻塞,并且可以響應 stop 命令。 上游filter可能會在獲取停止命令之前提供一些額外的MediaSample,但下游filter只是拒絕它們,因為它已經(jīng)停止。

filter的分類

filter 可以分為多個大類:

  • filter 將數(shù)據(jù)引入。 數(shù)據(jù)可能來自文件、網(wǎng)絡、相機或其他任何位置。 每個源filter 處理不同類型的數(shù)據(jù)源。
  • 轉(zhuǎn)換filter 采用輸入流、處理數(shù)據(jù)并創(chuàng)建輸出流。 編碼器和解碼器是轉(zhuǎn)換filter 的示例。
  • 呈現(xiàn)器 filter 位于鏈的末尾。 他們接收數(shù)據(jù)并將其呈現(xiàn)給用戶。 例如,視頻呈現(xiàn)器在顯示器上繪制視頻幀、音頻呈現(xiàn)器將音頻數(shù)據(jù)發(fā)送到聲音卡、文件編寫器將數(shù)據(jù)寫入文件。
  • 拆分器filter 將輸入流拆分為兩個或多個輸出,通常在此過程中分析輸入流。 例如,AVI 拆分器將字節(jié)流分析為單獨的視頻流和音頻流。
  • 復用filter 采用多個輸入,并將其合并到單個流中。 例如,AVI 復用器執(zhí)行 AVI 拆分器反運算。 它采用音頻和視頻流,并生成 AVI 格式的字節(jié)流。
    所有 DirectShow filter 都公開 IBaseFilter 接口,所有pin 都公開 IPin 接口。

pin的作用

filterpin連接提供數(shù)據(jù)。 數(shù)據(jù)從一個filter的輸出pin移動到另一個filter的輸入pin。 輸出pin傳遞數(shù)據(jù)的最常見方法是對輸入調(diào)用 IMemInputPin::Receive 方法,但也有一些其他機制。

根據(jù)filter,媒體數(shù)據(jù)的內(nèi)存可以通過各種方式分配:在堆上、在 DirectDraw中、使用共享 GDI 內(nèi)存或使用某種其他分配機制。 負責分配內(nèi)存的對象稱為 分配器,該分配器是公開 IMemAllocator 接口的 COM 對象。

當兩個pin連接時,其中一個pin必須提供分配器。 DirectShow 定義一系列方法調(diào)用,用于建立哪個pin提供分配器。 pin還就分配器將創(chuàng)建的緩沖區(qū)數(shù)和緩沖區(qū)大小達成一致。

在流式處理開始之前,分配器會創(chuàng)建緩沖區(qū)池。 在流式處理期間,上游filter使用數(shù)據(jù)填充緩沖區(qū),并將其傳遞到下游filter。 但是,上游filter不會為下游filter提供指向緩沖區(qū)的原始指針。 相反,它使用稱為 MediaSample的 COM 對象,分配器創(chuàng)建這些對象來管理緩沖區(qū)。 MediaSample公開 IMediaSample 接口。 MediaSample包含:

  • 指向基礎緩沖區(qū)的指針
  • 時間戳
  • 各種標志
  • (可選)媒體類型
    時間戳定義呈現(xiàn)器filter用于計劃呈現(xiàn)的呈現(xiàn)時間。
    標志指示自上一個示例以來數(shù)據(jù)中是否存在中斷之類的情況。
    媒體類型為filter提供了一種在流中更改格式的方法。 通常,該示例沒有媒體類型,這表示格式自上一個示例以來沒有更改。
    filter使用緩沖區(qū)時,它會保留樣本的引用計數(shù)。 分配器使用引用計數(shù)來確定何時可以重復使用緩沖區(qū)。 這可以防止filter覆蓋另一個filter仍在使用的緩沖區(qū)。 樣本不會返回到分配器的可用樣本池,直到每個filter釋放它。

filter Graph

Filter Graph 管理器是一個 COM 對象,用于控制filter Graph中的一組filter 。 它執(zhí)行許多功能,包括以下內(nèi)容:

  • 協(xié)調(diào)filter 之間的狀態(tài)更改。
  • 建立引用時鐘。
  • 將事件傳達回應用程序。
  • 為應用程序提供生成filter Graph 的方法。
    此處簡要介紹了其中每個函數(shù)。 可在文檔的其他地方找到詳細信息。
    狀態(tài)更改。 filter 中的狀態(tài)更改必須按特定順序發(fā)生。 因此,應用程序不會直接向filter 發(fā)出狀態(tài)更改命令。 相反,它會向 Filter Graph 管理器提供單個命令,后者將命令分發(fā)給每個filter 。 查找的工作方式與此類似:應用程序向 Filter Graph 管理器提供一個 seek 命令,后者將其分發(fā)到filter 。
    參考時鐘。 圖中的所有filter 都使用相同的時鐘,稱為 引用時鐘。 引用時鐘可確保同步所有流。 應呈現(xiàn)視頻幀或音頻示例的時間稱為 演示時間。 表示時間相對于參考時鐘進行測量。 Filter Graph 管理器選擇引用時鐘,通常是聲音卡上的時鐘或系統(tǒng)時鐘。
    圖形事件。 Filter Graph 管理器使用事件隊列通知應用程序filter Graph 中發(fā)生的事件。 此機制類似于 Windows 消息循環(huán)。
    圖形生成方法。 Filter Graph 管理器為應用程序提供了向圖形添加filter 、將filter 連接到其他filter 以及斷開filter 連接的方法。
    Filter Graph 管理器不處理的一個函數(shù)是將數(shù)據(jù)從一個filter 移動到下一個filter 。 這由filter 本身通過其pin 連接完成。 處理始終在單獨的線程上進行。

filter是如何與音頻和視頻硬件交互的

所有 DirectShow filter都是用戶模式軟件組件。 為了使內(nèi)核模式硬件設備(如視頻捕獲卡)加入 DirectShow filter圖,設備必須表示為用戶模式filter。 此函數(shù)由 DirectShow 提供的專用“包裝器”filter執(zhí)行。 這些filter包括 音頻捕獲 filter、 VFW 捕獲 filter、 電視調(diào)諧器 filter、 電視音頻 filter和 模擬視頻橫杠 filter。 DirectShow 還提供名為 KsProxy 的filter,該filter可以表示任何類型的 Windows 驅(qū)動程序模型 (WDM) 流式處理設備。 硬件供應商可以通過提供 Ksproxy 插件(由 KsProxy 聚合的 COM 對象)來擴展 KsProxy 以支持自定義功能。

包裝器filter公開表示設備功能的 COM 接口。 應用程序使用這些接口向filter傳遞和從filter傳遞信息。 filter將 COM 方法調(diào)用轉(zhuǎn)換為設備驅(qū)動程序調(diào)用,在內(nèi)核模式下將該信息傳遞給驅(qū)動程序,然后將結(jié)果轉(zhuǎn)換回應用程序。 電視調(diào)諧器、電視音頻、模擬視頻交叉欄和 KsProxy filter通過 IKsPropertySet 接口支持自定義驅(qū)動程序?qū)傩浴?VFW 捕獲filter和音頻捕獲filter不是以這種方式擴展的。

對于應用程序開發(fā)人員,包裝器filter使應用程序能夠像控制任何其他 DirectShow filter一樣控制設備。 無需特殊編程;與內(nèi)核模式設備通信的詳細信息封裝在filter中。

Windows 設備視頻

VFW 捕獲filter支持 Windows (VfW) 捕獲卡的早期視頻。 當目標系統(tǒng)上存在 VfW 卡時,可以使用 DirectShow 系統(tǒng)設備枚舉器發(fā)現(xiàn)它并將其添加到filter圖中。 有關詳細信息,請參閱 枚舉設備和filter。

音頻捕獲和混音設備 (聲卡)

較新的聲卡具有用于麥克風和其他類型的設備的輸入插孔。 通常,這些卡還具有板載混合功能,用于控制每個輸入的音量、高音和低音。 在 DirectShow 中,聲音卡的輸入和混音器由音頻捕獲filter包裝。 可以使用系統(tǒng)設備枚舉器發(fā)現(xiàn)每個聲音卡。 若要查看系統(tǒng)中的聲卡,請運行 GraphEdit 并從“音頻捕獲源”類別中進行選擇。 該類別中的每個filter都是音頻捕獲filter的單獨實例。 (請參閱 使用 GraphEdit.)

WDM 流式處理設備

較新的硬件解碼器和捕獲卡符合 Windows 驅(qū)動程序模型 (WDM) 規(guī)范。 這些設備比 VfW 設備具有更大的功能。 WDM 視頻捕獲卡可以支持 VfW 下不可用的功能,包括捕獲格式的枚舉、視頻參數(shù)(如色調(diào)和亮度)的編程控制、編程輸入選擇和電視調(diào)諧器支持。

為了支持 WDM 流式處理設備,DirectShow 提供了 KsProxy filter(ksproxy.ax) 。 KsProxy被稱為“瑞士軍刀過濾器”,因為它做許多不同的事情。 filter上的pin數(shù)以及filter公開的 COM 接口數(shù)取決于基礎驅(qū)動程序的功能。 KsProxy 不會顯示在名稱“KsProxy”下的filter圖中。它始終采用在注冊表中找到的設備的友好名稱。 若要查看系統(tǒng)上的 WDM 設備,請運行 GraphEdit 并從 WDM 流式處理類別中進行選擇。 即使系統(tǒng)上只有一個 WDM 卡,該卡也可能包含多個設備。 每個設備都表示為單獨的filter,其中每個filter實際上都是 KsProxy。

應用程序使用系統(tǒng)設備枚舉器查找系統(tǒng)上的 WDM 設備名字對象。 KsProxy 通過在名字對象上調(diào)用 BindToObject 來實例化。 由于 KsProxy 可以表示所有類型的 WDM 設備,因此它必須查詢驅(qū)動程序以確定驅(qū)動程序支持的屬性集。 屬性集是 WDM 驅(qū)動程序以及某些用戶模式filter(如 MPEG-2 軟件解碼器)使用的數(shù)據(jù)結(jié)構(gòu)的集合。 KsProxy 將自身配置為公開與這些屬性集對應的 COM 接口。 KsProxy 將 COM 方法調(diào)用轉(zhuǎn)換為屬性集,并將其發(fā)送到驅(qū)動程序。 硬件供應商可以通過提供插件來擴展 KsProxy,插件是供應商特定的接口,用于公開設備的特殊功能。 所有這些詳細信息都對應用程序隱藏。 應用程序通過 KsProxy 控制設備,其方式與任何其他 DirectShow filter的方式相同。

內(nèi)核流式處理

WDM 設備支持內(nèi)核流式處理,其中數(shù)據(jù)完全在內(nèi)核模式下流式傳輸,而無需切換到用戶模式。 在內(nèi)核模式和用戶模式之間切換計算成本高昂;內(nèi)核流式處理允許高比特率,而不會給主機 CPU 帶來負擔。 基于 WDM 的filter可以使用內(nèi)核流式處理將多媒體數(shù)據(jù)從一個硬件設備直接傳遞到另一個硬件設備,無論是在同一個卡上還是在不同的卡,而無需將數(shù)據(jù)復制到系統(tǒng)的main內(nèi)存中。

從應用程序的角度來看,數(shù)據(jù)似乎從一個用戶模式filter移動到下一個用戶模式filter。 實際上,數(shù)據(jù)可能根本不會進入用戶模式,而是可以直接從一個內(nèi)核模式設備流式傳輸?shù)搅硪粋€內(nèi)核模式設備,直到在視頻圖形上呈現(xiàn)卡。 某些方案(如捕獲到文件)要求數(shù)據(jù)在某個時間點從內(nèi)核模式傳遞到用戶模式。 但是,此開關不一定要求將數(shù)據(jù)復制到內(nèi)存中的新位置。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容