shithub: openh264

Download patch

ref: 24192cc235ae186a4f3b907f6aebc1ac3a6a9252
parent: 3b5448cbbcea4a7defd470842eaa538258b04593
author: Sijia Chen <sijchen@cisco.com>
date: Thu Oct 30 14:31:50 EDT 2014

add validation of slice parameters instead of assert

--- a/codec/encoder/core/inc/svc_enc_slice_segment.h
+++ b/codec/encoder/core/inc/svc_enc_slice_segment.h
@@ -196,8 +196,8 @@
 bool CheckRasterMultiSliceSetting (const int32_t kiMbNumInFrame, SSliceArgument* pSliceArg);
 bool CheckRowMbMultiSliceSetting (const int32_t kiMbWidth,  SSliceArgument* pSliceArg);
 
-void GomValidCheckSliceNum (const int32_t kiMbWidth, const int32_t kiMbHeight, uint32_t* pSliceNum);
-void GomValidCheckSliceMbNum (const int32_t kiMbWidth, const int32_t kiMbHeight,  SSliceArgument* pSliceArg);
+bool GomValidCheckSliceNum (const int32_t kiMbWidth, const int32_t kiMbHeight, uint32_t* pSliceNum);
+bool GomValidCheckSliceMbNum (const int32_t kiMbWidth, const int32_t kiMbHeight,  SSliceArgument* pSliceArg);
 //end of checking valid para
 
 int32_t DynamicAdjustSlicePEncCtxAll (SSliceCtx* pSliceCtx,
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -307,11 +307,20 @@
         break;
       }
       if (pCodingParam->iRCMode != RC_OFF_MODE) {	// multiple slices verify with gom
-        //check uiSliceNum
-        GomValidCheckSliceNum (iMbWidth, iMbHeight, &pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum);
+        //check uiSliceNum and set uiSliceMbNum with current uiSliceNum
+        if (!GomValidCheckSliceNum (iMbWidth, iMbHeight, &pSpatialLayer->sSliceCfg.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->sSliceCfg.sSliceArgument.uiSliceNum);
+        }
+        if (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum <= 1 ||
+            !GomValidCheckSliceMbNum (iMbWidth, iMbHeight, &pSpatialLayer->sSliceCfg.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->sSliceCfg.sSliceArgument.uiSliceNum);
+          return ENC_RETURN_UNSUPPORTED_PARA;
+        }
         assert (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum > 1);
-        //set uiSliceMbNum with current uiSliceNum
-        GomValidCheckSliceMbNum (iMbWidth, iMbHeight, &pSpatialLayer->sSliceCfg.sSliceArgument);
       } else if (!CheckFixedSliceNumMultiSliceSetting (iMbNumInFrame,
                  &pSpatialLayer->sSliceCfg.sSliceArgument)) {	// verify interleave mode settings
         //check uiSliceMbNum with current uiSliceNum
@@ -1858,11 +1867,19 @@
         break;
       }
       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);
-        //set uiSliceMbNum with current uiSliceNum
-        GomValidCheckSliceMbNum (kiMbWidth, kiMbHeight, &pDlp->sSliceCfg.sSliceArgument);
+        //check uiSliceNum and set uiSliceMbNum with current uiSliceNum
+        if (!GomValidCheckSliceNum (kiMbWidth, kiMbHeight, &pDlp->sSliceCfg.sSliceArgument.uiSliceNum)) {
+          WelsLog (pLogCtx, WELS_LOG_WARNING,
+                   "ParamValidationExt(), unsupported setting with Resolution and uiSliceNum combination under RC on! So uiSliceNum is changed to %d!",
+                   pDlp->sSliceCfg.sSliceArgument.uiSliceNum);
+        }
+        if (pDlp->sSliceCfg.sSliceArgument.uiSliceNum <= 1 ||
+            !GomValidCheckSliceMbNum (kiMbWidth, kiMbHeight, &pDlp->sSliceCfg.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!",
+                   pDlp->sSliceCfg.sSliceArgument.uiSliceNum);
+          return ENC_RETURN_INVALIDINPUT;
+        }
       } else if (!CheckFixedSliceNumMultiSliceSetting (kiMbNumInFrame,
                  &pDlp->sSliceCfg.sSliceArgument)) {	// verify interleave mode settings
         //check uiSliceMbNum with current uiSliceNum
@@ -1894,7 +1911,7 @@
       2; // Disable loop filter on slice boundaries since that's not allowed with multithreading
   *pMaxSliceCount					= iMaxSliceCount;
 
-  return 0;
+  return ENC_RETURN_SUCCESS;
 }
 
 /*!
--- a/codec/encoder/core/src/svc_enc_slice_segment.cpp
+++ b/codec/encoder/core/src/svc_enc_slice_segment.cpp
@@ -218,7 +218,7 @@
 
 
 // GOM based RC related for uiSliceNum decision, only used at SM_FIXEDSLCNUM_SLICE
-void GomValidCheckSliceNum (const int32_t kiMbWidth, const int32_t kiMbHeight, uint32_t* pSliceNum) {
+bool GomValidCheckSliceNum (const int32_t kiMbWidth, const int32_t kiMbHeight, uint32_t* pSliceNum) {
   const int32_t kiCountNumMb	= kiMbWidth * kiMbHeight;
   int32_t iSliceNum			= *pSliceNum;
   int32_t iGomSize;
@@ -246,15 +246,16 @@
     break;
   }
 
-  if (0 == iSliceNum)
-    iSliceNum = 1;
-
-  *pSliceNum	= iSliceNum;
+  if (*pSliceNum	!= iSliceNum) {
+    *pSliceNum	= (0 != iSliceNum) ? iSliceNum : 1;
+    return false;
+  }
+  return true;
 }
 
 
 // GOM based RC related for uiSliceMbNum decision, only used at SM_FIXEDSLCNUM_SLICE
-void GomValidCheckSliceMbNum (const int32_t kiMbWidth, const int32_t kiMbHeight, SSliceArgument* pSliceArg) {
+bool GomValidCheckSliceMbNum (const int32_t kiMbWidth, const int32_t kiMbHeight, SSliceArgument* pSliceArg) {
   uint32_t* pSlicesAssignList		= & (pSliceArg->uiSliceMbNum[0]);
   const uint32_t kuiSliceNum			= pSliceArg->uiSliceNum;
   const int32_t kiMbNumInFrame	= kiMbWidth * kiMbHeight;
@@ -292,10 +293,15 @@
     else if (iNumMbAssigning > iMaximalMbNum)
       iNumMbAssigning	= iMaximalMbNum;
 
-    assert (iNumMbAssigning > 0);
+    if (iNumMbAssigning <= 0) {
+      return false;
+    }
 
     iNumMbLeft -= iNumMbAssigning;
-    assert (iNumMbLeft > 0);
+    if (iNumMbLeft <= 0)  {
+      return false;
+    }
+
     pSlicesAssignList[uiSliceIdx]	= iNumMbAssigning;
 
     ++ uiSliceIdx;
@@ -302,6 +308,8 @@
     iMaximalMbNum	= iNumMbLeft - (kuiSliceNum - uiSliceIdx - 1) * iMinimalMbNum;	// get maximal num_mb in left parts
   }
   pSlicesAssignList[uiSliceIdx] = iNumMbLeft;
+
+  return true;
 }