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

Video streaming 在MediaFoundation硬件MFT中设置更大的GOP大小,video-streaming,directx,h.264,ms-media-foundation,Video Streaming,Directx,H.264,Ms Media Foundation,我正在尝试对通过桌面复制API捕获的桌面进行实时流传输。H264编码工作正常,除了桌面复制API仅在屏幕发生变化时才发送帧,但视频编码器希望以恒定的帧速率发送帧。因此,当没有触发屏幕更改时,我被迫保存上一个样本,以恒定速率向编码器提供数据。这是可行的,我可以在另一端看到实时输出 但有一个问题是,编码器以恒定速率生成的大样本等于新的全屏样本(可能是关键帧)的大小。我还注意到,即使屏幕没有变化,我只提供我之前创建的样本,并且除了设置的样本时间外,它们之间几乎没有差异,I帧(大样本)也会精确地每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\u AVEncCommonRealTime属性,这些设置是否相互不兼容

我还尝试了下面的代码(从chromium复制)。关键帧计数仍然没有变化,它仍然每秒钟生成一次I帧。我想我错过了什么

对于chromium中的commit,其中包含他们关于此特定配置的讨论。阅读这篇讨论给了我一些希望,但还没有运气

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
接口

作为:

认证硬件编码器 [……]

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

以下Windows 8和Windows 8.1
ICodecAPI
属性为 所需:

[……]

CODECAPI\u AVEncMPVGOPSize

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


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

我认为您可以尝试不同的编码器比特率值。更改比特率可能不起作用。如果降低比特率,它仍将以恒定速率产生相同数量的I帧,从而产生较低质量的视频输出,这是不可取的。我也尝试了chromium()中的此代码,但似乎没有任何变化。这是有效的。在SetOutputType之前设置此属性似乎很重要。我是用另一种方式做的,假设它可以工作,因为我只是在调用后才启动编码器。看起来英特尔编码器不遵守此设置。在Nvidia上运行良好。我没能在英特尔机器上测试它。它可以在Nvidia设备上完美运行。我错误地认为它在所有硬件上的行为都是一样的。我已经做了很多实验,但无法找出原因。我假设它通常有效,但值16384可能超出范围。我也尝试设置256,但英特尔硬件上似乎没有任何变化。在chromium项目中,他们实际上已将其配置为INT32_MAX。即使设置INT32_MAX在Nvidia机器上也可以正常工作。