• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 181  文章 - 15  trackbacks - 0
            <2008年2月>
            272829303112
            3456789
            10111213141516
            17181920212223
            2425262728291
            2345678

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            My Tech blog

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            一、 總覽:

            Graph、Filter、Pin、Simple

            Graph:可以理解為媒體處理的流程圖。

            Filter:可以理解為媒體處理流程圖中的一個步驟。

            Pin:可以理解為媒體處理各個步驟之間的數據流節點。

            Simple:可以理解為各個形態的數據。

            Filter的分類:

            · source filter:將數據從源(比如媒體文件)引入Graph。

            · transform filter:數據流入、改變、流出。

            · Renderer filters:把最終結果展現給用戶。

            · splitter filter:比如把一個媒體流分解為視頻和音頻。

            · mux filter:和splitter filter相反。

            1. Graph Manager

            主要對處于同一個Graph的Filter(s)進行統一的管理。

            比如:

            · 各個Filter的狀態切換

            · 建立同步時鐘

            · 事件回發

            · 創建

            為什么要統一管理狀態切換?

            因為處于同一Graph中的各個Filter的狀態切換往往需要遵循嚴格的先后順序。所以一般通過發送命令給Graph Manager的方式進行各Filter的狀態變更。

            為什么要建立同步時鐘?

            比如聲像需要同步。

            2. Media Types

            結構體AM_MEDIA_TYPE定義了媒體類型。

            主要包含如下結構:

            · Major type: 由一個GUID來表示。通常包含音視頻、未知流、MIDI等等。

            · Subtype: 由一個GUID來表示。Major type為視頻,則子類型可以包括RGB-24, RGB-32, UYVY

            · Format block: 說明圖形尺寸、幀率等信息。如果Major type為視頻,sub type為RGB-24,則Format block的信息會被自動辨識。

            3. SampleAllocator

            需要注意的是,各個filter之間并不直接傳送它們各自進行處理的數據的指針。它們通過一個暴露IMemAllocator接口的Com組件來分配內存。填充了數據的內存被封裝到Sample里面。各個Filter真正使用的是Sample。Sample通常包含:

            · 內存指針

            · 時間戳

            · 標識

            · 媒體類型(可選)

            這里當一個Filter使用Sample的時候,它同時掌握這個Sample的引用計數,這樣就有效杜絕了資源爭用現象的發生。

            4. Filter Graph中的硬件

            硬件被封裝到Filter中,任何與硬件的交互都轉化為與Filter的交互。

            二、 Graph-Building 組件

            Filter Graph Manager.

            Capture Graph Builder:設計的初衷是視頻捕獲,但是可以衍生很多用途。

            Filter Mapper and System Device Enumerator:枚舉可用的filter.

            DVD Graph Builder

            Video Control

            1. 智能拼接

            1) 如果在Graph里面有一個沒有輸入的Filter,那么Graph在完成自己的時候,就會考慮這個Filter。如果有一個已有的Filter的流出恰好與這個沒有輸入的Filter的流入相匹配,則將這兩個Filter連接。

            2) Graph在完成自己的過程中也會查找所有注冊過的Filter與當前非終點Filter的流出進行匹配。注冊的Filter會有一個權值,作為Graph進行連接嘗試的優先級依據。

            步驟:

            1) 使用IStreamBuilder(如果pin實現了這個接口,但大多數情況沒有)。(否則2)

            2) 查找被緩存的Filter。(否則3)

            3) 查找Graph現有的Filter。(否則4)

            4) 查找所有注冊了的Filter。

            2. 關鍵方法

            IFilterGraph::ConnectDirect:直接連接兩個Filter,如不成功,返回失敗。

            IGraphBuilder::Connect:連接兩個Filter,如果可能,直接連接,否則通過中間Filter(s)進行連接。

            IGraphBuilder::Render:你自己建立了一系列從源開始的Filter,基于這些Filter(s)完成Graph。

            IGraphBuilder::RenderFile:從一個文件開始完成Graph.

            IFilterGraph::AddFilter:向Graph中添加一個Filter

            通過這些方法,你可以:

            1、 由Graph Manager建立整個Graph。(通過RenderFile)

            2、 由Graph Manager建立部分Graph。(比如你想自己寫一個AVI文件,當然也可以通過Render來生成預覽)

            3、 完全手動建立整個Graph。(需要自己AddFilter,還需要自己Connect)。

            三、 Direct Show 數據流概述

            1. 關鍵接口(方法)

            IMediaSample:對Filter之間使用的內存的封裝。

            IMemAllocator::GetBuffer:從allocator獲取Buffer(即ImediaSimple的實現對象)

            摘要:

            由于Render會按照時間戳來Render數據,所以它會一直占用它的上一級Filter流入的Simple,直到時間戳所標識的時間到達。所以當上一級Filter用完了allocator的Simple池中的Simple時,會阻塞而不處理,進而反向影響到更上一級的Filters,從而使它們變為等待的狀態。同時由于時間戳對于Render的時間上的要求,所有上級Render都必須在Simple的時間戳標識的時間到達之前處理完自己對于該Simple的動作。

            2. Transport(傳送)

            · Push Model(推送模型):上層filter(pin-out)將處理好的數據推送給下層filter(pin-in)。下層filter在需要數據的時候通過IMemInputPin::Receive來獲取數據。

            · Pull Model(抓取模型):下層filter(pin-in)在需要數據的時候,通過IAsyncReader異步向上層filter請求數據。(通常用于視頻文件的回放)

            3. Samples and Allocators

            1) 引用計數

            上層Filter(pin-out)通過IMemAllocator::GetBuffer向Allocator申請Simple,如果此時沒有Simple的引用計數為0,則說明Allocator的Simple池中沒有可用的Simple,則GetBuffer的調用會被阻塞。一旦Simple池中出現可用的Simple,則先前阻塞的GetBuffer放行,并獲取一個引用計數變為1的Simple。此Simple處理后,傳遞給下層Filter(pin-in),下層Filter如果在Receive方法中處理Simple,則它與上層Filter的處理處于同一線程中,Simple的引用計數不會變化,如果下層Filter需要通過創建線程異步使用上層推入的Simple進行處理,則該Simple的引用計數會加1,變為2.之后如果上層Filter的推送線程結束,則Simple的引用計數減1,變為1.

            2) 提交和撤銷Allocator

            IMemAllocator::Commit,在被調用之前,所有的GetBuffer無效,

            調用IMemAllocator::Decommit之后,所有的GetBuffer調用無效.

            4. Filter 狀態變化

            Filter狀態的變化由Graph Manager進行控制。

            所有的狀態變化都是自低(Render Filter)向上(Source Filter)進行的。比如暫停的時候,Render Filter會首先暫停,這時候Render之上的Filter中都會存有未能推送的Simple,此時相當于在各個Filter之前都堆積了一些等待處理的數據。沿著Render向上的Filter逐個暫停,直到Source。當狀態從暫停變化為開始的時候,Render會首先變化為開始狀態,處理在它之前堆積的數據,并釋放那些被占用的Simple。然后逐步向上直到Source,Source在能夠獲取Simple之后,數據繼續流入Graph,整個Graph進入開始狀態。

            posted on 2008-02-22 22:10 littlegai 閱讀(1076) 評論(0)  編輯 收藏 引用 所屬分類: 我的讀書筆記
            久久久久亚洲精品日久生情| 伊人久久一区二区三区无码| 亚洲精品无码久久久| 精品久久久久久综合日本| 久久精品成人| 国产成人精品三上悠亚久久| 久久精品国产99国产精品澳门| 色偷偷偷久久伊人大杳蕉| 久久香蕉国产线看观看99| 久久99这里只有精品国产| 国产国产成人久久精品 | 亚洲精品乱码久久久久久蜜桃图片| 久久99精品久久只有精品| 日本久久久久久久久久| 国产人久久人人人人爽| 国产呻吟久久久久久久92| 久久99这里只有精品国产| 91久久精品国产成人久久| 久久99中文字幕久久| 亚洲v国产v天堂a无码久久| 久久久久AV综合网成人| 亚洲中文久久精品无码| 2021国产成人精品久久| 无码AV波多野结衣久久| 精品国产婷婷久久久| 久久久艹| 99久久成人国产精品免费| 久久99精品久久只有精品| 色综合久久天天综线观看| 99久久精品国产高清一区二区 | 亚洲精品乱码久久久久久久久久久久| 91精品国产高清91久久久久久| 久久国产综合精品五月天| 97久久超碰成人精品网站| 伊人久久久AV老熟妇色| 麻豆精品久久久久久久99蜜桃| 国产精品久久久久一区二区三区| 人妻少妇久久中文字幕| 久久国产亚洲精品| 久久AV高清无码| 亚洲人成伊人成综合网久久久 |