我正在尝试实时流式传输通过桌面复制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");
}
任何帮助将不胜感激。
从Chromium提取的代码段就是这样做的方法:您必须使用ICodecAPI
界面。
认证的硬件编码器
[...]
以下是一组必需和可选的
ICodecAPI
属性使编码器通过HCK编码器认证。以下Windows 8和Windows 8.1
ICodecAPI
属性是必填:[...]
CODECAPI_AVEncMPVGOPSize
因此,在大多数情况下,您将拥有该物业。
请注意,您可能需要在开始实际流式传输之前设置属性。