there are a lot of questions asked regarding opencv + H.264 but
none of them gave detailed explanation.
i am using openh264(openh264-1.4.0-win32msvc.dll) along with opencv 3.1(custom build with cmake having ffmpeg enabled) in visual studio, i wanted to save video coming from webcam in mp4 format with H.264 compression
VideoWriter write = VideoWriter("D:/movie.mp4", CV_FOURCC('H', '2', '6', '4'), 10.0, cv::Size(192, 144), true);
before using openh264, in console window i was seeing an warning message "Failed to load openh264 library : openh264-1.4.0-win32msvc.dll please check your environment and/or download from here: https://github.com/cisco/openh264/releases" (also video was not been saved)
so i downloaded the dll & kept in a folder with my program file(exe) now when i run the program, i'm seeing different error "[OpenH264] this = 0x0DE312C0, warning: bEnabledFrameSkip=0, bitrate can't be controlled for RC_QUALITY_MODE and RC_TIMESTAMP_MODE without enabling skip frame" (now video is saved, but size is very high! bit rate is around 1200 Kbps)
for me, the sole purpose of using h264 is to reduce the file size.. i think i may have to build openh264 myself with some changes to remove this error, can anyone guide me how? or tell me if there is a way to reduce bit rate somehow through code?
P.S: I tried giving -1 instead of CV_FOURCC(), 'installed codecs' window in my system showed up, i couldn't find h264 or x264 or h264vfw even though i have installed variety of codec packs & h264 from here
Thanks & regards
If you want to control bitrate, You have to use both
encoderParemeters.iRCMode = RC_OFF_MODE;
encoderParemeters.bEnableFrameSkip = true;
Here I am showing all the Openh264 Encoding parameters as an Example:
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);
Hope it will help you.