2017-02-28 78 views
2

我正在學習Windows媒體基礎。
我測試了Windows SDK中提供的幾個示例應用程序。
我有從相機和視頻播放文件的視頻捕獲示例應用程序。合併兩個視頻流在一個流中,如畫中畫(WMF)

我想存檔的是將這兩個視頻源組合在一個視頻源中,然後生成一個視頻流,如畫中畫。 Windows媒體基礎如何做到這一點?

我已閱讀有關MFCreateAggregateSource
https://msdn.microsoft.com/en-us/library/windows/desktop/dd388085(v=vs.85).aspx

MFCreateAggregateSource在這種情況下使用,或者它只是用於混合音頻和視頻流?

我想在全屏模式下放置一個視頻,然後在小窗口的第一個視頻的右上角顯示另一個視頻流。

這是如何使用媒體基礎完成的?

** **更新

我更多的關注,利用WMF其解碼並隨後將它們混合,然後重新編碼它們,然後寫入文件讀取兩個視頻流。而不是在屏幕上渲染它們。

回答

2

MFCreateAggregateSource不會進行視頻混合。它將僅從兩個來源創建一個來源,例如,可由MediaSession使用(通過拓撲和拓撲節點)。

如果你只是想顯示兩個視頻,你可以使用Enhanced Video Renderer

您可以使用MFCreateAggregateSource每個流連接EVR。如果你不想處理時間戳/解碼器等等,你還需要使用媒體會話(IMFMediaSesion)。

+0

這就是我所做的,但現在我正努力在一個窗口中分別顯示兩個視頻。我試圖使用'm_pVideoMixerControl-> SetStreamOutputRect(0,&rect)',但它不起作用。如何做到這一點。 – User7723337

+0

你通過什麼值。 rect在0.0到1.0的範圍內。例如MFVideoNormalizedRect rcHalf = {0.0,0.0,0.5,0.5};同時使用m_pStreamSink-> GetIdentifier檢查流的標識符是否正確。 – mofo77

1

您的任務非常不尋常,並且沒有任何媒體基礎組件允許將兩個視頻流合併爲一個。然而,'IMFMediaSesion'支持通過'MFCreateAggregateSource'在一個源中處理兩個視頻流。這意味着像'LEGO'這樣的媒體基金會可以讓您自行撰寫解決方案,將兩個視頻流合併爲一個像畫中畫一樣的視頻流,但它本身並不支持這種功能。

問候。

P.S.我想建議閱讀'開發微軟媒體基礎應用程序' '安東波林格'(Developing Microsoft® Media Foundation Applications) - 它包含了很多例子的一個流,但它包含了'WaterMarkTransform'的代碼 - 用於注入圖像的代碼Media Foundation Transform進入視頻流 - 爲您的解決方案啓動此類代碼凸輪 - 將一個視頻流注入另一個視頻流。

P.S.我有一個錯誤 - 我看到你只想顯示畫中畫 - 所以EVR - 默認的視頻渲染器支持16個視頻流 - 一個參考和15個額外的 - 你需要通過'MFCreateVideoRendererActivate'創建'VideoRenderer',然後創建每個視頻流(對於兩個流中的每一個,你的情況)TopologyNode,爲每個TopologyNode設置已經通過設置'SetObject'創建的'VideoRenderer' - 結果許多視頻流將使用ONE'VideoRenderer'。BY設置SetUINT32TopologyNode'MF_TOPONODE_STREAMID',您必須選擇哪個流將參考 - '背景圖片' - 通過設置0,以及哪個流將爲'MF_TOPONODE_STREAMID'大於0(例如1)的additional Pictureadditional Picture的位置可以通過IMFVideoMixerControl來控制 - 它包括下列方法: GetStreamOutputRect - 檢索合成矩形內視頻流的位置。

GetStreamZOrder - 檢索視頻流的z順序。

SetStreamOutputRect - 設置合成矩形內視頻流的位置。

SetStreamZOrder - 設置視頻流的z順序。

+0

嗨@Evgeny Pereguda:感謝您發佈此詳細信息,這非常有幫助。所以根據最新的更新,可以使用Windows媒體基礎混合兩個視頻流。如果你有任何實現這個或任何文檔的例子,可以描述它是如何實現的,這將有助於我理解流程。另外我對拓撲有點困惑,它在實現時如何使用。再次感謝您的幫助。 – User7723337

+0

嗨@Evgeny Pereguda:同樣如果我們想將混合視頻(畫中畫)保存到一個文件中,那麼該怎麼做? – User7723337

+0

我可以推薦閱讀'Anton Polinger'開發的'開發Microsoft®Media Foundation應用程序'一書 - 它是解釋Media Foundation Topology概念的一本書。我有這本書的代碼示例 - 。此外,您可以研究我的項目om Media Foundation [在Windows 7和Windows 8上從網絡攝像機捕捉實時視頻](https://www.codeproject.com/articles/776058/捕獲實時視頻 - 從網絡攝像頭在Windows上) - 這個項目有與網絡攝像頭一起工作的代碼 - 它包括了在實時視頻中注入圖像的例子 - 'WaterMark'。 –

1

MFCreateAggregateSource甚至序列發生器可能對視頻混合工作正常,但爲了更好地控制過程,在我參與的項目中,我使用了多個MFSourceReaders來MFSinkWriter方法。這樣,如果我將EVR附加到接收器寫入器,或者將輸出視頻存儲在文件中,我都可以顯示混合視頻內容。在我正在開發的項目中,要求僅輸出到mp4,但稍後我將不得不添加預覽支持。爲此,我打算使用兩個接收器作家 - 一個用於EVR(或DX11VideoRenderer),一個用於MP4接收器。實施工作非常穩定。它有一個視頻混合線程,可以從每個源讀取器讀取,匹配時間戳,混合視頻樣本,並將混合視頻樣本或音頻樣本(僅一個)輸出到接收器寫入器。希望這可以幫助。

+0

是否可以提供更多關於這個或任何涉及混合兩個視頻流的組件示例的詳細信息。目前,我並不擔心顯示混合流,但是,1.閱讀兩個流,2.混合然後寫入文件。所以我會讀流使用WMF API解碼它們,然後混合它們,然後重新編碼它們,然後寫入文件。 – User7723337

+1

這個想法是爲每個源(文件,捕獲)創建一個IMFSourceReader。爲其中的每一個實現一個IMFSourceReaderCallback,以便異步接收樣本並將每個樣本放入一個隊列中。然後在一個單獨的線程中取出樣本並混合視頻樣本(例如使用directx)。您可以使用從EVR獲取或由您創建的DirectX管理器(DX設備)配置IMFSourceReaders。您可以通過IMFSinkWriter對象將混合視頻樣本提供給EVR。或者您可以檢查MFCaptureD3D樣本,瞭解如何直接使用DX繪製混合樣本。 – VuVirt

+0

感謝您的詳細信息。我們如何使用DirectX來混合兩個流樣本?當我們混合採樣時,我們如何配置EVR進行顯示。 – User7723337