我正在尝试直播通过桌面复制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,"Failed to set GOPInSeq");
CHECK_HR(pMFTOutputMediaType->SetUINT32(MF_MT_MAX_KEYFRAME_SPACING,"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");
}
任何帮助将不胜感激。