在 MediaFoundation 硬件 MFT 中设置更大的 GOP 大小

Setting larger GOP size in MediaFoundation hardware MFT

我正在尝试直播通过桌面复制捕获的桌面 API。 H264 编码工作正常,除了桌面复制 API 仅在屏幕发生变化时才交付帧,但视频编码器希望帧以恒定帧速率交付。因此,当没有触发屏幕变化时,我不得不保存之前的样本以恒定速率馈送编码器。这行得通,我可以在另一端看到实时输出。

但有一个问题,编码器以恒定速率生成一个大样本,其大小等于新的全屏样本(可能是关键帧)的大小。我还注意到 I 帧(那个大样本)每 1 秒精确生成一次(我想,它可能是默认的 GOP 大小),即使没有屏幕变化并且我只提供我之前的样本除了我设置的采样时间外,它们之间几乎没有区别。这对于实时流来说成本很高,我不希望解码器能够在流中寻找或加入流(至少,我可以控制它),有没有办法解决这个问题设置更大的 GOP?

我尝试了以下所有设置,但似乎没有任何变化。

FPS: 30

CHECK_HR(pMFTOutputMediaType->SetUINT32(CODECAPI_AVEncMPVGOPSize, 1024), "Failed to set GOP size");
CHECK_HR(pMFTOutputMediaType->SetUINT32(CODECAPI_AVEncMPVGOPSInSeq, 1024), "Failed to set GOPInSeq");
CHECK_HR(pMFTOutputMediaType->SetUINT32(MF_MT_MAX_KEYFRAME_SPACING, 1024), "Failed to set keyframe spacing");

我也试过设置CODECAPI_AVEncCommonRealTime 属性,这些设置互相不兼容吗?

我也试过下面的代码(从 chromium https://github.com/chromium/chromium/blob/master/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc 复制)。关键帧计数仍然没有变化,它仍然每隔一秒生成一次 I 帧。我想我错过了什么。

Here is the code review link 用于包含他们关于此特定配置的讨论的 chromium 提交。阅读这个讨论给了我一些希望,但还没有运气。

void SetEncoderModes() {

    VARIANT var = { 0 };

    if (!mpCodecAPI) {
        CHECK_HR(_pTransform->QueryInterface(IID_PPV_ARGS(&mpCodecAPI)), "Failed to get codec api");
    }

    var.vt = VT_UI4;
    var.lVal = 1024;

    CHECK_HR(mpCodecAPI->SetValue(&CODECAPI_AVEncMPVGOPSize, &var), "Failed to set GOP size");
}

如有任何帮助,我们将不胜感激。

从 Chromium 中提取的代码片段是实现此目的的方法:您必须使用 ICodecAPI 界面。

作为documented on MSDN:

Certified Hardware Encoder

[...]

The following is the set of required and optional ICodecAPI properties for encoders to pass the HCK encoder certification.

The following Windows 8 and Windows 8.1 ICodecAPI properties are required:

[...]

CODECAPI_AVEncMPVGOPSize

所以在大多数情况下你会得到 属性。

请注意,您可能需要在开始实际流式传输之前设置 属性。