shithub: openh264

Download patch

ref: 14d89eb48c51c21a0e4274f011f08132fb183c20
parent: 76b428a453bb44a8400b383d77f2702e31de52ff
author: huade <[email protected]>
date: Fri Dec 11 08:07:46 EST 2015

refact validate and init logic for fixed sliceMode

--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -165,6 +165,83 @@
              "doesn't support the number of reference frame(%d) change to auto select mode", iNumRef);
   }
 }
+
+int32_t SliceArgumentValidationFixedSliceMode(SLogContext* pLogCtx,
+                                              SSliceArgument* pSliceArgument, const RC_MODES  kiRCMode,
+                                              const int32_t kiPicWidth,       const int32_t kiPicHeight) {
+  int32_t iCpuCores            = 0;
+  int32_t iIdx                 = 0;
+  const int32_t iMbWidth       = (kiPicWidth + 15) >> 4;
+  const int32_t iMbHeight      = (kiPicHeight + 15) >> 4;
+  const int32_t iMbNumInFrame  = iMbWidth * iMbHeight;
+  bool  bSingleMode            = false;
+
+  pSliceArgument->uiSliceSizeConstraint = 0;
+
+  if (pSliceArgument->uiSliceNum == 0) {
+    WelsCPUFeatureDetect (&iCpuCores);
+    pSliceArgument->uiSliceNum = iCpuCores;
+  }
+
+  if (pSliceArgument->uiSliceNum <= 1) {
+    WelsLog (pLogCtx, WELS_LOG_INFO, "SliceArgumentValidationFixedSliceMode(), uiSliceNum(%d) you set for SM_FIXEDSLCNUM_SLICE, now turn to SM_SINGLE_SLICE type!",
+    pSliceArgument->uiSliceNum);
+    bSingleMode = true;
+  }
+
+  // considering the coding efficient and performance,
+  // iCountMbNum constraint by MIN_NUM_MB_PER_SLICE condition of multi-pSlice mode settting
+  if (iMbNumInFrame <= MIN_NUM_MB_PER_SLICE) {
+    WelsLog (pLogCtx, WELS_LOG_INFO, "SliceArgumentValidationFixedSliceMode(), uiSliceNum(%d) you set for SM_FIXEDSLCNUM_SLICE, now turn to SM_SINGLE_SLICE type as CountMbNum less than MIN_NUM_MB_PER_SLICE!",
+             pSliceArgument->uiSliceNum);
+    bSingleMode = true;
+  }
+
+  if (bSingleMode) {
+    pSliceArgument->uiSliceMode = SM_SINGLE_SLICE;
+    pSliceArgument->uiSliceNum = 1;
+    for (iIdx = 0; iIdx < MAX_SLICES_NUM; iIdx++) {
+      pSliceArgument->uiSliceMbNum[iIdx] = 0;
+    }
+    return ENC_RETURN_SUCCESS;
+  }
+
+  if (pSliceArgument->uiSliceNum > MAX_SLICES_NUM) {
+    pSliceArgument->uiSliceNum = MAX_SLICES_NUM;
+    WelsLog (pLogCtx, WELS_LOG_WARNING, "SliceArgumentValidationFixedSliceMode(), uiSliceNum exceed MAX_SLICES_NUM! So setting slice num eqaul to MAX_SLICES_NUM(%d)!",
+             pSliceArgument->uiSliceNum);
+  }
+
+  if (kiRCMode != RC_OFF_MODE) { // multiple slices verify with gom
+    //check uiSliceNum and set uiSliceMbNum with current uiSliceNum
+    if (!GomValidCheckSliceNum (iMbWidth, iMbHeight, &pSliceArgument->uiSliceNum)) {
+      WelsLog (pLogCtx, WELS_LOG_WARNING, "SliceArgumentValidationFixedSliceMode(), unsupported setting with Resolution and uiSliceNum combination under RC on! So uiSliceNum is changed to %d!",
+      pSliceArgument->uiSliceNum);
+    }
+
+    if (pSliceArgument->uiSliceNum <= 1 ||
+        !GomValidCheckSliceMbNum (iMbWidth, iMbHeight, pSliceArgument)) {
+      WelsLog (pLogCtx, WELS_LOG_ERROR,
+               "SliceArgumentValidationFixedSliceMode(), unsupported setting with Resolution and uiSliceNum (%d) combination  under RC on! Consider setting single slice with this resolution!",
+               pSliceArgument->uiSliceNum);
+      return ENC_RETURN_UNSUPPORTED_PARA;
+    }
+  } else if (!CheckFixedSliceNumMultiSliceSetting (iMbNumInFrame, pSliceArgument)) {
+    //check uiSliceMbNum with current uiSliceNum
+    WelsLog (pLogCtx, WELS_LOG_ERROR,
+             "SliceArgumentValidationFixedSliceMode(), invalid uiSliceMbNum (%d) settings!,now turn to SM_SINGLE_SLICE type",
+    pSliceArgument->uiSliceMbNum[0]);
+    pSliceArgument->uiSliceMode = SM_SINGLE_SLICE;
+    pSliceArgument->uiSliceNum  = 1;
+    for (iIdx = 0; iIdx < MAX_SLICES_NUM; iIdx++) {
+      pSliceArgument->uiSliceMbNum[iIdx] = 0;
+    }
+  }
+
+  return ENC_RETURN_SUCCESS;
+}
+
+
 /*!
  * \brief   validate checking in parameter configuration
  * \pParam  pParam      SWelsSvcCodingParam*
@@ -398,6 +475,7 @@
     uint32_t iMbHeight          = 0;
     int32_t iMbNumInFrame       = 0;
     uint32_t iMaxSliceNum       = MAX_SLICES_NUM;
+    int32_t  iReturn            = 0;
     if ((kiPicWidth <= 0) || (kiPicHeight <= 0) || (kiPicWidth > MAX_WIDTH) || (kiPicHeight > MAX_HEIGHT)) {
       WelsLog (pLogCtx, WELS_LOG_ERROR,
                "ParamValidationExt(),width(1-%d),height(1-%d)invalid %d x %d in dependency layer settings!", MAX_WIDTH, MAX_HEIGHT,
@@ -436,68 +514,10 @@
       }
       break;
     case SM_FIXEDSLCNUM_SLICE: {
-      pSpatialLayer->sSliceArgument.uiSliceSizeConstraint = 0;
-
-      iMbWidth  = (kiPicWidth + 15) >> 4;
-      iMbHeight = (kiPicHeight + 15) >> 4;
-      iMbNumInFrame = iMbWidth * iMbHeight;
-      iMaxSliceNum = MAX_SLICES_NUM;
-      if (pSpatialLayer->sSliceArgument.uiSliceNum == 0) {
-        int32_t uiCpuCores = 0;
-        WelsCPUFeatureDetect (&uiCpuCores); // detect cpu capacity features
-        pSpatialLayer->sSliceArgument.uiSliceNum = uiCpuCores;
-
-        if (uiCpuCores <= 1) {
-          WelsLog (pLogCtx, WELS_LOG_INFO, "ParamValidationExt(), uiCpuCores = 1, switched to SM_SINGLE_SLICE");
-          pSpatialLayer->sSliceArgument.uiSliceMode = SM_SINGLE_SLICE;
-          pSpatialLayer->sSliceArgument.uiSliceNum = 1;
-          pSpatialLayer->sSliceArgument.uiSliceSizeConstraint = 0;
-          for (iIdx = 0; iIdx < MAX_SLICES_NUM; iIdx++) {
-            pSpatialLayer->sSliceArgument.uiSliceMbNum[iIdx] = 0;
-          }
-          break;
-        }
-      }
-      if (pSpatialLayer->sSliceArgument.uiSliceNum > iMaxSliceNum) {
-        WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceNum (%d) settings!",
-                 pSpatialLayer->sSliceArgument.uiSliceNum);
+      iReturn = SliceArgumentValidationFixedSliceMode(pLogCtx, &pSpatialLayer->sSliceArgument, pCodingParam->iRCMode,
+                                                      kiPicWidth, kiPicHeight);
+      if(iReturn)
         return ENC_RETURN_UNSUPPORTED_PARA;
-      }
-      if (pSpatialLayer->sSliceArgument.uiSliceNum == 1) {
-        WelsLog (pLogCtx, WELS_LOG_DEBUG,
-                 "ParamValidationExt(), uiSliceNum(%d) you set for SM_FIXEDSLCNUM_SLICE, now turn to SM_SINGLE_SLICE type!",
-                 pSpatialLayer->sSliceArgument.uiSliceNum);
-        pSpatialLayer->sSliceArgument.uiSliceMode = SM_SINGLE_SLICE;
-        break;
-      }
-      if (pCodingParam->iRCMode != RC_OFF_MODE) { // multiple slices verify with gom
-        //check uiSliceNum and set uiSliceMbNum with current uiSliceNum
-        if (!GomValidCheckSliceNum (iMbWidth, iMbHeight, &pSpatialLayer->sSliceArgument.uiSliceNum)) {
-          WelsLog (pLogCtx, WELS_LOG_WARNING,
-                   "ParamValidationExt(), unsupported setting with Resolution and uiSliceNum combination under RC on! So uiSliceNum is changed to %d!",
-                   pSpatialLayer->sSliceArgument.uiSliceNum);
-        }
-        if (pSpatialLayer->sSliceArgument.uiSliceNum <= 1 ||
-            !GomValidCheckSliceMbNum (iMbWidth, iMbHeight, &pSpatialLayer->sSliceArgument)) {
-          WelsLog (pLogCtx, WELS_LOG_ERROR,
-                   "ParamValidationExt(), unsupported setting with Resolution and uiSliceNum (%d) combination  under RC on! Consider setting single slice with this resolution!",
-                   pSpatialLayer->sSliceArgument.uiSliceNum);
-          return ENC_RETURN_UNSUPPORTED_PARA;
-        }
-        assert (pSpatialLayer->sSliceArgument.uiSliceNum > 1);
-      } else if (!CheckFixedSliceNumMultiSliceSetting (iMbNumInFrame,
-                 &pSpatialLayer->sSliceArgument)) { // verify interleave mode settings
-        //check uiSliceMbNum with current uiSliceNum
-        WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceMbNum (%d) settings!",
-                 pSpatialLayer->sSliceArgument.uiSliceMbNum[0]);
-        return ENC_RETURN_UNSUPPORTED_PARA;
-      }
-      // considering the coding efficient and performance, iCountMbNum constraint by MIN_NUM_MB_PER_SLICE condition of multi-pSlice mode settting
-      if (iMbNumInFrame <= MIN_NUM_MB_PER_SLICE) {
-        pSpatialLayer->sSliceArgument.uiSliceMode = SM_SINGLE_SLICE;
-        pSpatialLayer->sSliceArgument.uiSliceNum = 1;
-        break;
-      }
     }
     break;
     case SM_RASTER_SLICE: {
@@ -2232,10 +2252,8 @@
 
   do {
     SSpatialLayerConfig* pDlp           = &pCodingParam->sSpatialLayers[iSpatialIdx];
-    SSliceArgument* pSliceArgument                  = &pDlp->sSliceArgument;
-    const int32_t kiMbWidth             = (pDlp->iVideoWidth + 15) >> 4;
-    const int32_t kiMbHeight            = (pDlp->iVideoHeight + 15) >> 4;
-    const int32_t kiMbNumInFrame        = kiMbWidth * kiMbHeight;
+    SSliceArgument* pSliceArgument      = &pDlp->sSliceArgument;
+    int32_t iReturn                     = 0;
     int32_t iSliceNum                   = (SM_FIXEDSLCNUM_SLICE == pSliceArgument->uiSliceMode && 0==pSliceArgument->uiSliceNum) ? kiCpuCores : pSliceArgument->uiSliceNum;
     // NOTE: Per design, in case MT/DYNAMIC_SLICE_ASSIGN enabled, for SM_FIXEDSLCNUM_SLICE mode,
     // uiSliceNum of current spatial layer settings equals to uiCpuCores number; SM_SIZELIMITED_SLICE mode,
@@ -2246,80 +2264,17 @@
     case SM_SIZELIMITED_SLICE:
       iMaxSliceCount = AVERSLICENUM_CONSTRAINT;
       break; // go through for SM_SIZELIMITED_SLICE?
-    case SM_FIXEDSLCNUM_SLICE:
-      if (iSliceNum > iMaxSliceCount) {
-        iMaxSliceCount = iSliceNum;
-      }
-      if (0==iSliceNum) {
-        //the auto slice num logic
-        pDlp->sSliceArgument.uiSliceNum = kiCpuCores;
+    case SM_FIXEDSLCNUM_SLICE: {
+      iReturn = SliceArgumentValidationFixedSliceMode(pLogCtx, &pDlp->sSliceArgument, pCodingParam->iRCMode,
+                                                      pDlp->iVideoWidth, pDlp->iVideoHeight);
+      if(iReturn)
+        return ENC_RETURN_UNSUPPORTED_PARA;
 
-        if (0==kiCpuCores){
-        int32_t uiCpuCores = 0;
-        WelsCPUFeatureDetect (&uiCpuCores); // detect cpu capacity features
-        pDlp->sSliceArgument.uiSliceNum = uiCpuCores;
-
-        if (uiCpuCores == 1) {
-          WelsLog (pLogCtx, WELS_LOG_INFO, "InitSliceSettings(), uiCpuCores = 1, switched to SM_SINGLE_SLICE");
-          pDlp->sSliceArgument.uiSliceMode = SM_SINGLE_SLICE;
-          pDlp->sSliceArgument.uiSliceNum = 1;
-          pDlp->sSliceArgument.uiSliceSizeConstraint = 0;
-          for (int32_t iIdx = 0; iIdx < MAX_SLICES_NUM; iIdx++) {
-            pDlp->sSliceArgument.uiSliceMbNum[iIdx] = 0;
-          }
-          break;
-        }
-        }
-
-        if (pDlp->sSliceArgument.uiSliceNum == 1) {
-          WelsLog (pLogCtx, WELS_LOG_DEBUG,
-                   "InitSliceSettings(), uiSliceNum(%d) you set for SM_AUTO_SLICE, now turn to SM_SINGLE_SLICE type!",
-                   pDlp->sSliceArgument.uiSliceNum);
-          pDlp->sSliceArgument.uiSliceMode = SM_SINGLE_SLICE;
-          break;
-        }
-
-        if (pDlp->sSliceArgument.uiSliceNum > MAX_SLICES_NUM) {
-          pDlp->sSliceArgument.uiSliceNum = MAX_SLICES_NUM;
-        }
-        iMaxSliceCount = WELS_MAX(iMaxSliceCount, pDlp->sSliceArgument.uiSliceNum);
-
-        if (pCodingParam->iRCMode != RC_OFF_MODE) { // multiple slices verify with gom
-          //check uiSliceNum and set uiSliceMbNum with current uiSliceNum
-          if (!GomValidCheckSliceNum (kiMbWidth, kiMbHeight, &pDlp->sSliceArgument.uiSliceNum)) {
-            WelsLog (pLogCtx, WELS_LOG_WARNING,
-                     "InitSliceSettings(), unsupported setting with Resolution and uiSliceNum combination under RC on! So uiSliceNum is changed to %d!",
-                     pDlp->sSliceArgument.uiSliceNum);
-          }
-          if (pDlp->sSliceArgument.uiSliceNum <= 1 ||
-              !GomValidCheckSliceMbNum (kiMbWidth, kiMbHeight, &pDlp->sSliceArgument)) {
-            WelsLog (pLogCtx, WELS_LOG_ERROR,
-                     "InitSliceSettings(), unsupported setting with Resolution and uiSliceNum (%d) combination  under RC on! Consider setting single slice with this resolution!",
-                     pDlp->sSliceArgument.uiSliceNum);
-            return ENC_RETURN_INVALIDINPUT;
-          }
-        } else if (!CheckFixedSliceNumMultiSliceSetting (kiMbNumInFrame,
-                                                         &pDlp->sSliceArgument)) {    // verify interleave mode settings
-          //check uiSliceMbNum with current uiSliceNum
-          WelsLog (pLogCtx, WELS_LOG_ERROR,
-                   "InitSliceSettings(), invalid uiSliceMbNum (%d) settings!,now turn to SM_SINGLE_SLICE type",
-                   pDlp->sSliceArgument.uiSliceMbNum[0]);
-          pDlp->sSliceArgument.uiSliceMode = SM_SINGLE_SLICE;
-          pDlp->sSliceArgument.uiSliceNum = 1;
-        }
-        // considering the coding efficient and performance, iCountMbNum constraint by MIN_NUM_MB_PER_SLICE condition of multi-pSlice mode settting
-        if (kiMbNumInFrame <= MIN_NUM_MB_PER_SLICE) {
-          pDlp->sSliceArgument.uiSliceMode = SM_SINGLE_SLICE;
-          pDlp->sSliceArgument.uiSliceNum = 1;
-          break;
-        }
+      if (pSliceArgument->uiSliceNum > iMaxSliceCount) {
+        iMaxSliceCount = pSliceArgument->uiSliceNum;
       }
-      // need perform check due uiSliceNum might change, although has been initialized somewhere outside
-      if (pCodingParam->iRCMode != RC_OFF_MODE) {
-        GomValidCheckSliceMbNum (kiMbWidth, kiMbHeight, pSliceArgument);
-      } else {
-        CheckFixedSliceNumMultiSliceSetting (kiMbNumInFrame, pSliceArgument);
-      }
+
+    }
       break;
     case SM_SINGLE_SLICE:
       if (iSliceNum > iMaxSliceCount)
@@ -3838,8 +3793,7 @@
     switch (pParam->sSliceArgument.uiSliceMode) {
     case SM_FIXEDSLCNUM_SLICE: {
       if ((iCurDid > 0) && (pSvcParam->iMultipleThreadIdc > 1) &&
-          (pSvcParam->sSpatialLayers[iCurDid].sSliceArgument.uiSliceMode == SM_FIXEDSLCNUM_SLICE
-           && pSvcParam->bUseLoadBalancing
+          (pSvcParam->bUseLoadBalancing
            && pSvcParam->iMultipleThreadIdc >= pSvcParam->sSpatialLayers[iCurDid].sSliceArgument.uiSliceNum)
          )
         AdjustEnhanceLayer (pCtx, iCurDid);
--- a/codec/encoder/core/src/svc_enc_slice_segment.cpp
+++ b/codec/encoder/core/src/svc_enc_slice_segment.cpp
@@ -153,8 +153,13 @@
     pSlicesAssignList[uiSliceIdx] = kiMbNumPerSlice;
     iNumMbLeft -= kiMbNumPerSlice;
   }
+
   pSlicesAssignList[uiSliceIdx] = iNumMbLeft;
 
+  if (iNumMbLeft <= 0 || kiMbNumPerSlice <= 0 ) {
+    return false;
+  }
+
   return true;
 }
 
@@ -295,7 +300,6 @@
   iMinimalMbNum = iGomSize;
   while (uiSliceIdx + 1 < kuiSliceNum) {
     iMaximalMbNum = iNumMbLeft - (kuiSliceNum - uiSliceIdx - 1) * iMinimalMbNum; // get maximal num_mb in left parts
-
     // make sure one GOM at least in each slice for safe
     if (iNumMbAssigning < iMinimalMbNum)
       iCurNumMbAssigning = iMinimalMbNum;
@@ -317,6 +321,9 @@
     ++ uiSliceIdx;
   }
   pSlicesAssignList[uiSliceIdx] = iNumMbLeft;
+  if ( iNumMbLeft < iMinimalMbNum ) {
+    return false;
+  }
 
   return true;
 }