关于opencv + H.264有很多问题,但是
他们都没有给出详细的解释。
我在视觉工作室中使用openh264(openh264-1.4.0-win32msvc.dll)以及opencv 3.1(启用了ffmpeg的cmake的自定义版本),我想将来自网络摄像头的视频保存为H.264压缩的mp4格式
在使用openh264之前,在控制台窗口中我看到一条警告消息
“无法加载openh264库:openh264-1.4.0-win32msvc.dll
请检查您的环境和/或从此处下载:
https://github.com/cisco/openh264/releases“
(视频也未保存)
所以我下载了dll并保存在我的程序文件(exe)的文件夹中
现在,当我运行程序时,我看到了不同的错误
“[OpenH264]此= 0x0DE312C0,警告:bEnabledFrameSkip = 0,如果不启用跳过帧就无法控制RC_QUALITY_MODE和RC_TIMESTAMP_MODE的比特率”
(现在保存了视频,但是大小非常高!比特率约为1200 Kbps)
对我来说,使用h264的唯一目的是减小文件大小。.我想我可能必须自己进行一些更改才能构建openh264以消除此错误,有人可以指导我如何做吗?还是告诉我是否有办法通过代码以某种方式降低比特率?
P.S:我尝试给-1而不是CV_FOURCC(),系统中显示“已安装的编解码器”窗口,即使我从here安装了各种编解码器包和h264,我也找不到h264或x264或h264vfw
感谢和问候
最佳答案
如果要控制比特率,则必须同时使用
encoderParemeters.iRCMode = RC_OFF_MODE;
encoderParemeters.bEnableFrameSkip = true;
在这里,我以示例显示所有Openh264编码参数:
long nReturnedValueFromEncoder = WelsCreateSVCEncoder(&m_pSVCVideoEncoder);
m_nVideoWidth = 352;
m_nVideoHeight = 288;
SEncParamExt encoderParemeters;
memset(&encoderParemeters, 0, sizeof(SEncParamExt));
m_pSVCVideoEncoder->GetDefaultParams(&encoderParemeters);
encoderParemeters.iUsageType = CAMERA_VIDEO_REAL_TIME;
encoderParemeters.iTemporalLayerNum = 0;
encoderParemeters.uiIntraPeriod = 15;
encoderParemeters.eSpsPpsIdStrategy = INCREASING_ID;
encoderParemeters.bEnableSSEI = false;
encoderParemeters.bEnableFrameCroppingFlag = true;
encoderParemeters.iLoopFilterDisableIdc = 0;
encoderParemeters.iLoopFilterAlphaC0Offset = 0;
encoderParemeters.iLoopFilterBetaOffset = 0;
encoderParemeters.iMultipleThreadIdc = 0;
encoderParemeters.iRCMode = RC_BITRATE_MODE;
encoderParemeters.iMinQp = 0;
encoderParemeters.iMaxQp = 52;
encoderParemeters.bEnableDenoise = false;
encoderParemeters.bEnableSceneChangeDetect = false;
encoderParemeters.bEnableBackgroundDetection = true;
encoderParemeters.bEnableAdaptiveQuant = false;
encoderParemeters.bEnableFrameSkip = true;
encoderParemeters.bEnableLongTermReference = true;
encoderParemeters.iLtrMarkPeriod = 20;
encoderParemeters.bPrefixNalAddingCtrl = false;
encoderParemeters.iSpatialLayerNum = 1;
SSpatialLayerConfig *spartialLayerConfiguration = &encoderParemeters.sSpatialLayers[0];
spartialLayerConfiguration->uiProfileIdc = PRO_BASELINE;//;
encoderParemeters.iPicWidth = spartialLayerConfiguration->iVideoWidth = m_nVideoWidth;
encoderParemeters.iPicHeight = spartialLayerConfiguration->iVideoHeight = m_nVideoHeight;
encoderParemeters.fMaxFrameRate = spartialLayerConfiguration->fFrameRate = (float)30;
encoderParemeters.iTargetBitrate = spartialLayerConfiguration->iSpatialBitrate = 500000;
encoderParemeters.iTargetBitrate = spartialLayerConfiguration->iMaxSpatialBitrate = 500000;
spartialLayerConfiguration->iDLayerQp = 24;
//spartialLayerConfiguration->sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
spartialLayerConfiguration->sSliceArgument.uiSliceMode = SM_SINGLE_SLICE;
nReturnedValueFromEncoder = m_pSVCVideoEncoder->InitializeExt(&encoderParemeters);
希望对您有帮助。