5

我正在尝试使用 MediaFoundation API 对视频进行编码,但在将样本推送到 SinkWriter 时遇到问题。

我正在通过 Desktop Duplication API 获取要编码的帧。我最终得到的是一个带有桌面图像的 ID3D11Texture2D。

我正在尝试创建一个包含此表面的 IMFVideoSample,然后将该视频样本推送到 SinkWriter。

我尝试过以不同的方式解决这个问题:

  • 我调用MFCreateVideoSampleFromSurface(texture, &pSample)其中纹理为 ID3D11Texture2D,填写了 SampleTime 和 SampleDuration,然后将创建的样本传递给 SinkWriter。
    SinkWriter 返回 E_INVALIDARG。

  • 我尝试通过将 nullptr 作为第一个参数传递并自己使用 MFCreateDXGISurfaceBuffer 创建缓冲区来创建示例,然后将生成的缓冲区传递给示例。
    那也没有用。

  • 我通读了 MediaFoundation 文档,但找不到有关如何使用 DirectX 纹理创建样本的详细信息。

我没有东西可以尝试了。
有没有人以前使用过这个 API 并且可以想到我应该检查的东西,或者我可以如何去调试它?

4

1 回答 1

2

首先你应该学会使用mftrace工具。很可能,它会立即告诉您问题所在。

但我的猜测是,可能会出现以下问题。

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

  2. 可能 SinkWriter 需要一个可以在 CPU 上读取的纹理。为了解决这个问题,当一个框架可用时,创建一个相同格式 + 大小的暂存纹理,调用 CopyResource 将桌面复制到暂存纹理,然后将该暂存纹理传递给 MF。

  3. 即使您使用硬件编码器,CPU 也不会尝试读取纹理数据,我认为直接将桌面纹理传递给 MF 也不是一个好主意。

为样本设置 D3D 纹理时,不会在任何地方复制数据,样本仅保留纹理。

MF 异步工作,如果需要,它可以在其拓扑节点中缓冲多个样本。

DD 同步为您提供数据,您只能在 AcquireNextFrame 和 ReleaseFrame 调用之间访问纹理。

于 2016-07-25T21:17:40.093 回答