diff --git a/codec/api/svc/codec_app_def.h b/codec/api/svc/codec_app_def.h index e4f074d8..129a05d5 100644 --- a/codec/api/svc/codec_app_def.h +++ b/codec/api/svc/codec_app_def.h @@ -275,6 +275,7 @@ typedef struct TagEncParamExt int iMaxBitrate; // max bitrate desired int iMaxQp; int iMinQp; + unsigned int uiMaxNalSize; /*LTR settings*/ bool bEnableLongTermReference; // 0: on, 1: off diff --git a/codec/encoder/core/inc/param_svc.h b/codec/encoder/core/inc/param_svc.h index 0ff439b3..66146726 100644 --- a/codec/encoder/core/inc/param_svc.h +++ b/codec/encoder/core/inc/param_svc.h @@ -188,6 +188,7 @@ static void FillDefault (SEncParamExt& param, const bool kbEnableRc) { param.iMaxQp = 51; param.iMinQp = 0; param.iUsageType = CAMERA_VIDEO_REAL_TIME; + param.uiMaxNalSize = 0; for(int32_t iLayer = 0;iLayer< MAX_SPATIAL_LAYER_NUM;iLayer++){ param.sSpatialLayers[iLayer].uiProfileIdc = PRO_BASELINE; @@ -333,6 +334,7 @@ int32_t ParamTranscode (const SEncParamExt& pCodingParam) { iTargetBitrate = pCodingParam.iTargetBitrate; // target bitrate iMaxBitrate = pCodingParam.iMaxBitrate; + uiMaxNalSize = pCodingParam.uiMaxNalSize; /* Denoise Control */ bEnableDenoise = pCodingParam.bEnableDenoise ? true : false; // Denoise Control // only support 0 or 1 now diff --git a/codec/encoder/core/inc/wels_const.h b/codec/encoder/core/inc/wels_const.h index 3e9c4437..fca7c065 100644 --- a/codec/encoder/core/inc/wels_const.h +++ b/codec/encoder/core/inc/wels_const.h @@ -167,6 +167,8 @@ #define UNAVAILABLE_DQ_ID ((uint8_t)(-1)) #define LAYER_NUM_EXCHANGEABLE 2 +#define NAL_HEADER_ADD_0X30BYTES 50 + #define MAX_NAL_UNIT_NUM_IN_AU 256 // predefined maximal number of NAL Units in an access unit #define MAX_ACCESS_UINT_CAPACITY (1<<20) // Maximal AU capacity in bytes: 1024 KB predefined #define MAX_ACCESS_UNIT_CACHE_NUM 2 // Maximal Access Unit(AU) cache number to be processed, denote current AU and the next coming AU. diff --git a/codec/encoder/core/src/encoder_ext.cpp b/codec/encoder/core/src/encoder_ext.cpp index 815a0cd5..c3f9132b 100644 --- a/codec/encoder/core/src/encoder_ext.cpp +++ b/codec/encoder/core/src/encoder_ext.cpp @@ -196,7 +196,10 @@ int32_t ParamValidationExt (sWelsEncCtx*pCtx,SWelsSvcCodingParam* pCodingParam) WelsLog (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceMode (%d) settings!\n", fDlp->sSliceCfg.uiSliceMode); return ENC_RETURN_UNSUPPORTED_PARA; } - + if((pCodingParam->uiMaxNalSize != 0) && (fDlp->sSliceCfg.uiSliceMode != SM_DYN_SLICE)){ + WelsLog (pCtx, WELS_LOG_ERROR,"ParamValidationExt(), invalid uiSliceMode (%d) settings!,MaxNalSize = %d\n", fDlp->sSliceCfg.uiSliceMode,pCodingParam->uiMaxNalSize); + return ENC_RETURN_UNSUPPORTED_PARA; + } //check pSlice settings under multi-pSlice if (kiPicWidth <= 16 && kiPicHeight <= 16) { //only have one MB, set to single_slice @@ -328,6 +331,19 @@ int32_t ParamValidationExt (sWelsEncCtx*pCtx,SWelsSvcCodingParam* pCodingParam) fDlp->sSliceCfg.sSliceArgument.uiSliceSizeConstraint); return ENC_RETURN_UNSUPPORTED_PARA; } + + if( pCodingParam->uiMaxNalSize <= NAL_HEADER_ADD_0X30BYTES) { + WelsLog (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiMaxNalSize (%d) settings!\n", + pCodingParam->uiMaxNalSize); + return ENC_RETURN_UNSUPPORTED_PARA; + } + + if( fDlp->sSliceCfg.sSliceArgument.uiSliceSizeConstraint > (pCodingParam->uiMaxNalSize - NAL_HEADER_ADD_0X30BYTES)){ + WelsLog (pCtx, WELS_LOG_WARNING, "ParamValidationExt(), slice mode = SM_DYN_SLICE, uiSliceSizeConstraint = %d ,uiMaxNalsize = %d!\n", + fDlp->sSliceCfg.sSliceArgument.uiSliceSizeConstraint,pCodingParam->uiMaxNalSize); + fDlp->sSliceCfg.sSliceArgument.uiSliceSizeConstraint = pCodingParam->uiMaxNalSize - NAL_HEADER_ADD_0X30BYTES; + } + // considering the coding efficient and performance, iCountMbNum constraint by MIN_NUM_MB_PER_SLICE condition of multi-pSlice mode settting if (iMbWidth * iMbHeight <= MIN_NUM_MB_PER_SLICE) { fDlp->sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;