2016-07-25 111 views
5

我正嘗試使用MediaFoundation API對視頻進行編碼,但我遇到了將示例推送到SinkWriter的問題。使用Media Foundation對Direct X表面進行編碼

我正在通過Desktop Duplication API獲取要編碼的幀。我最終得到的是帶有桌面圖像的ID3D11Texture2D。

我試圖創建一個包含此表面的IMFVideoSample,然後將該視頻示例推送到SinkWriter。

我試着去了解這個以不同的方式:

  • 我叫MFCreateVideoSampleFromSurface(texture, &pSample)其中質地的ID3D11Texture2D,填補了SampleTime和SampleDuration,然後通過創建樣品到SinkWriter。
    SinkWriter返回了E_INVALIDARG。

  • 我嘗試通過傳遞nullptr作爲第一個參數並使用MFCreateDXGISurfaceBuffer自己創建緩衝區,然後將生成的緩衝區傳遞到Sample中來創建示例。
    這也沒有工作。

  • 我閱讀了MediaFoundation文檔,找不到有關如何從DirectX紋理創建樣本的詳細信息。

我跑出來的東西嘗試。
有沒有人在那裏使用過這個API,並且可以想到我應該檢查的東西,或者我可以怎樣去調試這個東西?

+0

我認爲你使用MFCreateVideoSampleFromSurface和MFCreateDXGISurfaceBuffer犯了一個錯誤。這些函數創建用於寫入DirectX和可視化表面的緩衝區,並使用接口「IMF2DBuffer」創建對象,但編碼器和編寫器需要具有「IMFMediaBuffer」的對象。他們無法理解'IMF2DBuffer'。嘗試使用函數'MFCreateSampleCopierMFT' - 它創建的MFT對象用於從[IMFMediaBuffer]複製到[MSDN]上的IMF2DBuffer(https://msdn.microsoft.com/en-us/library/windows/desktop/dd388101(v = vs.85)的.aspx)。可能是它可以做倒轉的工作!?! –

+0

你確定嗎? 查看「MFCreateDXGISurfaceBuffer」的文檔,它指出它返回一個指向IMFMediaBuffer的指針。 –

+0

您可以嘗試通過'MFCreateDXGISurfaceBuffer'中的'IMFMediaBuffer'緩衝區獲取數據。 –

回答

1

首先你應該學會使用mftrace tool。 很可能,它會馬上告訴你這個問題。

但我的猜測是,下列問題可能發生。

  1. 可能除了SampleTime/SampleDuration之外,還需要其他一些屬性。

  2. 也許,SinkWriter需要一個可以在CPU上讀取的紋理。爲了解決這個問題,當一個框架可用時,創建一個相同格式+大小的分段紋理,調用CopyResource將桌面複製到分段紋理,然後將該分段紋理傳遞給MF。

  3. 即使您使用硬件編碼器,以便CPU從不嘗試讀取紋理數據,我認爲將桌面紋理直接傳遞給MF也不是一個好主意。

當您爲示例設置D3D紋理時,沒有數據被複制到任何地方,該示例僅保留紋理。

MF工作異步,它可能會緩存其拓撲節點中的幾個樣本,如果他們想。

DD爲您同步提供數據,您只能訪問AcquireNextFrame和ReleaseFrame調用之間的紋理。

+0

我試圖不要讓太多問題陷入困境,但我在將它傳遞給MF之前先複製桌面紋理,方法是獲取桌面紋理描述符並在使用CopyResource之前使用該紋理創建新紋理。 但是,感謝lor的mftrace指針,會看看那個。 –

+0

我使用了mfctrace,並發現發送到水槽的樣本被報告爲0B大小,所以它們的創建出了問題。 –