我试图通过桌面复制API捕获的桌面直播,H264编码工作正常,但是桌面复制API仅在屏幕更改时提供帧,而视频编码器期望按恒定的帧率提供帧。因此,我被迫保存先前的样本以便在没有屏幕更改触发时以恒定的速率向编码器馈送数据。这有效,我可以在另一端看到实时输出。
然而,有一个问题,编码器以恒定的速率生成等于全屏新样本大小的大样本(可能是关键帧)。我还注意到,即使没有屏幕更改,我只提供了先前创建的样本,并且它们之间几乎没有差异(除了我设置的样本时间),也会每隔1秒钟(我猜测可能是默认的GOP大小)产生一个I帧(即大样本)。这对于实时流而言是昂贵的,我不希望解码器能够在流中间寻找或加入流(至少我对此有控制),是否可以通过设置较大的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
属性,这两个设置是否不兼容?
我还尝试了以下代码(从Chromium https://github.com/chromium/chromium/blob/master/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc复制而来)。关键帧计数仍然没有变化,它仍然每秒生成一个I帧。我想我可能漏掉了一些东西。
这是代码审查链接,其中包含他们讨论此特定配置的讨论。阅读此讨论给了我一些希望,但仍未成功。
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");
}
非常感谢您的帮助。