directx的媒體對象

來源:互聯網
上載者:User
微軟的directx媒體對象簡稱DMOs,是一種寫流資料的新方法。由於某些原因,DMOs非常象微軟的directshow過濾器。DMO處理資料是利用輸入資料來產生輸出資料的。DMO比組件API函數更加類似directshow。因此,DMO非常容易建立、測試和使用。DMO完全相容directshow,但應用程式可以在沒有directshow的情況下使用DMO。在directshow的應用程式裡,DMO被directshow過濾器封裝,稱為DMO封裝過濾器。過濾器和DMO的區別就在於對於應用程式的透明度,也就是哪個是不需要使用DMO的API,即應用程式可以不用directshow而直接使用DMO。因此寫一個DMO,將建立一個在應用程式中可以被廣泛使用的組件。DMO和directshow過濾器的區別Directshow過濾器僅僅工作在directshow過濾映像中。在映像中,過濾映像管理器在應用程式和過濾器之間作為一種媒介。DMO則沒有這種要求,一個應用程式可以單獨的使用DMO。在directshow中,過濾器將為流資料作大量的工作。包括:·分配緩衝。·裁決媒體類型和串連到其它的過濾器·通過濾波圖形壓棧資料·將事件發送給過濾圖形管理器·同步多線程相對照,一個DMO不作上述的任何事情。而是由客戶使用這些DMO類型。客戶給它們分配緩衝並進行資料填充。然後將緩衝傳給DMO,DMO將處理它們。客戶獲得輸出緩衝。在DirectShow中,DMO封裝過濾器是DMO的一個客戶,因此可以處理所有這些任務,而其它應用程式能過提供自己的應用執行個體。DMOs有以下先進特性:·有較少的函數支援,因此通常較directshow過濾器小且簡單。·因為不要求過濾圖形因此比directshow要更加靈活。當需要directshow提供的服務時,便可以使用它,例形的同步、智能串連、自動處理流資料和線程管理。如果不需要這些服務,可以直接存取DMO。·DMOs常常可以處理同步的資料,這樣會避免過濾器開發人員所必須考慮的很多線程的問題。·不象acm和vcm解碼,DMO是基於元件物件模型的,因此可以通過QueryInterface介面進行擴充。·DMOs比acm和vcm解碼支援更多的無規律的流模式。像directshow過濾器,DMOs還支援多輸入和多輸出。由於以上原因,應該儘可能的使用DMO而不是directshow。然而也由一些情況是DMO不適合的。例如:·異常傳輸要求。DMO封裝過濾器使用ImemInputPin傳輸。如果需要在directshow應用程式中用到別的傳輸機制,那麼就必須重新寫一個過濾器。 ·建立動態圖形。如果應用程式執行了動態圖形建立,或許需要寫一個自己的過濾器。例如需要控制分配程式的建立。DMO測試程式Directx8.0 SDK包括了一個測試DMO的程式。名字叫:DMOtest。這個測試程式可以協助檢驗DMO。這個程式安裝在SDK的bin/DXUtils目錄中。如果要進行DMO開發,那麼DMO測試程式將是測試的一部分。為了使用DMOtest,必須為DMO產生一個測試資料。為此SDK包含了一個 DMOdump.dll中的directshow過濾器,需要用regsvr32進行這個過濾器的註冊。 使用DMO媒體對象這一節描述了怎樣在應用程式中使用DMO對象。這裡只講述直接存取DMOs的方法。在directshow中使用DMO的方法,將在下面的章節講解。本節包含以下部分。·流和緩衝·資料流·怎樣處理資料·可丟棄和可選擇的流·內部處理的DMOs流和緩衝一個DMO擁有m個輸入產生n個輸出的對象。輸入和輸出都叫做流。每一個DMO至少有一個流。一個DMO可以沒有輸入資料流或者沒有輸出資料流,但典型的DMO是包括輸入和輸出資料流的。注意:流不是明晰的COM對象。它們是DMO對象自身的引用,是從基於0開始的索引。一個DMO是通過輸入資料流來獲得資料。它首先處理資料然後通過輸出資料流產生輸出。所有資料類型都使用一個媒體類型(media type)。媒體類型定義了怎樣識別資料的內容。例如,320×240 的24位 rgb視頻是一種類型;44.1千赫茲16位立體的pcm音頻是另外一種類型。用DMO_MEDIA_TYPE結構描述媒體類型。一個DMO中的每個流都可以接收某個範圍的媒體類型。利用DMO,既可接收任意大位的視頻流,也可只支援16位的視頻。一個DMO可以被限制到特定關係的輸入和輸出。例如,如果一個輸入資料流被設定到16位視頻,可能相應的輸出會要求同樣的位。應用程式可以枚舉每一個流首選的媒體類型和測試指定的輸入輸出關聯。例如:·一個建立avi資料的DMO可以有兩個輸入資料流,一個是視頻,一個是音頻。它卻可能產生一個輸交叉存取音頻視頻的資料流。·一個多色調分色印的rgb映像可能有24位的rgb的視頻輸入和8位的rgb視頻輸出。應用程式提交的輸入資料在記憶體塊中被劃分。每個記憶體塊被一個叫緩衝區的COM對象封裝,這個緩衝區必須支援ImediaBuffer介面。這個介面包含了設定緩衝資料長度,接收資料指標,接收緩衝分配的尺寸的方法。應用程式可以用這種方法來分配所有的緩衝區,這個針對輸入和輸出兩者都適用。資料流這一節講述了怎樣在應用程式和DMO中進行資料的移動。應用程式交替的進行交付輸入緩衝和請求輸出兩種動作。處理輸入緩衝可以調用DMO中的ImediaObject::ProcessInput方法。處理輸出緩衝可以調用ImediaObject::ProcessOutput方法。有兩種方法可以停止輸入資料流。·中斷方式:當一個應用程式輸入資料完結,或者資料中有中斷,那麼應用程式會用訊號通知終止。中斷通知DMO後將不會再有輸入,與此同時,DMO可以仍然進行資料處理,因此應用程式應該請求輸出,直到DMO通知沒有剩餘資料時才可以真正結束。·沖洗方式:應用程式可以用沖洗方式中斷資料流。如果DMO有資料在緩衝中,那麼資料將被立即釋放。流的開始是在應用程式第一次調用IMediaObject::ProcessInput。但是DMO會直到應用程式為每個流都設定了媒體類型之後才會開始流的運作。(非強制性的流除外)當應用程式以沖洗方式通知DMO,或者以中斷方式通知每個流資料然後處理了所有的輸出之後,流資料才會被停止。這些行為將會使DMO返回到非流狀態。DMO將會保留所有的媒體類型設定,但將會釋放掉所有的ImediaBuffer指標。以後不會在有任何的輸出,直到應用程式再次調用ProcessInput。處理流資料將執行以下步驟。1.           查詢DMO來獲得流的數量和每一個流首選的媒體類型。2.           為所有的流設定媒體類型。3.           分配輸入緩衝和輸出緩衝。4.           調用ProcessInput填充輸入緩衝區。5.           調用ProcessOutput接收輸出資料。重複4和5,直到所有的輸入資料被處理。6.           發一個中斷訊號然後將剩餘的輸出處理完畢。可以用沖洗資料的辦法來中斷步驟4到6。怎樣處理資料這一節將更詳細的解釋前面列出的步驟。步驟1 查詢DMO首先,查詢DMO來獲得流的數量和每一個流首選的媒體類型。為了得到輸入資料流和輸出資料流的數量,可以調用IMediaObject::GetStreamCount方法。對於每一個流來講,DMO會將按照首選媒體類型的優先順序的順序來排列,然後為每一個類型分配索引,索引是從0開始的。為了得到一個首選的媒體類型的細節,可以調用IMediaObject::GetInputType 方法來處理輸入,輸出可以調用IMediaObject::GetOutputType方法。為了枚舉一個流中所有的媒體類型,可以使用迴圈遞增媒體類型的索引直到方法返回DMO_E_NO_MORE_ITEMS,下面是示範代碼。 
DWORD cInputs, cOutputs, type = 0
DMO_MEDIA_TYPE mt
 
pDMO->GetStreamCount(&cInputs, &cOutputs)
 
for (DWORD i = 0; i < cInputs; i++)
{
    while (pDMO->GetInputType(i, type, &mt) != DMO_E_NO_MORE_ITEMS)
    {
        if ( this media type is one you want )
            break
        MoFreeMediaType(&mt)
        type++
    }
}
GetInputType和GetOutputType方法返回一個DMO_MEDIA_TYPE結構。下面就是相應的結構成員。·主類型:被指定流媒體類型的GUID。主類型是一般的分類,象視頻和音頻一樣。·子類型:一個指定流子類型的GUID。子類型是更細的分類。如MEDIASUBTYPE_RGB24 2特指24位rgb視頻。·pbFormat:一個指向結構裡描述格式的指標。格式結構指定的資訊比如是視頻的寬高,或者一個音頻速率等等。不同的媒體類型使用不同的格式。大部分視頻資料使用VIDEOINFOHEADER結構。音頻資料使用WAVEFORMATEX結構。·formattype:指定了包含了pbFormat的格式結構。媒體類型可能有一個NULL的格式結構,表示formattype是GUID_NULL的值。一個NULL的格式預示DMO可以接受指定媒體類型內部一定範圍的格式。例如,一個流要求PCM音頻和其相近的採樣率範圍的格式。因此它將會返回MEDIATYPE_Audio作為主類型,NULL格式的MEDIASUBTYPE_PCMAudio子類型。應用程式必須調用MoFreeMediaType函數來釋放pbFormat。步驟2 設定媒體類型在找到DMO的主媒體類型之後,設定每個流的媒體類型可以調用ImediaObject::SetInputType和IMediaObject::SetOutputType方法。DMO不能保證每個被報告的媒體類型組合都是有效。就象輸出類型可能需要匹配輸入類型。你可以測試一個媒體類型,用DMO_SET_TYPEF_TEST_ONLY標誌來調用 SetInputType或者SetOutputType。對於解碼器,你通常應該設定輸入類型然後在選擇一個輸出類型。對於編碼器,你應該設定輸出類型然後選擇一個輸入類型。因為設定一個流將會影響到別的流,因此你需要將以前設定的媒體類型清除。這個功能可以調用SetInputType或者SetOutputType,參數填充DMO_SET_TYPEF_CLEAR標誌。步驟3 分配緩衝在設定媒體類型之後,每個緩衝請求查詢DMO。這些可以依靠媒體類型來改變。對於每個流來講,可以調用MediaObject::GetInputSizeInfo 或者IMediaObject::GetOutputSizeInfo方法。這些方法返回三個值:·最小緩衝尺寸,以位元組為單位·如果一個緩衝是被對齊的,如果起始地址是一些指定整數的倍數,這些情況下對齊是被要求的。·對於一些輸入緩衝,最大資料的數量被DMO控制。要求輸入的資料是緩衝的倍數必須分配足夠的緩衝來處理這些請求。為了符合尺寸要求,一個輸入資料流可以要求每個緩衝包含唯一的完整的採樣,或者包含精確的一個採樣,或者使用一個固定的採樣尺寸。為了實現這些要求,可以調用IMediaObject::GetInputStreamInfo方法。步驟4 處理輸入現在可以交付一個輸入緩衝給DMO。對於每一個輸入資料流,用媒體資料填充一個或者多個輸入緩衝。可以直接的向緩衝寫資料,或者從另外一個DMO上使用一個輸出緩衝。調用ProcessInput方法來交付每一個緩衝。當應用程式沖洗DMO的時候,緩衝可以被釋放,但千萬不要在DMO釋放之前重複使用緩衝。為了決定一個流是否可以接收更多的資料,可以調用IMediaObject::GetInputStatus方法。如果流可以接受更多的資料,那麼此方法將會返回DMO_INPUT_STATUSF_ACCEPT_DATA標誌。步驟5 處理輸出鑒於ProcessInput一次交付一個出入緩衝,因此ProcessOutput通常一次輸出所有的流資料。應用程式傳遞一個DMO_OUTPUT_DATA_BUFFER矩陣,這個結構用於每個輸出資料流。這個結構包含了一個指向輸出緩衝的指標和被填充的不同資訊。在ProcessOutput方法中,DMO會產生儘可能多的資料(被給定的輸出緩衝大小)。如果在處理所有的資料前填充了輸出緩衝,它將會在dwStatus結構中設定DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE標誌。當方法返回時,將會檢查每個結構的這個標誌。如果標誌是存在,則重新調用ProcessOutput。在流開始之後,DMO可以一直接收資料,或者產生輸出資料,或者兩者同時產生。因此不是GetInputStatus返回DMO_INPUT_STATUSF_ACCEPT_DATA標誌,就是ProcessOutput返回DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE標誌。應用程式保持資料流就是通過測試這些標誌和調用ProcessInput或者ProcessOutput。步驟 6 發出中斷訊號當交付所有的有效輸入資料後,調用IMediaObject::Discontinuity方法進行結束。可丟棄和可選擇的(非強制性的)流一個DMO可以指定一些輸出資料流作為可丟棄的或者是可選擇的:·一個可丟棄的流包括應用程式可以丟棄的資料,完整的或者間斷的採樣。·一個可選擇的流是一個不是所有應用程式都需要的次要的流,或者是包括主流附加資訊的流。要了查詢一個流是否為可丟棄或者是可選的,可以調用IMediaObject::GetOutputStreamInfo方法和檢測pdwFlags參數。DMO_OUTPUT_STREAMF_DISCARDABLE標誌表明了流是具有可丟棄的特點。DMO_OUTPUT_STREAMF_OPTIONAL標誌則表示流具有可選擇的特點。通常至少有一個流是不可選擇的。當調用IMediaObject::ProcessOutput方法時,可以從一個或者多個流中通過在dwFlags參數中設定DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER標誌來丟棄資料。對於每個想丟棄的流來說,都要設定DMO_OUTPUT_DATA_BUFFER結構的pBuffer為空白。如果pBuffer是NUL,但又沒有設定DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER標誌,那麼DMO將不會丟棄資料,就算流是可丟棄的或者是可選擇的都無濟於事。萬一pBuffer是NULL但沒有資料被丟棄,那麼DMO將會發一個DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE標誌來表明這個流仍然有資料的。如果有輸出資料流沒有處理,但又不丟棄它,DMO將不能在別的輸出資料流中產生資料。如果從不使用可選擇的流,那麼就沒有必要設定它的媒體類型了。同樣的情況不適合可丟棄的流。必須在一個可丟棄的流中設定媒體類型。in-place 媒體對象某些資料轉換可直接由修改資料來acCOMplished,這既是所謂的in-place 處理。許多音頻和視頻效果可在適當位置進行處理。In-place 處理比直接把資料複製到另一緩衝有效。為了處理in-place資料, 可單獨調用IMediaObjectInPlace::Process 方法, 而不是分開調用ProcessInput 和ProcessOutput。傳遞一個包含輸入資料的位元組數組。當方法返回時,位元組數組包含輸出資料。支援IMediaObjectInPlace 的必須支援所有MediaObject 方法。可以選擇使用in-place 處理或建立獨立的輸入、輸出緩衝。注意不要混淆兩種類型的處理。如果調用 Process, 就不要調用 ProcessInput 或 ProcessOutput,反之亦然。在輸入停止後,in-place DMO 可建立一些附加輸出,即所謂尾效果(effect tail)。例如,混響效果在輸入“安靜”後仍持續工作。DMO 產生尾效果,程式必須用零輸入緩衝調用Process 方法直到尾 被COMpletely 處理。
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.