DirectShow學習指南之資料流結束通知

2021-09-30 03:36:39 字數 3450 閱讀 8923

當乙個源filter結束傳送資料流時,它呼叫和它連線的filter的輸入pin的ipin::endofstream,然後下游的filter再依次通知與之相連的filter。當endofstream方法一直呼叫到renderer filter的時候,最後的乙個filter就給filter圖表管理器傳送乙個ec_complete事件通知。如果renderer有多個輸入pin,當所有的輸入pin都接收到end of stream通知的時候,它才會給filter圖表管理器傳送乙個ec_complete事件通知。

filter必須在其他函式呼叫之後呼叫endofstream函式,比如imeminputpin::receive.。

在一些情況下,下游的filter可能比源filter更早的發現資料流的結束。在這種情況下,下游filter傳送 結束stream的通知,同時, imeminputpin::receive函式返回s_false直到圖表管理器停止。這個返回值提示源filter停止傳送資料。

對ec_complete事件的預設處理

預設的情況下,filter圖表管理器並不將ec_complete事件通知傳送給應用程式,當所有的資料流都傳送了ec_complete事件通知後,它才給應用程式傳送乙個ec_complete事件通知。所以,應用程式只有在所有的資料流停止的時候才能接收到這個通知。

filter圖表管理器通過計算支援seeking介面的filter,並且具有乙個renderer pin,沒有相應的輸出pin,就可以確定資料流的數目。filter圖表管理器通過下面的方法來決定乙個pin是否是個renderer 。

1、pin的ipin::queryinternalconnections方法通過npin引數返回0;

2、filter保露乙個iamfiltermiscflags介面,並且返回乙個am_filter_misc_flags_is_renderer標誌。

在拉模式下的資料流結束通知

在iasyncreader連線中,源filter並不傳送資料流結束的通知,相應的傳送資料流結束的通知是有renderer filter發出的。

new segments

當graph執行的時候,在整個graph中會有大量的資料流動。同時也有一些資料排在佇列裡等到傳遞。當graph移動這些未決的資料,並在該記憶體塊中寫入新的資料是需要一定的時間的。例如,在seek命令後,源filter在生成新的sample,這些是需要一定時間的。為了減小延遲,下游的filter在seek命令必須丟掉以前的sample。這個拋棄sample的過程就叫flushing。

當事件改變了資料的流向時,這可以使garph響應的更及時一些。

推模式和拉模式在處理flushing的時候有點不同。我們先討論一下推模式,然後再討論拉模式。

下面兩種情況下發生flushing

1、源filter呼叫下游filter輸入pin的ipin::beginflush方法,然後下游的filter就開始拒絕從上游filter接收資料流。然後它開始拋棄它正在處理的samples,繼續呼叫下游filter的ipin::beginflush方法。

2、當源filter準備好新的資料時,它呼叫輸入pin的ipin::endflush方法,這就告訴下游的filter可以接收新的samples,然後繼續呼叫下游的filter的ipin::endflush。

在beginflush方法中,輸入pin進行了下列工作:

1、首先呼叫下游filter的輸入pin上的calls beginflush方法

2、拒絕處理資料流,包括receive和endofstream方法

3、取消那些正在阻塞等待filter釋放allocator的等待,

4、如果filter正處於阻塞資料狀態,那麼filter就退出阻塞。例如當停止的時候renderer filter就阻塞,此時,filter就要取消阻塞。

在endflush方法中,輸入pin做了下列工作:

1、等待所有正在佇列中的samples被拋棄

2、釋放存放資料的buffer,這一步也可能在beginflush方法裡,但是,beginflush方法streaming 執行緒是不同步的。filter在beginflush和endflush方法之間不能夠處理如何資料

3、清除所有的ec_complete通知

4、呼叫下游filter的endflush方法

此時,filter可以再次接收sample。

在拉模式中,parser filter初始化flushing,而不是由source filter,它不僅呼叫了下游filteripin::beginflush and ipin::endflush方法,它又呼叫了源filter輸出pin上的iasyncreader::beginflush and iasyncreader::endflush,如果此時,源filter有未決的read請求,它就拋棄

seeking

filter通過imediaseeking介面支援seeking。應用程式從filter 圖表管理器請求imediaseeking介面,然後通過這個介面,執行seek命令。filter圖表管理器傳遞到graph裡所有的renderer filter。每個renderer 通過上游filter的輸出pin來傳遞seek命令,直到某乙個filter可以執行這個seek命令。一般來說,源filter,或者parser filter可以執行seek 命令。

當乙個filter執行seek命令的時候,它就flushes所有的未決的資料,這是為了減少seek命令的遲延。當乙個seek命令後,stream time設定為零。

下面的圖表演示了seek過程

圖1如果乙個parser filter 的輸出pin不止乙個的話,它就指定乙個pin來接收seek commands,其他的pin當接收到seek 命令時,就拒絕或者忽略seek 命令。這樣,parser就保持了所有的資料流同步。

pin連線時資料格式的動態改變

當兩個filter連線的時候,他們會就某種**型別達成協議。這種資料型別用來描述上游filter將傳遞什麼格式的資料。大多數情況下,在連線的持續過程中,這個**型別是不變的,但是,directshow也支援動態改變**型別。

directshow定義了一些機制來支援動態改變**型別。關鍵在於filter graph的狀態和將要改變的型別。

如果graph處於停止狀態,pin可以重新連線,重新就某個**型別達成協議。

一些filter還支援動態的連線,

當graph處於活動狀態,並且不支援動態的重新連線的時候,有三種機制支援**型別的改變。

queryaccept (downstream) 適用於輸出pin向下游的filter提出改變**型別,並且新的**格式的大小不超過原來的buffer。

queryaccept (upstream) 適用於輸入pin首先向上游的filter提出**型別的改變,新的**型別格式可以和原來的大小一致,也可以大於。

receiveconnection適用於輸出pin首先提出改變**型別,但是新的**型別的格式大於原來的buffer。

Linux 學習指南

第乙個話題,嵌入式學習的路徑有哪些.這是乙個初學者常問的問題,也是初學者問嵌入式該如何入門的根源.我感覺有兩個方面,偏硬和偏軟.我不認為嵌入式開發軟體佔絕對比重,相反,軟硬體都懂,才是嵌入式高手所應該追求的,也是高手的必由之路.硬體道路 第一步 pcb設計,一般為開發板的電路裁減和擴充,由開發板原理...

Perl學習指南

首先,請考慮如下問題 如果你學過其他語言,那就可以從學習 perl 的語法開始 perl語言入門 或者是從 perl 的自帶文件。當你對 perl 的語法了解後,嘗試書中的例子,試著寫一些簡單的程式。很快你就會發現 perl 和你以前學過的語言類似。如果你是乙個有經驗的程式設計師,你可能直接會從讀程...

SAP HANA 學習指南

sap hana 學習指南 第一部分 sap hana 概覽 第二部分 sap hana資料庫體系結構 2.1 體系結構概覽 2.2 記憶體結構 2.3 sap hana 多版本併發控制 sap hana mvcc 2.4 列儲存 column store 2.5 行儲存 row store 2.6...