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

问题描述 投票:3回答:1

我正在尝试实时流式传输通过桌面复制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帧。我想我缺少什么。

Here is the code review link表示铬的提交,其中包含有关此特定配置的讨论。阅读此讨论给了我一些希望,但还没有运气。

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");
}

任何帮助将不胜感激。

video-streaming directx h.264 ms-media-foundation mft
1个回答
0
投票

从Chromium提取的代码段就是这样做的方法:您必须使用ICodecAPI界面。

documented on MSDN

认证的硬件编码器

[...]

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

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

[...]

CODECAPI_AVEncMPVGOPSize

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

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

© www.soinside.com 2019 - 2024. All rights reserved.