- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
问题陈述:
英特尔硬件MFT不遵守GOP设置,导致实时应用程序占用更多带宽。相同的代码可以在Nvidia硬件MFT上正常工作。
背景:
我正在尝试使用Windows10计算机上的MediaFoundation H264硬件编码器将通过DesktopDuplication API捕获的NV12样本编码为视频流,并通过LAN进行实时流处理和渲染。
最初,我在编码器处面临太多缓冲,因为编码器在提供输出样本之前最多缓冲25帧(GOP大小)。经过一些研究,我发现设置CODECAPI_AVLowLatencyMode可以减少延迟,但要花一些质量和带宽。
设置CODECAPI_AVLowLatencyMode属性有点改善了性能,但没有达到实时要求。现在看来,编码器至少在生成样本之前仍至少缓冲15帧(在输出中引入大约2秒钟的延迟)。并且仅当配置了低帧速率时,此行为才是明显的。在60FPS时,输出几乎是实时的,没有视觉上明显的延迟。
实际上,只有当帧频设置为低于30FPS时,人眼才能看到缓冲。并且,延迟与FPS配置成反比增加,在25FPS时,延迟在几百毫秒内,而当FPS配置为10(恒定速率)时,延迟增加到3秒。我猜想,将FPS设置为大于30(说60FPS)实际上会导致编码器缓冲区足够快地溢出,以产生明显延迟的采样。
最近,我也尝试使用CODECAPI_AVEncCommonRealTime属性(https://docs.microsoft.com/en-us/windows/win32/directshow/avenccommonrealtime-property)来检查它在降低输入帧频以避免带宽消耗时是否提高了性能,但是该调用失败,并出现“ parametercorrect”错误。
我的实验:
为了保持恒定的帧速率,并迫使编码器产生实时输出,我将相同的样本(以前保存的样本)馈送到
编码器以30FPS / 60FPS的恒定速率传输。我正在这样做
最多只能捕获10FPS(或任何所需的FPS)并伪造30 / 60FPS
通过三次或完全按照
以EMULATED_FRAME_RATE / ACTUAL_FRAME_RATE的比率(例如:30 / 10、60 / 15、60 / 20)精确地以恒定间隔填充空白。例如,当10秒钟没有变化时,我将给编码器提供30 * 10倍(30FPS)的相同样本。我从一些开源Github项目中了解了这种方法,也从Chrome的实验代码示例中学到了这种方法,还被告知(Primarily on SO,以及在其他论坛上),这是推动编码器实现实时输出的唯一方法,因此没办法解决。
上述方法产生近乎实时的输出,但消耗的数据却比我预期的要多,即使我仅将先前保存的样本馈送到编码器。
无论屏幕内容在30FPS还是0FPS(空闲)下变化,Intel MFT上的输出比特率似乎始终保持在350KBps至500KBps之间,而NVidia MFT(具有30FPS和500KB比特率配置)上的输出比特率则介于80KBps至400KBps之间。在这种情况下,NVidia硬件编码器似乎要好一些。
实际上,在屏幕空闲期间,编码器每秒产生的数据量比上述速率要多。我已经能够通过setting a larger GOP size减少NVidia设备上的数据消耗(当前配置的GOP大小为16K)。但是,在英特尔图形620硬件上,屏幕空闲时间数据消耗保持在300KBps左右,而在NVidia GTX 1070(配置:500KB比特率和30FPS)上,屏幕空闲时间数据消耗保持在50KBps至80KBps。我猜想,英特尔硬件MFT根本不遵守GOP设置,或者改进并不明显。
通过设置非常低的比特率,我还能够分别将Intel和Nvidia硬件上的空闲时间数据消耗降低到〜130KBps和〜40KBps,但这仍然是不可接受的,这也会使视频质量下降。
当输入采样之间没有变化时,是否可以将编码器配置为产生小于约10KBps的输出?当没有任何变化但〜10KBps还是可以接受的时候,我实际上的目标是〜0KB输出。
更新:
我可以通过以下方式减少NVidia MFT上的空闲时间数据消耗
调整一些参数,以400KB比特率配置将其调整为〜20KBps以下,以100KB比特率将其调整为〜10KBps以下
组态。这令人信服。但是,具有相同编码器配置的相同代码在Intel机器上产生的数据量将增加20至40倍。英特尔(英特尔图形620)肯定不遵守GOP设置。我什至尝试将GOP从256更改为INT_MAX,英特尔硬件MFT的输出似乎没有变化。
更新2:
在试用了编码器属性之后(我仅使用eAVEncCommonRateControlMode_UnconstrainedVBR而不是eAVEncCommonRateControlMode_CBR配置了CODECAPI_AVEncCommonRateControlMode),现在我可以看到Intel MFT在屏幕空闲时间内产生了3KBps的数据,但是仅在最初的几秒钟(大约3至8秒)内产生了数据。 ,然后回到同一故事。我猜想在几秒钟后,编码器将丢失对关键帧的参考,无法将其与样本进行比较,并且在那一点之后似乎无法恢复。无论GOP是16/128/256/512/1024还是INT_MAX,其行为都是相同的。
编码器配置:
参考:http://alax.info/blog/1586
const int EMULATED_FRAME_RATE = 30;//
const int TARGET_FPS = 10;
const int FPS_DENOMINATOR = 1;
const unsigned long long time_between_capture = 1000 / TARGET_FPS;
const unsigned long long nEmulatedWaitTime = 1000 / EMULATED_FRAME_RATE;
const unsigned long long TARGET_AVERAGE_BIT_RATE = 4000000; // Adjusting this affects the quality of the H264 bit stream.
const LONGLONG VIDEO_FRAME_DURATION = 10ll * 1000ll * 1000ll / ((long long)EMULATED_FRAME_RATE); // frame duration in 100ns units
const UINT32 KEY_FRAME_SPACING = 16384;
const UINT32 GOP_SIZE = 16384;
const UINT32 BPICTURECOUNT = 2;
VARIANT var = { 0 };
//no failure on both Nvidia & Intel, but Intel seems to be not behaving as expected
var.vt = VT_UI4;
var.lVal = GOP_SIZE;
CHECK_HR(mpCodecAPI->SetValue(&CODECAPI_AVEncMPVGOPSize, &var), "Failed to set GOP size");
var.vt = VT_BOOL;
var.ulVal = VARIANT_TRUE;
// fails with "parameter incorrect" error.
CHECK_HR(mpCodecAPI->SetValue(&CODECAPI_AVEncCommonRealTime, &var), "Failed to set realtime mode");
var = { 0 };
var.vt = VT_BOOL;
var.ulVal = VARIANT_TRUE;
CHECK_HR(mpCodecAPI->SetValue(&CODECAPI_AVLowLatencyMode, &var), "Failed to set low latency mode");
var = { 0 };
var.vt = VT_BOOL;
var.ulVal = VARIANT_TRUE;
CHECK_HR(mpCodecAPI->SetValue(&CODECAPI_AVEncCommonLowLatency, &var), "Failed to set low latency mode");
var = { 0 };
var.vt = VT_UI4;
var.lVal = 2; // setting B-picture count to 0 to avoid latency and buffering at both encoder and decoder
CHECK_HR(mpCodecAPI->SetValue(&CODECAPI_AVEncMPVDefaultBPictureCount, &var), "Failed to set B-Picture count");
var = { 0 };
var.vt = VT_UI4;
var.lVal = 100; //0 - 100 (100 for best quality, 0 for low delay)
CHECK_HR(mpCodecAPI->SetValue(&CODECAPI_AVEncCommonQualityVsSpeed, &var), "Failed to set Quality-speed ratio");
var = { 0 };
var.vt = VT_UI4;
var.lVal = 20;
CHECK_HR(mpCodecAPI->SetValue(&CODECAPI_AVEncCommonQuality, &var), "Failed to set picture quality");
var = { 0 };
var.vt = VT_UI4;
var.lVal = eAVEncCommonRateControlMode_CBR; // This too fails on some hardware
CHECK_HR(mpCodecAPI->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var), "Failed to set rate control");
var = { 0 };
var.vt = VT_UI4;
var.lVal = 4000000;
CHECK_HR(mpCodecAPI->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var), "Failed to set Adaptive mode");
var = { 0 };
var.vt = VT_UI4;
var.lVal = eAVEncAdaptiveMode_FrameRate;
CHECK_HR(mpCodecAPI->SetValue(&CODECAPI_AVEncAdaptiveMode, &var), "Failed to set Adaptive mode");
VARIANT ValueMin = { 0 };
VARIANT ValueMax = { 0 };
VARIANT SteppingDelt = { 0 };
HRESULT hr = S_OK;
if (!mpCodecAPI) {
CHECK_HR(_pTransform->QueryInterface(IID_PPV_ARGS(&mpCodecAPI)), "Failed to get codec api");
}
hr = mpCodecAPI->GetParameterRange(&CODECAPI_AVEncMPVGOPSize, &ValueMin, &ValueMax, &SteppingDelt);
CHECK_HR(hr, "Failed to get GOP range");
VariantClear(&ValueMin);
VariantClear(&ValueMax);
VariantClear(&SteppingDelt);
最佳答案
发生了一些奇迹。在同时使用编码器配置的同时,我不小心将主显示器更改为机器上的另一台显示器,现在问题已解决。切换回先前选择的主监视器会导致相同的问题。我怀疑d3ddevice会造成麻烦。我不确定为什么仅在该设备/显示器上会发生这种情况,因此必须进行更多实验。
注意:由于我尚未找出仅在该monitor / d3d设备上发生问题的原因,因此我未将其标记为答案。只是将其发布为可能遇到类似情况的其他人的参考。一旦能够找到特定d3d11device实例上异常行为的原因,我将更新答案。
这就是我创建d3ddevice的方式,并将其重复用于桌面复制图像捕获器,视频处理器以进行颜色转换以及通过MFT_MESSAGE_SET_D3D_MANAGER属性进行硬件转换。
选项:
const D3D_DRIVER_TYPE m_DriverTypes[] = {
//Hardware based Rasterizer
D3D_DRIVER_TYPE_HARDWARE,
//High performance Software Rasterizer
D3D_DRIVER_TYPE_WARP,
//Software Rasterizer (Low performance but more accurate)
D3D_DRIVER_TYPE_REFERENCE,
//TODO: Explore other driver types
};
const D3D_FEATURE_LEVEL m_FeatureLevel[] = {
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1
//TODO: Explore other features levels as well
};
int m_DriversCount = ARRAYSIZE(m_DriverTypes);
int m_FeatureLevelsCount = ARRAYSIZE(m_FeatureLevel);
DWORD errorCode = ERROR_SUCCESS;
if (m_FnD3D11CreateDevice == NULL)
{
errorCode = loadD3D11FunctionsFromDll();
}
if (m_Id3d11Device)
{
m_Id3d11Device = NULL;
m_Id3d11DeviceContext = NULL;
}
UINT uiD3D11CreateFlag = (0 * D3D11_CREATE_DEVICE_SINGLETHREADED) | D3D11_CREATE_DEVICE_VIDEO_SUPPORT;
if (errorCode == ERROR_SUCCESS)
{
if (m_FnD3D11CreateDevice) {
for (UINT driverTypeIndex = 0; driverTypeIndex < m_DriversCount; ++driverTypeIndex)
{
m_LastErrorCode = D3D11CreateDevice(nullptr, m_DriverTypes[driverTypeIndex], nullptr, uiD3D11CreateFlag,
m_FeatureLevel, m_FeatureLevelsCount, D3D11_SDK_VERSION, &m_Id3d11Device, &m_SelectedFeatureLevel, &m_Id3d11DeviceContext);
if (SUCCEEDED(m_LastErrorCode))
{
break;
}
}
}
}
关于video-streaming - 英特尔H264硬件MFT不支持GOP设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59051443/
你能解释一下两者之间的区别吗 和 ? 最佳答案 通过使用 .您可以添加多个源元素。多个源元素可以链接到不同的视频文件。浏览器将使用第一个识别的格式。
我正在使用 ImagePickerController 处理 iPhone 视频捕获。我已经设置了图像选择器 Controller 的属性。我用它来将视频的最大长度设置为 60 秒。 imagePic
我正在制作一个进行基本视频处理的应用程序。我成功地合并到视频(视频上的视频)。 如何将左上角的小视频裁剪成一个圆圈? 最佳答案 如果您想导出该视频,您需要: 创建 CALayer,它将成为您的视频层的
我正在使用 SVT-AV1 和 FFMPEG 将视频编码为 AV1 视频和 opus 音频编解码器(.webm),它工作正常,除了视频搜索不起作用(非常糟糕)。当我寻找时,CPU 使用率会上升,并且需
在 Adobe Muse 中使用 VIDEO.JS 目前我已将海报图像配置为在视频开头显示, 当视频结束时,我希望海报图像重新出现。谢谢你的帮助! 最佳答案 将来最好的方法是通过 css。我只是a
我目前正在尝试从单张图片 (1980*1024) 生成视频 这是我的命令: ffmpeg -threads 8 -r 1 -loop 1 -i "C:\Library\Titling\__Resour
我想从 HTML 获取框架 javascript 中的组件,以便我可以处理它们然后输出到 Canvas 最佳答案 看看这个代码笔:Demo var videoId = 'video'; va
我已经使用 video.js 一段时间了,正在寻找响应式解决方案。我看到 4.6 声称是这样,但无法开始工作。我在文档中找不到任何关于使其响应的内容。我基本上只需要它保持在容器的 100% 并保持其纵
我正在寻找任何用于设置视频流服务器的现代资源。最好是开源解决方案。 我对此的搜索导致了很多死胡同。我也确实需要构建自己的服务而不是支付服务费用。 最佳答案 要设置您自己的视频流服务器,您应该从以下组件
如何在处理流媒体或网络视频时拦截“无法播放视频”对话框? 我尝试了以下操作并能够显示我的自定义错误消息。但最重要的是,我仍然收到 Android MediaPlayer 错误对话框“无法播放视频”。
它使我的视频居中并将控件放置在 div 底部但视频流出。在 css 样式表中,css 似乎无法识别。样式表中的 cos 颜色为黑色。我使用 Chrome 。 div.video_div{ width:
在 HTML5 video 元素中,您定义 type 属性的值始终以 video 开头。从元素是视频不是已经很明显,它是视频类型吗?为什么需要这样的视频:type="video/mp4",不应该只是t
我想通过 jQuery 或 Javascript 检测 html5 标签内的特定视频何时已完全加载(我的意思是,下载到浏览器的缓存中)。视频具有 preload = "auto"属性。 我尽我所能做到
HTML5 带来或将带来和 标签等等。自从我听说了他们,读了之后更是如此Why do we have an img element?特别是Jay C. Weber's message back fro
我正在制定一个 Web 应用程序的详细信息,该应用程序涉及顺序加载一长串(非常短的)视频剪辑,一个接一个,用户偶尔会输入建立新的视频剪辑加载方向. 我希望能够让浏览器一次预加载五个视频剪辑。然而,我们
我想知道 HTML5 标签现在支持.avi 格式视频文件的播放。 最佳答案 简短回答:否。改用 WebM 或 Ogg。 This article几乎涵盖了您需要了解的有关 的所有信息元素,包括哪些浏
尽管它似乎处于某种危险之中,但开放视频标准是一个好主意。我看到了一些关于运动跟踪的演示——只是概念验证,但仍然很有趣。现在,我要说的是,如果可以访问用户的网络摄像头,像这样的概念真的会是一个收获……想
我正在尝试使用 php-facebook-sdk 并借助 curl Facebook API 创建广告。 我已经使用 curl 上传了我的视频,它返回了一个 ID。现在,该视频 ID 将用于添加广告,
我正在使用 Video.js在我的网站上显示视频的插件。 我想删除画中画图标。我已经尝试了几个小时,但没有成功。 我做错了什么? 最佳答案 它应该是 data-setup='{"cont
使用 MediaRecorder 从 SurfaceView 录制视频 录音机 recorderProfile = CamcorderProfile.get( CamcorderProfile.QUA
我是一名优秀的程序员,十分优秀!