shithub: openh264

Download patch

ref: 24fb213d6e4e41e50af5955ab30275b1abddda8f
parent: c13bfe6407252f64610b0c2c9aa0737054dcd71e
parent: 0b2c82d92b28fbda54401044b0374b0bbaeafa3b
author: ruil2 <[email protected]>
date: Thu Nov 20 04:33:36 EST 2014

Merge pull request #1537 from sijchen/after_review

[Encoder] Two refinements related to max bit rate setting and Timestamp

--- a/codec/api/svc/codec_app_def.h
+++ b/codec/api/svc/codec_app_def.h
@@ -50,6 +50,8 @@
 #define MAX_SLICES_NUM_TMP			( ( MAX_NAL_UNITS_IN_LAYER - SAVED_NALUNIT_NUM_TMP ) / 3 )
 
 #define AUTO_REF_PIC_COUNT  -1  // encoder selects the number of reference frame automatically
+#define UNSPECIFIED_BIT_RATE 0  //
+
 typedef enum {
   /* Errors derived from bitstream parsing */
   dsErrorFree			= 0x00,	/* Bitstream error-free */
--- a/codec/encoder/core/inc/param_svc.h
+++ b/codec/encoder/core/inc/param_svc.h
@@ -136,7 +136,7 @@
 
     param.iComplexityMode = MEDIUM_COMPLEXITY;
     param.iTargetBitrate			= 0;	// overall target bitrate introduced in RC module
-    param.iMaxBitrate             = MAX_BIT_RATE;
+    param.iMaxBitrate         = UNSPECIFIED_BIT_RATE;
     param.iMultipleThreadIdc		= 1;
 
     param.iLTRRefNum				= 0;
@@ -179,7 +179,7 @@
       param.sSpatialLayers[iLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
       param.sSpatialLayers[iLayer].sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 1500;
       param.sSpatialLayers[iLayer].sSliceCfg.sSliceArgument.uiSliceNum = 1;
-      param.sSpatialLayers[iLayer].iMaxSpatialBitrate = MAX_BIT_RATE;
+      param.sSpatialLayers[iLayer].iMaxSpatialBitrate = UNSPECIFIED_BIT_RATE;
       const int32_t kiLesserSliceNum = ((MAX_SLICES_NUM < MAX_SLICES_NUM_TMP) ? MAX_SLICES_NUM : MAX_SLICES_NUM_TMP);
       for (int32_t idx = 0; idx < kiLesserSliceNum; idx++)
         param.sSpatialLayers[iLayer].sSliceCfg.sSliceArgument.uiSliceMbNum[idx] = 960;
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -494,7 +494,21 @@
       pLayerParam = & (pParam->sSpatialLayers[i]);
       fRatio = pLayerParam->iSpatialBitrate / (static_cast<float> (iOrigTotalBitrate));
       pLayerParam->iSpatialBitrate = static_cast<int32_t> (pParam->iTargetBitrate * fRatio);
+      if ( UNSPECIFIED_BIT_RATE != pLayerParam->iMaxSpatialBitrate && pLayerParam->iSpatialBitrate > pLayerParam->iMaxSpatialBitrate ) {
+        WelsLog (pLogCtx, WELS_LOG_WARNING,
+                 "WelsEncoderApplyBitRate(), iSpatialBitrate(%d) > iMaxSpatialBitrate(%d) at Layer %d, limiting iSpatialBitrate to iMaxSpatialBitrate!",
+                 pLayerParam->iSpatialBitrate, pLayerParam->iMaxSpatialBitrate, iLayer);
+        pLayerParam->iSpatialBitrate = pLayerParam->iMaxSpatialBitrate;
+      }
     }
+  } else {
+    SSpatialLayerConfig* pLayerParam = & (pParam->sSpatialLayers[iLayer]);
+    if ( UNSPECIFIED_BIT_RATE != pLayerParam->iMaxSpatialBitrate && pLayerParam->iSpatialBitrate > pLayerParam->iMaxSpatialBitrate ) {
+      WelsLog (pLogCtx, WELS_LOG_WARNING,
+               "WelsEncoderApplyBitRate(), iSpatialBitrate(%d) > iMaxSpatialBitrate(%d) at Layer %d, limiting iSpatialBitrate to iMaxSpatialBitrate!",
+               pLayerParam->iSpatialBitrate, pLayerParam->iMaxSpatialBitrate, iLayer);
+      pLayerParam->iSpatialBitrate = pLayerParam->iMaxSpatialBitrate;
+    }
   }
 }
 
@@ -2999,13 +3013,13 @@
 
 //loop each layer to check if have skip frame when RC and frame skip enable (maxbr>0)
 bool CheckFrameSkipBasedMaxbr (sWelsEncCtx* pCtx, int32_t iSpatialNum, EVideoFrameType eFrameType,
-                               const uint32_t uiTimeStamp) {
+                               const long long uiTimeStamp) {
   SSpatialPicIndex* pSpatialIndexMap = &pCtx->sSpatialIndexMap[0];
   bool bSkipMustFlag = false;
   if (pCtx->pSvcParam->bEnableFrameSkip) {
     if ((RC_QUALITY_MODE == pCtx->pSvcParam->iRCMode) || (RC_BITRATE_MODE == pCtx->pSvcParam->iRCMode)) {
       for (int32_t i = 0; i < iSpatialNum; i++) {
-        if (0 == pCtx->pSvcParam->sSpatialLayers[i].iMaxSpatialBitrate) {
+        if (UNSPECIFIED_BIT_RATE == pCtx->pSvcParam->sSpatialLayers[i].iMaxSpatialBitrate) {
           break;
         }
         pCtx->uiDependencyId = (uint8_t) (pSpatialIndexMap + i)->iDid;
@@ -3087,7 +3101,7 @@
   }
 
   //loop each layer to check if have skip frame when RC and frame skip enable
-  if (CheckFrameSkipBasedMaxbr (pCtx, iSpatialNum, eFrameType, (uint32_t)pSrcPic->uiTimeStamp)) {
+  if (CheckFrameSkipBasedMaxbr (pCtx, iSpatialNum, eFrameType, pSrcPic->uiTimeStamp)) {
     pFbi->eFrameType = videoFrameTypeSkip;
     WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %lld",
              pSrcPic->uiTimeStamp);