4261 lines · 181.9 KB · C++
RawDownload
/*! * \copy *     Copyright (c)  2009-2013, Cisco Systems *     All rights reserved. * *     Redistribution and use in source and binary forms, with or without *     modification, are permitted provided that the following conditions *     are met: * *        * Redistributions of source code must retain the above copyright *          notice, this list of conditions and the following disclaimer. * *        * Redistributions in binary form must reproduce the above copyright *          notice, this list of conditions and the following disclaimer in *          the documentation and/or other materials provided with the *          distribution. * *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *     POSSIBILITY OF SUCH DAMAGE. * * * \file	encoder_ext.c * * \brief	core encoder for SVC * * \date	7/24/2009 Created * ************************************************************************************* */ #include "encoder.h"#include "cpu.h"#include "utils.h"#include "svc_enc_golomb.h"#include "au_set.h"#include "picture_handle.h"#include "svc_base_layer_md.h"#include "svc_encode_slice.h"#include "svc_mode_decision.h"#include "decode_mb_aux.h"#include "deblocking.h"#include "ref_list_mgr_svc.h"#include "ls_defines.h"#include "crt_util_safe_x.h"	// Safe CRT routines like utils for cross platforms#include "slice_multi_threading.h"#include "measure_time.h"#include "svc_set_mb_syn.h" namespace WelsEnc {  int32_t WelsCodeOnePicPartition (sWelsEncCtx* pCtx,                                 SFrameBSInfo* pFrameBsInfo,                                 SLayerBSInfo* pLayerBsInfo,                                 int32_t* pNalIdxInLayer,                                 int32_t* pLayerSize,                                 int32_t iFirstMbInPartition,	// first mb inclusive in partition                                 int32_t iEndMbInPartition,	// end mb exclusive in partition                                 int32_t iStartSliceIdx                                );  int32_t WelsBitRateVerification (SLogContext* pLogCtx, SSpatialLayerConfig* pLayerParam, int32_t iLayerId) {  if (pLayerParam->iSpatialBitrate <= 0) {    WelsLog (pLogCtx, WELS_LOG_ERROR, "Invalid bitrate settings in layer %d, bitrate= %d", iLayerId,             pLayerParam->iSpatialBitrate);    return ENC_RETURN_UNSUPPORTED_PARA;  }  if (pLayerParam->iMaxSpatialBitrate == pLayerParam->iSpatialBitrate) {    WelsLog (pLogCtx, WELS_LOG_INFO,             "Setting MaxSpatialBitrate (%d) the same at SpatialBitrate (%d) will make the actual bit rate lower than SpatialBitrate",             pLayerParam->iMaxSpatialBitrate, pLayerParam->iSpatialBitrate);  }  int32_t iLevelMaxBitrate = g_ksLevelLimits[pLayerParam->uiLevelIdc - 1].uiMaxBR * CpbBrNalFactor;  if (pLayerParam->iMaxSpatialBitrate == UNSPECIFIED_BIT_RATE) {    pLayerParam->iMaxSpatialBitrate = iLevelMaxBitrate;    WelsLog (pLogCtx, WELS_LOG_INFO, "Current MaxSpatialBitrate is zero,Get this value from level limitation(%d)",             pLayerParam->iMaxSpatialBitrate);  }  if (pLayerParam->iMaxSpatialBitrate > iLevelMaxBitrate) {    ELevelIdc iCurLevel = pLayerParam->uiLevelIdc;    if (WelsAdjustLevel (pLayerParam)) {      WelsLog (pLogCtx, WELS_LOG_WARNING,               "MaxSpatialBitrate (%d) is larger that the limitation LEVEL_5_2, the setting will be invalid",               pLayerParam->iMaxSpatialBitrate);    }    WelsLog (pLogCtx, WELS_LOG_INFO,             "Level is changed from (%d) to (%d) according to the maxbitrate",             iCurLevel, pLayerParam->uiLevelIdc);  }  if (pLayerParam->iMaxSpatialBitrate < pLayerParam->iSpatialBitrate) {    WelsLog (pLogCtx, WELS_LOG_ERROR,             "MaxSpatialBitrate (%d) should be larger than SpatialBitrate (%d), considering it as error setting",             pLayerParam->iMaxSpatialBitrate, pLayerParam->iSpatialBitrate);    return ENC_RETURN_UNSUPPORTED_PARA;  }  return ENC_RETURN_SUCCESS;} void CheckProfileSetting (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam, int32_t iLayer, EProfileIdc uiProfileIdc) {  SSpatialLayerConfig* pLayerInfo = &pParam->sSpatialLayers[iLayer];  pLayerInfo->uiProfileIdc = uiProfileIdc;  if ((iLayer == SPATIAL_LAYER_0) && (uiProfileIdc != PRO_BASELINE)) {    pLayerInfo->uiProfileIdc = PRO_BASELINE;    WelsLog (pLogCtx, WELS_LOG_WARNING, "doesn't support profile(%d),change to baseline profile",             uiProfileIdc);  }  if (iLayer > SPATIAL_LAYER_0) {    if ((uiProfileIdc != PRO_BASELINE) || (uiProfileIdc != PRO_SCALABLE_BASELINE)) {      pLayerInfo->uiProfileIdc = PRO_BASELINE;      WelsLog (pLogCtx, WELS_LOG_WARNING, "doesn't support profile(%d),change to baseline profile",               uiProfileIdc);    }  }}void CheckLevelSetting (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam, int32_t iLayer, ELevelIdc uiLevelIdc) {  SSpatialLayerConfig* pLayerInfo = &pParam->sSpatialLayers[iLayer];  pLayerInfo->uiLevelIdc = uiLevelIdc;  if (uiLevelIdc == LEVEL_UNKNOWN) {    pLayerInfo->uiLevelIdc = LEVEL_1_0;    WelsLog (pLogCtx, WELS_LOG_INFO, "change LEVEL_UNKNOWN to LEVEL_1_0");  } else if ((uiLevelIdc < LEVEL_1_0) || (uiLevelIdc > LEVEL_5_2)) {    pLayerInfo->uiLevelIdc = LEVEL_1_0;    WelsLog (pLogCtx, WELS_LOG_WARNING, "doesn't support level(%d) change to LEVEL_1_0", uiLevelIdc);  }}void CheckReferenceNumSetting (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam, int32_t iNumRef) {  int32_t iRefUpperBound = (pParam->iUsageType == CAMERA_VIDEO_REAL_TIME) ?                           MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA : MAX_REFERENCE_PICTURE_COUNT_NUM_SCREEN;  pParam->iNumRefFrame = iNumRef;  if ((iNumRef < MIN_REF_PIC_COUNT) || (iNumRef > iRefUpperBound)) {    pParam->iNumRefFrame = AUTO_REF_PIC_COUNT;    WelsLog (pLogCtx, WELS_LOG_WARNING,             "doesn't support the number of reference frame(%d) change to auto select mode", iNumRef);  }}/*! * \brief	validate checking in parameter configuration * \pParam	pParam		SWelsSvcCodingParam* * \return	successful - 0; otherwise none 0 for failed */int32_t ParamValidation (SLogContext* pLogCtx, SWelsSvcCodingParam* pCfg) {  const float fEpsn = 0.000001f;  int32_t i = 0;   assert (pCfg != NULL);   if ((pCfg->iUsageType != CAMERA_VIDEO_REAL_TIME) && (pCfg->iUsageType != SCREEN_CONTENT_REAL_TIME)) {    WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidation(),Invalid usage type = %d", pCfg->iUsageType);    return ENC_RETURN_UNSUPPORTED_PARA;  }  if (pCfg->iUsageType == SCREEN_CONTENT_REAL_TIME) {    if (pCfg->iSpatialLayerNum > 1) {      WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidation(),Invalid the number of Spatial layer(%d)for screen content",               pCfg->iSpatialLayerNum);      return ENC_RETURN_UNSUPPORTED_PARA;    }    if (pCfg->bEnableAdaptiveQuant) {      WelsLog (pLogCtx, WELS_LOG_WARNING,               "ParamValidation(), AdaptiveQuant(%d) is not supported yet for screen content, auto turned off",               pCfg->bEnableAdaptiveQuant);      pCfg->bEnableAdaptiveQuant = false;    }    if (pCfg->bEnableSceneChangeDetect == false) {      pCfg->bEnableSceneChangeDetect = true;      WelsLog (pLogCtx, WELS_LOG_WARNING,               "ParamValidation(), screen change detection should be turned on,change bEnableSceneChangeDetect as true");    }   }  if (pCfg->iSpatialLayerNum > 1) {    int32_t iFinalWidth = pCfg->sSpatialLayers[pCfg->iSpatialLayerNum - 1].iVideoWidth;    int32_t iFinalHeight = pCfg->sSpatialLayers[pCfg->iSpatialLayerNum - 1].iVideoHeight;    for (i = 0; i < (pCfg->iSpatialLayerNum - 1); i++) {      SSpatialLayerConfig* fDlp = &pCfg->sSpatialLayers[i];      if ((fDlp->iVideoWidth > iFinalWidth) || (fDlp->iVideoHeight > iFinalHeight)) {        WelsLog (pLogCtx, WELS_LOG_ERROR,                 "ParamValidation,Invalid resolution layer(%d) resolution(%d x %d) shoudl be less than the highest spatial layer resolution(%d x %d) ",                 i, fDlp->iVideoWidth, fDlp->iVideoHeight, iFinalWidth, iFinalHeight);        return ENC_RETURN_UNSUPPORTED_PARA;      }    }  }  for (i = 0; i < pCfg->iSpatialLayerNum; ++ i) {    SSpatialLayerInternal* fDlp = &pCfg->sDependencyLayers[i];    if (fDlp->fOutputFrameRate > fDlp->fInputFrameRate || (fDlp->fInputFrameRate >= -fEpsn        && fDlp->fInputFrameRate <= fEpsn)        || (fDlp->fOutputFrameRate >= -fEpsn && fDlp->fOutputFrameRate <= fEpsn)) {      WelsLog (pLogCtx, WELS_LOG_ERROR,               "Invalid settings in input frame rate(%.6f) or output frame rate(%.6f) of layer #%d config file..",               fDlp->fInputFrameRate, fDlp->fOutputFrameRate, i);      return ENC_RETURN_INVALIDINPUT;    }    if (UINT_MAX == GetLogFactor (fDlp->fOutputFrameRate, fDlp->fInputFrameRate)) {      WelsLog (pLogCtx, WELS_LOG_WARNING,               "AUTO CORRECT: Invalid settings in input frame rate(%.6f) and output frame rate(%.6f) of layer #%d config file: iResult of output frame rate divided by input frame rate should be power of 2(i.e,in/pOut=2^n). \n Auto correcting Output Framerate to Input Framerate %f!\n",               fDlp->fInputFrameRate, fDlp->fOutputFrameRate, i, fDlp->fInputFrameRate);      fDlp->fOutputFrameRate = fDlp->fInputFrameRate;    }  }   if ((pCfg->iRCMode != RC_OFF_MODE) && (pCfg->iRCMode != RC_QUALITY_MODE) && (pCfg->iRCMode != RC_BUFFERBASED_MODE)      && (pCfg->iRCMode != RC_BITRATE_MODE)) {    WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidation(),Invalid iRCMode = %d", pCfg->iRCMode);    return ENC_RETURN_UNSUPPORTED_PARA;  }  //bitrate setting validation  if (pCfg->iRCMode != RC_OFF_MODE) {    int32_t  iTotalBitrate = 0;    if (pCfg->iTargetBitrate <= 0) {      WelsLog (pLogCtx, WELS_LOG_ERROR, "Invalid bitrate settings in total configure, bitrate= %d", pCfg->iTargetBitrate);      return ENC_RETURN_INVALIDINPUT;    }    for (i = 0; i < pCfg->iSpatialLayerNum; ++ i) {      SSpatialLayerConfig* pSpatialLayer = &pCfg->sSpatialLayers[i];      iTotalBitrate += pSpatialLayer->iSpatialBitrate;       if (WelsBitRateVerification (pLogCtx, pSpatialLayer, i) != ENC_RETURN_SUCCESS)        return ENC_RETURN_INVALIDINPUT;    }    if (iTotalBitrate > pCfg->iTargetBitrate) {      WelsLog (pLogCtx, WELS_LOG_ERROR,               "Invalid settings in bitrate. the sum of each layer bitrate(%d) is larger than total bitrate setting(%d)",               iTotalBitrate, pCfg->iTargetBitrate);      return ENC_RETURN_INVALIDINPUT;    }    if ((pCfg->iRCMode == RC_QUALITY_MODE) || (pCfg->iRCMode == RC_BITRATE_MODE))      if (!pCfg->bEnableFrameSkip)        WelsLog (pLogCtx, WELS_LOG_WARNING,                 "bEnableFrameSkip = %d,bitrate can't be controlled for RC_QUALITY_MODE and RC_BITRATE_MODE without enabling skip frame.",                 pCfg->bEnableFrameSkip);  }  return WelsCheckRefFrameLimitation (pLogCtx, pCfg);}  int32_t ParamValidationExt (SLogContext* pLogCtx, SWelsSvcCodingParam* pCodingParam) {  int8_t i = 0;  int32_t iIdx = 0;   assert (pCodingParam != NULL);  if (NULL == pCodingParam)    return ENC_RETURN_INVALIDINPUT;   if ((pCodingParam->iUsageType != CAMERA_VIDEO_REAL_TIME) && (pCodingParam->iUsageType != SCREEN_CONTENT_REAL_TIME)) {    WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(),Invalid usage type = %d", pCodingParam->iUsageType);    return ENC_RETURN_UNSUPPORTED_PARA;  }  if ((pCodingParam->iUsageType == SCREEN_CONTENT_REAL_TIME) && (!pCodingParam->bIsLosslessLink      && pCodingParam->bEnableLongTermReference)) {    WelsLog (pLogCtx, WELS_LOG_WARNING,             "ParamValidationExt(), setting lossy link for LTR under screen, which is not supported yet! Auto disabled LTR!");    pCodingParam->bEnableLongTermReference = false;  }  if (pCodingParam->iSpatialLayerNum < 1 || pCodingParam->iSpatialLayerNum > MAX_DEPENDENCY_LAYER) {    WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), monitor invalid pCodingParam->iSpatialLayerNum: %d!",             pCodingParam->iSpatialLayerNum);    return ENC_RETURN_UNSUPPORTED_PARA;  }   if (pCodingParam->iTemporalLayerNum < 1 || pCodingParam->iTemporalLayerNum > MAX_TEMPORAL_LEVEL) {    WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), monitor invalid pCodingParam->iTemporalLayerNum: %d!",             pCodingParam->iTemporalLayerNum);    return ENC_RETURN_UNSUPPORTED_PARA;  }   if (pCodingParam->uiGopSize < 1 || pCodingParam->uiGopSize > MAX_GOP_SIZE) {    WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), monitor invalid pCodingParam->uiGopSize: %d!",             pCodingParam->uiGopSize);    return ENC_RETURN_UNSUPPORTED_PARA;  }    if (pCodingParam->uiIntraPeriod && pCodingParam->uiIntraPeriod < pCodingParam->uiGopSize) {    WelsLog (pLogCtx, WELS_LOG_ERROR,             "ParamValidationExt(), uiIntraPeriod(%d) should be not less than that of uiGopSize(%d) or -1 specified!",             pCodingParam->uiIntraPeriod, pCodingParam->uiGopSize);    return ENC_RETURN_UNSUPPORTED_PARA;  }   if (pCodingParam->uiIntraPeriod && (pCodingParam->uiIntraPeriod & (pCodingParam->uiGopSize - 1)) != 0) {    WelsLog (pLogCtx, WELS_LOG_ERROR,             "ParamValidationExt(), uiIntraPeriod(%d) should be multiple of uiGopSize(%d) or -1 specified!",             pCodingParam->uiIntraPeriod, pCodingParam->uiGopSize);    return ENC_RETURN_UNSUPPORTED_PARA;  }  if (pCodingParam->iLoopFilterDisableIdc < 0 || pCodingParam->iLoopFilterDisableIdc > 6) {    WelsLog (pLogCtx, WELS_LOG_ERROR,             "ParamValidationExt(), iLoopFilterDisableIdc(%d) must be between 0 and 6",             pCodingParam->iLoopFilterDisableIdc);    return ENC_RETURN_UNSUPPORTED_PARA;  }    //about iMultipleThreadIdc, bDeblockingParallelFlag, iLoopFilterDisableIdc, & uiSliceMode  // (1) Single Thread  //	if (THREAD==1)//single thread  //		no parallel_deblocking: bDeblockingParallelFlag = 0;  // (2) Multi Thread: see uiSliceMode decision  if (pCodingParam->iMultipleThreadIdc == 1) {    //now is single thread. no parallel deblocking, set flag=0    pCodingParam->bDeblockingParallelFlag = false;  } else {    pCodingParam->bDeblockingParallelFlag = true;  }   for (i = 0; i < pCodingParam->iSpatialLayerNum; ++ i) {    SSpatialLayerConfig* pSpatialLayer = &pCodingParam->sSpatialLayers[i];    const int32_t kiPicWidth = pSpatialLayer->iVideoWidth;    const int32_t kiPicHeight = pSpatialLayer->iVideoHeight;    uint32_t iMbWidth		= 0;    uint32_t iMbHeight		= 0;    int32_t iMbNumInFrame		= 0;    uint32_t iMaxSliceNum		= MAX_SLICES_NUM;    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,               kiPicWidth, kiPicHeight);      return ENC_RETURN_UNSUPPORTED_PARA;    }    if ((kiPicWidth & 0x0F) != 0 || (kiPicHeight & 0x0F) != 0) {      WelsLog (pLogCtx, WELS_LOG_ERROR,               "ParamValidationExt(), in layer #%d iWidth x iHeight(%d x %d) both should be multiple of 16, can not support with arbitrary size currently!",               i, kiPicWidth, kiPicHeight);      return ENC_RETURN_UNSUPPORTED_PARA;    }     if (pSpatialLayer->sSliceCfg.uiSliceMode >= SM_RESERVED) {      WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceMode (%d) settings!",               pSpatialLayer->sSliceCfg.uiSliceMode);      return ENC_RETURN_UNSUPPORTED_PARA;    }    if ((pCodingParam->uiMaxNalSize != 0) && (pSpatialLayer->sSliceCfg.uiSliceMode != SM_DYN_SLICE)) {      WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceMode (%d) settings!,MaxNalSize = %d",               pSpatialLayer->sSliceCfg.uiSliceMode, pCodingParam->uiMaxNalSize);      return ENC_RETURN_UNSUPPORTED_PARA;    }    CheckProfileSetting (pLogCtx, pCodingParam, i, pSpatialLayer->uiProfileIdc);    CheckLevelSetting (pLogCtx, pCodingParam, i, pSpatialLayer->uiLevelIdc);    //check pSlice settings under multi-pSlice    if (kiPicWidth <= 16 && kiPicHeight <= 16) {      //only have one MB, set to single_slice      pSpatialLayer->sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;    }    switch (pSpatialLayer->sSliceCfg.uiSliceMode) {    case SM_SINGLE_SLICE:      pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum = 1;      pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 0;      for (iIdx = 0; iIdx < MAX_SLICES_NUM; iIdx++) {        pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceMbNum[iIdx] = 0;      }      break;    case SM_FIXEDSLCNUM_SLICE: {      pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 0;       iMbWidth	= (kiPicWidth + 15) >> 4;      iMbHeight	= (kiPicHeight + 15) >> 4;      iMbNumInFrame = iMbWidth * iMbHeight;      iMaxSliceNum = MAX_SLICES_NUM;      if (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum <= 0          || pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum > iMaxSliceNum) {        WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceNum (%d) settings!",                 pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum);        return ENC_RETURN_UNSUPPORTED_PARA;      }      if (pSpatialLayer->sSliceCfg.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->sSliceCfg.sSliceArgument.uiSliceNum);        pSpatialLayer->sSliceCfg.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->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);      } else if (!CheckFixedSliceNumMultiSliceSetting (iMbNumInFrame,                 &pSpatialLayer->sSliceCfg.sSliceArgument)) {	// verify interleave mode settings        //check uiSliceMbNum with current uiSliceNum        WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceMbNum (%d) settings!",                 pSpatialLayer->sSliceCfg.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->sSliceCfg.uiSliceMode	= SM_SINGLE_SLICE;        pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum	= 1;        break;      }    }    break;    case SM_AUTO_SLICE: {      pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 0;    }    break;    case SM_RASTER_SLICE: {      pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 0;       iMbWidth	= (kiPicWidth + 15) >> 4;      iMbHeight	= (kiPicHeight + 15) >> 4;      iMbNumInFrame = iMbWidth * iMbHeight;      iMaxSliceNum = MAX_SLICES_NUM;      if (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceMbNum[0] <= 0) {        WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceMbNum (%d) settings!",                 pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceMbNum[0]);        return ENC_RETURN_UNSUPPORTED_PARA;      }       if (!CheckRasterMultiSliceSetting (iMbNumInFrame,                                         &pSpatialLayer->sSliceCfg.sSliceArgument)) {	// verify interleave mode settings        WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceMbNum (%d) settings!",                 pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceMbNum[0]);        return ENC_RETURN_UNSUPPORTED_PARA;      }      if (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum <= 0          || pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum > iMaxSliceNum) {	// verify interleave mode settings        WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceNum (%d) in SM_RASTER_SLICE settings!",                 pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum);        return ENC_RETURN_UNSUPPORTED_PARA;      }      if (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum == 1) {        WelsLog (pLogCtx, WELS_LOG_WARNING,                 "ParamValidationExt(), pSlice setting for SM_RASTER_SLICE now turn to SM_SINGLE_SLICE!");        pSpatialLayer->sSliceCfg.uiSliceMode	= SM_SINGLE_SLICE;        break;      }      if ((pCodingParam->iRCMode != RC_OFF_MODE) && pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum > 1) {        WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), WARNING: GOM based RC do not support SM_RASTER_SLICE!");      }      // 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->sSliceCfg.uiSliceMode	= SM_SINGLE_SLICE;        pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum	= 1;        break;      }    }    break;    case SM_ROWMB_SLICE: {      pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 0;       iMbWidth	= (kiPicWidth + 15) >> 4;      iMbHeight	= (kiPicHeight + 15) >> 4;      iMaxSliceNum = MAX_SLICES_NUM;      if (iMbHeight > iMaxSliceNum) {        WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceNum (%d) settings more than MAX!", iMbHeight);        return ENC_RETURN_UNSUPPORTED_PARA;      }      pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum	= iMbHeight;       if (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum <= 0) {        WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceNum (%d) settings!",                 pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum);        return ENC_RETURN_UNSUPPORTED_PARA;      }      if (!CheckRowMbMultiSliceSetting (iMbWidth,                                        &pSpatialLayer->sSliceCfg.sSliceArgument)) {	// verify interleave mode settings        WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceMbNum (%d) settings!",                 pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceMbNum[0]);        return ENC_RETURN_UNSUPPORTED_PARA;      }    }    break;    case SM_DYN_SLICE: {      iMbWidth	= (kiPicWidth + 15) >> 4;      iMbHeight	= (kiPicHeight + 15) >> 4;      if (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceSizeConstraint <= 0) {        WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid iSliceSize (%d) settings!",                 pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceSizeConstraint);        return ENC_RETURN_UNSUPPORTED_PARA;      }       if (pCodingParam->uiMaxNalSize <= NAL_HEADER_ADD_0X30BYTES) {        WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiMaxNalSize (%d) settings!",                 pCodingParam->uiMaxNalSize);        return ENC_RETURN_UNSUPPORTED_PARA;      }       if (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceSizeConstraint > (pCodingParam->uiMaxNalSize -          NAL_HEADER_ADD_0X30BYTES)) {

Lines 1–500 of 4261.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t