關於push和pull模式的說明

最近好像很多人關注網絡數據流的時時播放.要求延時小.所以大家考慮使用push模式.
確實,push模式是針對live streaming video.pull針對的是文件的播放.
可是麻煩的是,如果想使用push播放,並且需要splitter filter的話,就會遇到麻煩了.
(如果,只是播放video,直接連接到decoder filter的話,應該沒有這個麻煩),因爲
並不是所有的splitter filter支持push模式.爲什麼呢?
下面從基本說起.

pull模式:
需要的是IAsyncReader接口.速度的控制是splitter filter代替了source filter.這是
個標準的directshow的機制.outpin必須同意splitter filter的allocator properties.
這就是爲什麼沒有辦法改變傳遞的數據塊的大小了(雖然可以修改每個的大小,可是沒有
辦法改變數據的總大小,就是爲什麼要求的數據一定會是2的次方了32768*6,16384*12等等).
在和splitter的連接過程中,splitter需要讀一些數據來判斷,從而決定流的類型,長度,
和一些相關的信息.連接完後,filter graph開始運行,splitter filter會繼續從source
filter要求數據,使用的是 IAsyncReader::SyncReadAligned() .就完成了render工作.

push模式:
流的控制是source filter完成.在開始連接時,splitter是不會要求數據,所有的判斷操作
都轉交給decoder處理了.render後,就是數據的傳輸了,使用CBaseOutputPin::GetDeliveryBuffer(),
在CBaseOutputPin::Deliver() ,就可以了.但是,最重要的是,push模式的CBaseOutputPin
要求IMemInput接口的支持!可惜的是,不是所有的splitter都有該接口.
(可以在“CBaseOutputPin Class”這章中,看到:
“Connects only to input pins that support the IMemInput interface.” ,CSourceStream
是從CBaseOutputPin繼承的,所以有同樣的問題)

大家可以看到,這是兩個不同的機制.所以就造成了剛纔的麻煩.不是每個splitter會支持
這兩個模式的.不支持push模式的splitter,會單方面的要求IAsyncReader的支持,可是你的
source filter卻不支持,怎麼辦???沒有辦法...結果就是沒有辦法render成功了.

做MPEG2的朋友就有福氣了,對於mpeg2的播放,微軟提供了兩個filter來支持source filter.
MPEG-2 Demultiplexer:這個是支持push模式的filter了.大家可以看看文檔中說的:
The MPEG-2 Demultiplexer (Demux) operates on MPEG-2 transport and program streams
that are delivered in push-mode. (For demultiplexing MPEG-2 program streams that
are delivered in pull-mode, such as in file-playback scenarios, use the MPEG-2 Splitter filter.)
MPEG-2 Splitter filter:這就是基本的splitter filter了.

做MPEG1的朋友們只好使用替代方法了:
如果在pull模式下,把流長度信息該爲infinite的話,就可以從播放時間上等同於push模式.
雖然沒有象push那樣時時,數據的遞交權不在自己的手中,可是在沒有更好的splitter filter
時,還是個不錯的替代方法,至少我做到了1秒的延時(應該不至於沒法忍受:)).
如果有誰找到了支持push的MPEG1的splitter filter,希望能夠告之大家...謝謝了:)


afterain
[email protected]
2001.12.21

 

發佈了34 篇原創文章 · 獲贊 1 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章