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;
}