4. DirectShow-數(shù)據(jù)流動(dòng)的過(guò)程

數(shù)據(jù)與數(shù)據(jù)緩沖區(qū)

數(shù)據(jù)保存在緩沖區(qū)中,緩沖區(qū)只是字節(jié)數(shù)組。 每個(gè)緩沖區(qū)由名為 MediaSample的 COM 對(duì)象包裝车荔,該對(duì)象實(shí)現(xiàn) IMediaSample 接口。 MediaSample由另一種類型的對(duì)象(稱為分配器)創(chuàng)建砾赔,該對(duì)象實(shí)現(xiàn) IMemAllocator 接口。 雖然兩個(gè)或更多個(gè)pin連接可能共享同一分配器青灼,但為每個(gè)pin連接分配一個(gè)分配器暴心。 下圖演示了此過(guò)程。

image.png

MediaSample是承載數(shù)據(jù)的載體

每個(gè)分配器創(chuàng)建MediaSample池杂拨,并為每個(gè)MediaSample分配緩沖區(qū)专普。 每當(dāng)filter需要使用數(shù)據(jù)填充緩沖區(qū)時(shí),它都會(huì)通過(guò)調(diào)用 IMemAllocator::GetBuffer 從分配器請(qǐng)求MediaSample弹沽。 如果分配器具有其他filter當(dāng)前未使用的任何MediaSample檀夹, GetBuffer 方法將立即返回,并返回指向MediaSample的指針策橘。 如果分配器的所有MediaSample都在使用中炸渡,則 方法將阻塞,直到MediaSample可用丽已。 當(dāng) 方法返回MediaSample時(shí)蚌堵,filter會(huì)將數(shù)據(jù)放入MediaSample里面的緩沖區(qū), (設(shè)置相應(yīng)的標(biāo)志沛婴,通常包括時(shí)間戳) 吼畏,并將MediaSample傳送到下游。

當(dāng)呈現(xiàn)器filter收到MediaSample時(shí)嘁灯,它會(huì)檢查時(shí)間戳并保留MediaSample泻蚊,直到filter圖的引用時(shí)鐘指示應(yīng)呈現(xiàn)數(shù)據(jù)。 filter呈現(xiàn)數(shù)據(jù)后旁仿,會(huì)釋放MediaSample藕夫。 在MediaSample的引用計(jì)數(shù)為零之前孽糖,MediaSample不會(huì)返回到分配器的MediaSample池中枯冈,這意味著每個(gè)filter都釋放了MediaSample毅贮。 下圖演示了此過(guò)程。

image.png

MediaSample可以作為上游生產(chǎn)者和下游消費(fèi)者中間的緩沖幀

上游filter可能在呈現(xiàn)器之前運(yùn)行尘奏,也就是說(shuō)滩褥,它填充緩沖區(qū)的速度可能比呈現(xiàn)器使用緩沖區(qū)快。 即便如此炫加,MediaSample也不會(huì)提前呈現(xiàn)瑰煎,因?yàn)槌尸F(xiàn)器會(huì)保留每個(gè)MediaSample,直到其呈現(xiàn)時(shí)間為止俗孝。 此外酒甸,上游filter不會(huì)意外覆蓋緩沖區(qū),因?yàn)?GetSample 僅返回未使用的示例赋铝。 上游filter可以提前運(yùn)行的數(shù)量取決于分配器池中的MediaSample數(shù)插勤。

上圖僅顯示一個(gè)分配器,但通常每個(gè)流有多個(gè)分配器革骨。 因此农尖,當(dāng)呈現(xiàn)器釋放示例時(shí),它可以具有級(jí)聯(lián)效果良哲。 下圖顯示了解碼器在等待呈現(xiàn)器釋放示例時(shí)保存壓縮的視頻幀的情況盛卡。 分析器filter也在等待解碼器發(fā)布示例。

image.png

當(dāng)呈現(xiàn)器釋放其示例時(shí)筑凫,解碼器對(duì) GetBuffer 的掛起調(diào)用將返回滑沧。 然后,解碼器可以解碼壓縮的視頻幀并釋放它所持有的MediaSample巍实,從而解除阻塞程序掛起的 GetBuffer 調(diào)用滓技。

本地內(nèi)存的數(shù)據(jù)傳輸機(jī)制

DirectShow 定義了本地內(nèi)存?zhèn)鬏數(shù)膬煞N機(jī)制:推送模型和拉取模型。

在推送模型中蔫浆,源filter生成數(shù)據(jù)并將其傳遞到下游的下一個(gè)filter殖属。 該filter被動(dòng)接收數(shù)據(jù)、處理數(shù)據(jù)瓦盛,并將數(shù)據(jù)發(fā)送到下游洗显。
在拉取模型中,源filter連接到分析器filter原环。 分析程序filter從源filter請(qǐng)求數(shù)據(jù)挠唆。 源filter通過(guò)傳遞數(shù)據(jù)來(lái)響應(yīng)請(qǐng)求。
推送模型使用 IMemInputPin 接口嘱吗,拉取模型使用 IAsyncReader 接口玄组。
推送模型比拉取模型更常見滔驾。 因此,以下文章采用推送模型俄讹。 本部分的最后一篇文章 “拉取模型”介紹了 IAsyncReader 接口與 IMemInputPin 的區(qū)別哆致。

當(dāng)pin將媒體數(shù)據(jù)傳送到另一個(gè)pin時(shí),它不會(huì)將直接指針傳遞給內(nèi)存緩沖區(qū)患膛。 相反摊阀,它傳遞指向管理內(nèi)存的 COM 對(duì)象的指針。 此對(duì)象稱為 MediaSample踪蹬,公開 IMediaSample 接口胞此。 接收pin通過(guò)調(diào)用 IMediaSample::GetPointer、IMediaSample::GetSize 和 IMediaSample::GetActualDataLength 等方法來(lái)訪問(wèn)內(nèi)存緩沖區(qū)跃捣。

MediaSample始終從輸出pin到輸入pin向下游移動(dòng)漱牵。 在推送模型中,輸出pin通過(guò)在輸入pin上調(diào)用 IMemInputPin::Receive 來(lái)提供MediaSample疚漆。 輸入pin將完全在 Receive 方法內(nèi)同步 (處理數(shù)據(jù)) 酣胀,或在工作線程上異步處理數(shù)據(jù)。 如果需要等待資源愿卸,則允許輸入pin在 Receive 方法中阻塞灵临。

在 IMemInputPin 接口中,上游filter確定要發(fā)送的數(shù)據(jù)趴荸,并將數(shù)據(jù)推送到下游filter儒溉。 對(duì)于某些filter, 拉取模型更合適发钝。 此處顿涣,下游filter從上游filter請(qǐng)求數(shù)據(jù)。 MediaSample仍會(huì)從輸出pin到輸入pin向下游移動(dòng)酝豪,但下游filter會(huì)啟動(dòng)數(shù)據(jù)流涛碑。 這種類型的連接使用 IAsyncReader 接口。

拉取模型的典型用途是在文件播放中孵淘。 例如蒲障,在 AVI 播放圖中, 異步文件源 filter執(zhí)行一般文件讀取操作瘫证,并將數(shù)據(jù)作為字節(jié)流傳遞揉阎,而沒有格式信息。 AVI 拆分器filter讀取 AVI 標(biāo)頭并將流分析為視頻和音頻MediaSample背捌。 與異步文件源filter相比毙籽,AVI 拆分器可以確定所需的數(shù)據(jù),因此它使用 IAsyncReader 而不是 IMemInputPin毡庆。

若要從輸出pin請(qǐng)求數(shù)據(jù)坑赡,輸入pin調(diào)用以下方法之一:
IAsyncReader::Request
IAsyncReader::SyncRead
IAsyncReader::SyncReadAligned烙如。
第一種方法是異步的,用于支持多個(gè)重疊讀取毅否。 其他是同步的亚铁。

理論上,任何filter都可以支持 IAsyncReader搀突,但在實(shí)踐中刀闷,它專為連接到分析程序filter的源filter而設(shè)計(jì)熊泵。 分析程序的作用非常類似于推送模型中的源filter仰迁。 暫停時(shí),它會(huì)創(chuàng)建一個(gè)流式處理線程顽分,該線程從 IAsyncReader 連接拉取數(shù)據(jù)并將其推送到下游徐许。 輸出pin使用 IMemInputPin,圖形的其余部分使用標(biāo)準(zhǔn)推送模型卒蘸。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末雌隅,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子缸沃,更是在濱河造成了極大的恐慌恰起,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件趾牧,死亡現(xiàn)場(chǎng)離奇詭異检盼,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)翘单,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門吨枉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人哄芜,你說(shuō)我怎么就攤上這事貌亭。” “怎么了认臊?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵圃庭,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我失晴,道長(zhǎng)剧腻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任师坎,我火速辦了婚禮恕酸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘胯陋。我一直安慰自己蕊温,他們只是感情好袱箱,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著义矛,像睡著了一般发笔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上凉翻,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天了讨,我揣著相機(jī)與錄音,去河邊找鬼制轰。 笑死前计,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的垃杖。 我是一名探鬼主播男杈,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼调俘!你這毒婦竟也來(lái)了伶棒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤彩库,失蹤者是張志新(化名)和其女友劉穎肤无,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體骇钦,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宛渐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了司忱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片皇忿。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖坦仍,靈堂內(nèi)的尸體忽然破棺而出鳍烁,到底是詐尸還是另有隱情,我是刑警寧澤繁扎,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布幔荒,位于F島的核電站,受9級(jí)特大地震影響梳玫,放射性物質(zhì)發(fā)生泄漏爹梁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一提澎、第九天 我趴在偏房一處隱蔽的房頂上張望姚垃。 院中可真熱鬧,春花似錦盼忌、人聲如沸积糯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)看成。三九已至君编,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間川慌,已是汗流浹背吃嘿。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留梦重,地道東北人兑燥。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像忍饰,于是被迫代替她去往敵國(guó)和親贪嫂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容