【发布时间】:2016-11-29 07:03:12
【问题描述】:
我正在尝试使用 MediaFoundation API 对视频进行编码,但在将样本推送到 SinkWriter 时遇到问题。
我正在通过桌面复制 API 获取要编码的帧。我最终得到的是一个 ID3D11Texture2D,其中包含桌面图像。
我正在尝试创建一个包含此表面的 IMFVideoSample,然后将该视频样本推送到 SinkWriter。
我尝试过以不同的方式解决这个问题:
我调用了
MFCreateVideoSampleFromSurface(texture, &pSample),其中纹理是 ID3D11Texture2D,填充了 SampleTime 和 SampleDuration,然后将创建的样本传递给 SinkWriter。
SinkWriter 返回 E_INVALIDARG。我尝试通过将 nullptr 作为第一个参数传递并自己使用 MFCreateDXGISurfaceBuffer 创建缓冲区来创建示例,然后将生成的缓冲区传递给示例。
那也没用。我通读了 MediaFoundation 文档,但找不到有关如何使用 DirectX 纹理创建示例的详细信息。
我没有东西可以尝试了。
有没有人以前使用过这个 API 并且可以想到我应该检查的东西,或者我可以如何去调试它?
【问题讨论】:
-
我认为您在使用
MFCreateVideoSampleFromSurface和MFCreateDXGISurfaceBuffer时犯了一个错误。这些函数创建用于写入 DirectX 表面和可视化的缓冲区,它们创建具有接口IMF2DBuffer的对象,但编码器和编写器需要具有IMFMediaBuffer的对象。他们无法理解IMF2DBuffer。尝试使用函数 'MFCreateSampleCopierMFT' - 它创建了 MFT 对象,用于在 MSDN 上从IMFMediaBuffer复制到IMF2DBuffer。也许它可以做反向工作!?! -
你确定吗?查看
MFCreateDXGISurfaceBuffer的文档,它声明它返回一个指向 IMFMediaBuffer 的指针。 -
从 DXGI 表面支持的样本/缓冲区中获取数据的最佳方法似乎是 MFGetService。另一个线程表明这两个 API 应该能够处理这个任务:stackoverflow.com/questions/14527718/…。我无法在任何地方找到任何体面的例子来充分利用这两种方法。我们将尝试朝着另一个方向前进,这是一种耻辱,因为 DesktopDuplication + MediaFoundation 似乎是解决我们问题的最佳解决方案。
-
您使用 DesktopDuplication + MediaFoundation 的想法很有趣。在“CaptureProject”站点上的项目 CaptureManager SDK 中,我使用 DirectX9 + MediaFoundation 来捕获实时屏幕视频,但它从桌面管理器复制图像(在任务管理器程序和桌面管理器中,彼此占 15%)。我认为使用 DesktopDuplication 会更有效率。
-
@Tiago Magalhães 你找到解决问题的方法了吗?我也被它困住了,因为我找不到相关的资源。
标签: c++ directx-11 ms-media-foundation dxgi