shithub: openh264

Download patch

ref: 2ab706a24e1fb002bbd039d8a94e224a11b347f8
parent: 501c77f66b73f207c7b0776aba8991b06861cc78
parent: d98ba6137cc68ac74d49e1aaf065406a939b2d2f
author: sijchen <[email protected]>
date: Tue Apr 8 10:22:08 EDT 2014

Merge pull request #638 from volvet/refine_enc_para

remove RC enable flag,  use RC Mode to indicate RC on or off

--- a/codec/api/svc/codec_app_def.h
+++ b/codec/api/svc/codec_app_def.h
@@ -174,9 +174,10 @@
 } SliceModeEnum;
 
 typedef enum {
-  RC_QUALITY_MODE,      //Quality mode
-  RC_BITRATE_MODE,   //Bitrate mode
-  RC_LOW_BW_MODE, //bitrate limited mode
+  RC_QUALITY_MODE = 0,      //Quality mode
+  RC_BITRATE_MODE = 1,   //Bitrate mode
+  RC_LOW_BW_MODE = 2, //bitrate limited mode
+  RC_OFF_MODE = -1,    // rate control off mode
 } RC_MODES;
 
 typedef enum {
@@ -237,7 +238,9 @@
   CAMERA_VIDEO_REAL_TIME, //camera video signal
   SCREEN_CONTENT_REAL_TIME,//screen content signal
 }EUsageType;
-/* SVC Encoding Parameters */
+
+// TODO:  Refine the parameters definition.
+// SVC Encoding Parameters
 typedef struct TagEncParamBase{
   EUsageType    iUsageType;	//application type;// CAMERA_VIDEO_REAL_TIME: //camera video signal; SCREEN_CONTENT_REAL_TIME: screen content signal;
   int		iInputCsp;	// color space of input sequence
@@ -276,7 +279,6 @@
   int      iEntropyCodingModeFlag;
 
   /* rc control */
-  bool    bEnableRc;
   bool    bEnableFrameSkip; // allow skipping frames to keep the bitrate within limits
   int     iMaxBitrate;        // max bitrate desired
   int     iMaxQp;
--- a/codec/console/enc/src/welsenc.cpp
+++ b/codec/console/enc/src/welsenc.cpp
@@ -111,7 +111,7 @@
   }
 
   SSpatialLayerConfig* pDLayer = &pSvcParam.sSpatialLayers[iLayer];
-  int iLeftTargetBitrate = (pSvcParam.bEnableRc)?pSvcParam.iTargetBitrate:0;
+  int iLeftTargetBitrate = (pSvcParam.iRCMode!=RC_OFF_MODE)?pSvcParam.iTargetBitrate:0;
   SLayerPEncCtx sLayerCtx;
   memset (&sLayerCtx, 0, sizeof (SLayerPEncCtx));
 
@@ -146,7 +146,7 @@
         //					pDLayer->frext_mode	= (bool)atoi(strTag[1].c_str());
       } else if (strTag[0].compare ("SpatialBitrate") == 0) {
         pDLayer->iSpatialBitrate	= 1000 * atoi (strTag[1].c_str());
-        if (pSvcParam.bEnableRc) {
+        if (pSvcParam.iRCMode!=RC_OFF_MODE) {
           if (pDLayer->iSpatialBitrate <= 0) {
             fprintf (stderr, "Invalid spatial bitrate(%d) in dependency layer #%d.\n", pDLayer->iSpatialBitrate, iLayer);
             return -1;
@@ -248,13 +248,11 @@
           pSvcParam.iMultipleThreadIdc = 0;
         else if (pSvcParam.iMultipleThreadIdc > MAX_THREADS_NUM)
           pSvcParam.iMultipleThreadIdc = MAX_THREADS_NUM;
-      } else if (strTag[0].compare ("EnableRC") == 0) {
-        pSvcParam.bEnableRc	= atoi (strTag[1].c_str()) ? true : false;
       } else if (strTag[0].compare ("RCMode") == 0) {
         pSvcParam.iRCMode	= (RC_MODES) atoi (strTag[1].c_str());
       } else if (strTag[0].compare ("TargetBitrate") == 0) {
         pSvcParam.iTargetBitrate	= 1000 * atoi (strTag[1].c_str());
-        if (pSvcParam.bEnableRc && pSvcParam.iTargetBitrate <= 0) {
+        if ((pSvcParam.iRCMode!=RC_OFF_MODE) && pSvcParam.iTargetBitrate <= 0) {
           fprintf (stderr, "Invalid target bitrate setting due to RC enabled. Check TargetBitrate field please!\n");
           return 1;
         }
@@ -394,7 +392,7 @@
   printf ("  -bgd    Control background detection (default: 0)\n");
   printf ("  -aq     Control adaptive quantization (default: 0)\n");
   printf ("  -ltr    Control long term reference (default: 0)\n");
-  printf ("  -rc	  Control rate control: 0-disable; 1-enable \n");
+  printf ("  -rc	  rate control mode: 0-quality mode; 1-bitrate mode; 2-bitrate limited mode; -1-rc off \n");
   printf ("  -tarb	  Overall target bitrate\n");
   printf ("  -numl   Number Of Layers: Must exist with layer_cfg file and the number of input layer_cfg file must equal to the value set by this command\n");
   printf ("  The options below are layer-based: (need to be set with layer id)\n");
@@ -466,7 +464,7 @@
       pSvcParam.iLtrMarkPeriod = atoi (argv[n++]);
 
     else if (!strcmp (pCommand, "-rc") && (n < argc))
-      pSvcParam.bEnableRc = atoi (argv[n++]) ? true : false;
+      pSvcParam.iRCMode = static_cast<RC_MODES>(atoi(argv[n++]));
 
     else if (!strcmp (pCommand, "-trace") && (n < argc))
       g_LevelSetting = atoi (argv[n++]);
--- a/codec/encoder/core/inc/param_svc.h
+++ b/codec/encoder/core/inc/param_svc.h
@@ -131,12 +131,12 @@
 
 
  public:
-TagWelsSvcCodingParam (const bool kbEnableRc = true) {
-  FillDefault (kbEnableRc);
+TagWelsSvcCodingParam () {
+  FillDefault ();
 }
 ~TagWelsSvcCodingParam()	{}
 
-static void FillDefault (SEncParamExt& param, const bool kbEnableRc) {
+static void FillDefault (SEncParamExt& param) {
   memset(&param, 0, sizeof(param));
   param.uiIntraPeriod		= 0;			// intra period (multiple of GOP size as desired)
   param.iNumRefFrame		= MIN_REF_PIC_COUNT;	// number of reference frame used
@@ -165,7 +165,6 @@
   param.iLoopFilterBetaOffset		= 0;	// BetaOffset:	valid range [-6, 6], default 0
  
   /* Rate Control */
-  param.bEnableRc		= kbEnableRc;
   param.iRCMode			= RC_QUALITY_MODE;
   param.iPaddingFlag	= 0;
 
@@ -200,8 +199,8 @@
   }
 }
 
-void FillDefault (const bool kbEnableRc) {
-  FillDefault(*this, kbEnableRc);
+void FillDefault () {
+  FillDefault(*this);
   uiGopSize			= 1;			// GOP size (at maximal frame rate: 16)
 
   SUsedPicRect.iLeft	=
@@ -234,7 +233,7 @@
 
 }
 
-int32_t ParamBaseTranscode (const SEncParamBase& pCodingParam, const bool kbEnableRc = true) {
+int32_t ParamBaseTranscode (const SEncParamBase& pCodingParam) {
 
   iInputCsp		= pCodingParam.iInputCsp;		// color space of input sequence
   fMaxFrameRate		= WELS_CLIP3 (pCodingParam.fMaxFrameRate, MIN_FRAME_RATE, MAX_FRAME_RATE);
@@ -248,7 +247,6 @@
   SUsedPicRect.iWidth = ((iPicWidth >> 1) << 1);
   SUsedPicRect.iHeight = ((iPicHeight >> 1) << 1);
 
-  bEnableRc			= kbEnableRc;
   iRCMode = pCodingParam.iRCMode;    // rc mode
 
   int8_t iIdxSpatial	= 0;
@@ -320,7 +318,6 @@
   bEnableFrameCroppingFlag	= true;
 
   /* Rate Control */
-  bEnableRc			= pCodingParam.bEnableRc;
   iRCMode = pCodingParam.iRCMode;    // rc mode
   iPaddingFlag = pCodingParam.iPaddingFlag;
 
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -231,7 +231,7 @@
         fDlp->sSliceCfg.uiSliceMode	= SM_SINGLE_SLICE;
         break;
       }
-      if (pCodingParam->bEnableRc) {	// multiple slices verify with gom
+      if (pCodingParam->iRCMode != RC_OFF_MODE) {	// multiple slices verify with gom
         //check uiSliceNum
         GomValidCheckSliceNum (iMbWidth, iMbHeight, &fDlp->sSliceCfg.sSliceArgument.uiSliceNum);
         assert (fDlp->sSliceCfg.sSliceArgument.uiSliceNum > 1);
@@ -285,7 +285,7 @@
         fDlp->sSliceCfg.uiSliceMode	= SM_SINGLE_SLICE;
         break;
       }
-      if (pCodingParam->bEnableRc && fDlp->sSliceCfg.sSliceArgument.uiSliceNum > 1) {
+      if ((pCodingParam->iRCMode!=RC_OFF_MODE) && fDlp->sSliceCfg.sSliceArgument.uiSliceNum > 1) {
         WelsLog (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), WARNING: GOM based RC do not support SM_RASTER_SLICE!\n");
       }
       // considering the coding efficient and performance, iCountMbNum constraint by MIN_NUM_MB_PER_SLICE condition of multi-pSlice mode settting
@@ -853,7 +853,7 @@
     // Need port pSps/pPps initialization due to spatial scalability changed
     if (!bUseSubsetSps) {
       WelsInitSps (pSps, pDlayerParam, pParam->uiIntraPeriod, pParam->iNumRefFrame, iSpsId,
-                   pParam->bEnableFrameCroppingFlag, pParam->bEnableRc);
+                   pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE);
 
       if (iDlayerCount > 1) {
         pSps->bConstraintSet0Flag = true;
@@ -862,7 +862,7 @@
       }
     } else {
       WelsInitSubsetSps (pSubsetSps, pDlayerParam, pParam->uiIntraPeriod, pParam->iNumRefFrame, iSpsId,
-                         pParam->bEnableFrameCroppingFlag, pParam->bEnableRc);
+                         pParam->bEnableFrameCroppingFlag, pParam->iRCMode!=RC_OFF_MODE);
     }
 
     // initialize pPps
@@ -1674,7 +1674,7 @@
       if (iSliceNum > iMaxSliceCount)
         iMaxSliceCount = iSliceNum;
       // need perform check due uiSliceNum might change, although has been initialized somewhere outside
-      if (pCodingParam->bEnableRc) {
+      if (pCodingParam->iRCMode!=RC_OFF_MODE) {
         GomValidCheckSliceMbNum (kiMbWidth, kiMbHeight, pSlcArg);
       } else {
         CheckFixedSliceNumMultiSliceSetting (kiMbNumInFrame, pSlcArg);
@@ -1705,7 +1705,7 @@
         pDlp->sSliceCfg.uiSliceMode	= SM_SINGLE_SLICE;
         break;
       }
-      if (pCodingParam->bEnableRc) {	// multiple slices verify with gom
+      if (pCodingParam->iRCMode != RC_OFF_MODE) {	// multiple slices verify with gom
         //check uiSliceNum
         GomValidCheckSliceNum (kiMbWidth, kiMbHeight, &pDlp->sSliceCfg.sSliceArgument.uiSliceNum);
         assert (pDlp->sSliceCfg.sSliceArgument.uiSliceNum > 1);
@@ -1922,7 +1922,7 @@
   if (pCodingParam->iMultipleThreadIdc > 1)
     iRet = CreateSliceThreads (pCtx);
 
-  WelsRcInitModule (pCtx,  pCtx->pSvcParam->bEnableRc ? WELS_RC_GOM : WELS_RC_DISABLE);
+  WelsRcInitModule (pCtx,  pCtx->pSvcParam->iRCMode!=RC_OFF_MODE ? WELS_RC_GOM : WELS_RC_DISABLE);
 
   pCtx->pVpp = new CWelsPreProcess (pCtx);
   if (pCtx->pVpp == NULL) {
@@ -2194,7 +2194,7 @@
     uint8_t		iCurDid = pCtx->uiDependencyId;
     uint32_t	uiFrmByte = 0;
 
-    if (pCtx->pSvcParam->bEnableRc) {
+    if (pCtx->pSvcParam->iRCMode != RC_OFF_MODE) {
       //RC case
       uiFrmByte = (
                     ((uint32_t) (pCtx->pSvcParam->sDependencyLayers[iCurDid].iSpatialBitrate)
@@ -3475,7 +3475,6 @@
     pOldParam->iLoopFilterBetaOffset		= pNewParam->iLoopFilterBetaOffset;	// BetaOffset:	valid range [-6, 6], default 0
    
     /* Rate Control */
-    pOldParam->bEnableRc			= pNewParam->bEnableRc;
     pOldParam->iRCMode	    	= pNewParam->iRCMode;
     pOldParam->iTargetBitrate	= pNewParam->iTargetBitrate;			// overall target bitrate introduced in RC module
     pOldParam->iPaddingFlag	    = pNewParam->iPaddingFlag;
--- a/codec/encoder/core/src/slice_multi_threading.cpp
+++ b/codec/encoder/core/src/slice_multi_threading.cpp
@@ -205,7 +205,7 @@
 
   int32_t iNumMbInEachGom = 0;
   SWelsSvcRc* pWelsSvcRc = &pCtx->pWelsSvcRc[iCurDid];
-  if (pCtx->pSvcParam->bEnableRc) {
+  if (pCtx->pSvcParam->iRCMode != RC_OFF_MODE) {
     iNumMbInEachGom = pWelsSvcRc->iNumberMbGom;
 
     if (iNumMbInEachGom <= 0) {
@@ -237,7 +237,7 @@
     int32_t iNumMbAssigning = (int32_t) (kiCountNumMb * pSliceComplexRatio[iSliceIdx] + EPSN);
 
     // GOM boundary aligned
-    if (pCtx->pSvcParam->bEnableRc) {
+    if (pCtx->pSvcParam->iRCMode != RC_OFF_MODE) {
       iNumMbAssigning = (int32_t) (1.0f * iNumMbAssigning / iNumMbInEachGom + 0.5f + EPSN) * iNumMbInEachGom;
     }
 
--- a/codec/encoder/core/src/wels_preprocess.cpp
+++ b/codec/encoder/core/src/wels_preprocess.cpp
@@ -368,9 +368,9 @@
   }
 
   if(pSvcParam->iUsageType != SCREEN_CONTENT_REAL_TIME){
-    if (pSvcParam->bEnableRc) {
+    if (pSvcParam->iRCMode != RC_OFF_MODE) {
       AnalyzePictureComplexity (pCtx, pCurPic, pRefPic, kiDidx, bCalculateBGD);
-  }
+    }
     WelsExchangeSpatialPictures (&m_pLastSpatialPicture[kiDidx][1], &m_pLastSpatialPicture[kiDidx][0]);
   }
   return 0;
--- a/codec/encoder/plus/src/welsEncoderExt.cpp
+++ b/codec/encoder/plus/src/welsEncoderExt.cpp
@@ -196,7 +196,7 @@
 /* Interfaces override from ISVCEncoder */
 
 int CWelsH264SVCEncoder::GetDefaultParams (SEncParamExt* argv) {
-  SWelsSvcCodingParam::FillDefault(*argv, true);
+  SWelsSvcCodingParam::FillDefault(*argv);
   return cmResultSuccess;
 }
 
@@ -211,9 +211,9 @@
     return cmInitParaError;
   }
 
-  SWelsSvcCodingParam	sConfig (true);
+  SWelsSvcCodingParam	sConfig;
   // Convert SEncParamBase into WelsSVCParamConfig here..
-  if (sConfig.ParamBaseTranscode (*argv, true)) {
+  if (sConfig.ParamBaseTranscode (*argv)) {
     WelsLog (m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), parameter_translation failed.\n");
     Uninitialize();
     return cmInitParaError;
@@ -230,7 +230,7 @@
     return cmInitParaError;
   }
 
-  SWelsSvcCodingParam	sConfig (true);
+  SWelsSvcCodingParam	sConfig;
   // Convert SEncParamExt into WelsSVCParamConfig here..
   if (sConfig.ParamTranscode (*argv)) {
     WelsLog (m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::InitializeExt(), parameter_translation failed.\n");
@@ -686,7 +686,7 @@
   break;
   case ENCODER_OPTION_SVC_ENCODE_PARAM_EXT: {	// SVC Encoding Parameter
     SEncParamExt		sEncodingParam;
-    SWelsSvcCodingParam	sConfig (true);
+    SWelsSvcCodingParam	sConfig;
     int32_t iInputColorspace = 0;
     int32_t iTargetWidth = 0;
     int32_t iTargetHeight = 0;
--- a/testbin/welsenc.cfg
+++ b/testbin/welsenc.cfg
@@ -28,7 +28,7 @@
 MultipleThreadIdc			    1	# 0: auto(dynamic imp. internal encoder); 1: multiple threads imp. disabled; > 1: count number of threads;
 
 #============================== RATE CONTROL ==============================
-EnableRC				1						# ENABLE RC
+RCMode			        0				    # 0: quality mode;  1: bitrate mode;  2: bitrate limited mode;  -1: rc off mode
 TargetBitrate			5000				    # Unit: kbps, controled by EnableRC also
 EnableFrameSkip			1		#Enable Frame Skip
 
--- a/testbin/welsenc_arbitrary_res.cfg
+++ b/testbin/welsenc_arbitrary_res.cfg
@@ -29,7 +29,7 @@
 MultipleThreadIdc			    1	# 0: auto(dynamic imp. internal encoder); 1: multiple threads imp. disabled; > 1: count number of threads;
 
 #============================== RATE CONTROL ==============================
-EnableRC				1						# ENABLE RC
+RCMode                          0                                   # 0: quality mode;  1: bitrate mode;  2: bitrate limited mode;  -1: rc off mode
 TargetBitrate			5000				    # Unit: kbps, controled by EnableRC also
 
 #============================== DENOISE CONTROL ==============================
--- a/testbin/welsenc_ios.cfg
+++ b/testbin/welsenc_ios.cfg
@@ -29,7 +29,7 @@
 MultipleThreadIdc			    1	# 0: auto(dynamic imp. internal encoder); 1: multiple threads imp. disabled; > 1: count number of threads;
 
 #============================== RATE CONTROL ==============================
-EnableRC				1						# ENABLE RC
+RCMode                          0                                   # 0: quality mode;  1: bitrate mode;  2: bitrate limited mode;  -1: rc off mode
 TargetBitrate			5000				    # Unit: kbps, controled by EnableRC also
 EnableFrameSkip			1		#Enable Frame Skip
 
--- a/testbin/welsenc_vd_1d.cfg
+++ b/testbin/welsenc_vd_1d.cfg
@@ -29,7 +29,7 @@
 MultipleThreadIdc			    1	# 0: auto(dynamic imp. internal encoder); 1: multiple threads imp. disabled; > 1: count number of threads;
 
 #============================== RATE CONTROL ==============================
-EnableRC				0						# ENABLE RC
+RCMode                          0                                   # 0: quality mode;  1: bitrate mode;  2: bitrate limited mode;  -1: rc off mode
 TargetBitrate			5000				    # Unit: kbps, controled by EnableRC also
 
 #============================== DENOISE CONTROL ==============================
--- a/testbin/welsenc_vd_rc.cfg
+++ b/testbin/welsenc_vd_rc.cfg
@@ -29,7 +29,7 @@
 MultipleThreadIdc			    1	# 0: auto(dynamic imp. internal encoder); 1: multiple threads imp. disabled; > 1: count number of threads;
 
 #============================== RATE CONTROL ==============================
-EnableRC			1						# ENABLE RC
+RCMode                          0                                   # 0: quality mode;  1: bitrate mode;  2: bitrate limited mode;  -1: rc off mode
 TargetBitrate			600				    # Unit: kbps, controled by EnableRC also
 
 #============================== DENOISE CONTROL ==============================