openh264 - bEnableFrameSkip = 0,无法控制比特率

时间:2016-04-10 01:41:00

标签: c++ opencv codec opencv3.1 openh264

有很多关于opencv + H.264的问题,但是 他们都没有给出详细解释。

我在visual studio中使用openh264(openh264-1.4.0-win32msvc.dll)以及opencv 3.1(使用cmake启用了ffmpeg的自定义构建),我希望以mp4格式保存来自网络摄像头的视频,并使用H.264压缩

  

VideoWriter write = VideoWriter(" D:/movie.mp4" ;, CV_FOURCC(' H',' 2',   ' 6',' 4'),10.0,cv :: Size(192,144),true);

在使用openh264之前,在控制台窗口中我看到了一条警告消息 "无法加载openh264库:openh264-1.4.0-win32msvc.dll 请检查您的环境和/或从这里下载: https://github.com/cisco/openh264/releases" (还没有保存视频)

所以我下载了dll&保存在我的程序文件(exe)的文件夹中 现在当我运行程序时,我看到了不同的错误 " [OpenH264] this = 0x0DE312C0,警告:bEnabledFrameSkip = 0,不能在不启用跳帧的情况下控制RC_QUALITY_MODE和RC_TIMESTAMP_MODE的比特率" (现在视频已保存,但尺寸非常高!比特率约为1200 Kbps)

对我来说,使用h264的唯一目的是减少文件大小..我想我可能需要自己构建openh264并进行一些更改以消除此错误,任何人都可以指导我如何操作?或告诉我是否有办法通过代码以某种方式降低比特率?

P.S:我尝试给-1而不是CV_FOURCC(),'安装编解码器'我系统中的窗口出现了,即使我安装了各种编解码器包,我也找不到h264或x264或h264vfw。来自here的h264

谢谢&问候

2 个答案:

答案 0 :(得分:2)

如果你想控制比特率,你必须同时使用

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);

希望它会对你有所帮助。

答案 1 :(得分:1)

您可以使用RC_BITRATE_MODE简单地控制比特率,并在Openh264中启用bEnableFrameSkip。