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



我正在尝试实时流式传输通过桌面复制 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属性,这些设置彼此不兼容吗?

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

这是 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接口。

如 MSDN 所述:

认证硬件编码器

[...]

以下是必需和可选ICodecAPI属性集 编码器通过 HCK 编码器认证。

以下 Windows 8 和 Windows 8.1 ICodecAPI属性是 必填:

[...]

CODECAPI_AVEncMPVGOPSize

因此,在大多数情况下,您将拥有该属性。

请注意,在开始实际流式处理之前,可能需要设置该属性。

最新更新