4898 lines · 209.0 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)      || (static_cast<float> (pLayerParam->iSpatialBitrate) < pLayerParam->fFrameRate)) {    WelsLog (pLogCtx, WELS_LOG_ERROR, "Invalid bitrate settings in layer %d, bitrate= %d at FrameRate(%f)", iLayerId,             pLayerParam->iSpatialBitrate, pLayerParam->fFrameRate);    return ENC_RETURN_UNSUPPORTED_PARA;  }   // deal with LEVEL_MAX_BR and MAX_BR setting  const int32_t iLevelMaxBitrate = (pLayerParam->uiLevelIdc != LEVEL_UNKNOWN) ? (g_ksLevelLimits[pLayerParam->uiLevelIdc -                                   1].uiMaxBR * CpbBrNalFactor) : UNSPECIFIED_BIT_RATE;  const int32_t iLevel52MaxBitrate = g_ksLevelLimits[LEVEL_NUMBER - 1].uiMaxBR * CpbBrNalFactor;  if (UNSPECIFIED_BIT_RATE != iLevelMaxBitrate) {    if ((pLayerParam->iMaxSpatialBitrate == UNSPECIFIED_BIT_RATE)        || (pLayerParam->iMaxSpatialBitrate > iLevel52MaxBitrate)) {      pLayerParam->iMaxSpatialBitrate = iLevelMaxBitrate;      WelsLog (pLogCtx, WELS_LOG_INFO,               "Current MaxSpatialBitrate is invalid (UNSPECIFIED_BIT_RATE or larger than LEVEL5_2) but level setting is valid, set iMaxSpatialBitrate to %d from level (%d)",               pLayerParam->iMaxSpatialBitrate, pLayerParam->uiLevelIdc);    } else if (pLayerParam->iMaxSpatialBitrate > iLevelMaxBitrate) {      ELevelIdc iCurLevel = pLayerParam->uiLevelIdc;      WelsAdjustLevel (pLayerParam);      WelsLog (pLogCtx, WELS_LOG_INFO,               "LevelIdc is changed from (%d) to (%d) according to the iMaxSpatialBitrate(%d)",               iCurLevel, pLayerParam->uiLevelIdc, pLayerParam->iMaxSpatialBitrate);    }  } else if ((pLayerParam->iMaxSpatialBitrate != UNSPECIFIED_BIT_RATE)             && (pLayerParam->iMaxSpatialBitrate > iLevel52MaxBitrate)) {    // no level limitation, just need to check if iMaxSpatialBitrate is too big from reasonable    WelsLog (pLogCtx, WELS_LOG_WARNING,             "No LevelIdc setting and iMaxSpatialBitrate (%d) is considered too big to be valid, changed to UNSPECIFIED_BIT_RATE",             pLayerParam->iMaxSpatialBitrate);    pLayerParam->iMaxSpatialBitrate = UNSPECIFIED_BIT_RATE;  }   // deal with iSpatialBitrate and iMaxSpatialBitrate setting  if (pLayerParam->iMaxSpatialBitrate != UNSPECIFIED_BIT_RATE) {    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);    } else 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_5_2) {    WelsLog (pLogCtx, WELS_LOG_INFO, "change unexpected levelidc(%d) setting to LEVEL_UNKNOWN", pLayerInfo->uiLevelIdc);    pLayerInfo->uiLevelIdc = LEVEL_UNKNOWN;  }}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) should be less than the highest spatial layer resolution(%d x %d) ",                 i, fDlp->iVideoWidth, fDlp->iVideoHeight, iFinalWidth, iFinalHeight);        return ENC_RETURN_UNSUPPORTED_PARA;      }    }  }   if (!CheckInRangeCloseOpen (pCfg->iLoopFilterDisableIdc, DEBLOCKING_IDC_0, DEBLOCKING_IDC_2 + 1) ||      !CheckInRangeCloseOpen (pCfg->iLoopFilterAlphaC0Offset, DEBLOCKING_OFFSET_MINUS, DEBLOCKING_OFFSET + 1) ||      !CheckInRangeCloseOpen (pCfg->iLoopFilterBetaOffset, DEBLOCKING_OFFSET_MINUS, DEBLOCKING_OFFSET + 1)) {    WelsLog (pLogCtx, WELS_LOG_ERROR,             "ParamValidation, Invalid iLoopFilterDisableIdc(%d) or iLoopFilterAlphaC0Offset(%d) or iLoopFilterBetaOffset(%d)!",             pCfg->iLoopFilterDisableIdc, pCfg->iLoopFilterAlphaC0Offset, pCfg->iLoopFilterBetaOffset);    return ENC_RETURN_UNSUPPORTED_PARA;  }   for (i = 0; i < pCfg->iSpatialLayerNum; ++ i) {    SSpatialLayerInternal* fDlp = &pCfg->sDependencyLayers[i];    SSpatialLayerConfig* pConfig = &pCfg->sSpatialLayers[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;      pConfig->fFrameRate = fDlp->fOutputFrameRate;    }  }   if ((pCfg->iRCMode != RC_OFF_MODE) && (pCfg->iRCMode != RC_QUALITY_MODE) && (pCfg->iRCMode != RC_BUFFERBASED_MODE)      && (pCfg->iRCMode != RC_BITRATE_MODE) && (pCfg->iRCMode != RC_TIMESTAMP_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) || (pCfg->iRCMode == RC_TIMESTAMP_MODE))      if (!pCfg->bEnableFrameSkip)        WelsLog (pLogCtx, WELS_LOG_WARNING,                 "bEnableFrameSkip = %d,bitrate can't be controlled for RC_QUALITY_MODE,RC_BITRATE_MODE and RC_TIMESTAMP_MODE without enabling skip frame.",                 pCfg->bEnableFrameSkip);  }  // ref-frames validation  if (((pCfg->iUsageType == CAMERA_VIDEO_REAL_TIME) || (pCfg->iUsageType == SCREEN_CONTENT_REAL_TIME))      ? WelsCheckRefFrameLimitationNumRefFirst (pLogCtx, pCfg)      : WelsCheckRefFrameLimitationLevelIdcFirst (pLogCtx, pCfg)) {    WelsLog (pLogCtx, WELS_LOG_ERROR, "WelsCheckRefFrameLimitation failed");    return ENC_RETURN_INVALIDINPUT;  }  return ENC_RETURN_SUCCESS;}  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;  }   //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;  }   // eSpsPpsIdStrategy checkings  if (pCodingParam->iSpatialLayerNum > 1 && (!pCodingParam->bSimulcastAVC)      && (SPS_LISTING & pCodingParam->eSpsPpsIdStrategy)) {    WelsLog (pLogCtx, WELS_LOG_WARNING,             "ParamValidationExt(), eSpsPpsIdStrategy setting (%d) with multiple svc SpatialLayers (%d) not supported! eSpsPpsIdStrategy adjusted to CONSTANT_ID",             pCodingParam->eSpsPpsIdStrategy, pCodingParam->iSpatialLayerNum);    pCodingParam->eSpsPpsIdStrategy = CONSTANT_ID;  }  if (pCodingParam->iUsageType == SCREEN_CONTENT_REAL_TIME && (SPS_LISTING & pCodingParam->eSpsPpsIdStrategy)) {    WelsLog (pLogCtx, WELS_LOG_WARNING,             "ParamValidationExt(), eSpsPpsIdStrategy setting (%d) with iUsageType (%d) not supported! eSpsPpsIdStrategy adjusted to CONSTANT_ID",             pCodingParam->eSpsPpsIdStrategy, pCodingParam->iUsageType);    pCodingParam->eSpsPpsIdStrategy = CONSTANT_ID;  }   if (pCodingParam->bSimulcastAVC && (SPS_LISTING & pCodingParam->eSpsPpsIdStrategy)) {    WelsLog (pLogCtx, WELS_LOG_INFO,             "ParamValidationExt(), eSpsPpsIdStrategy(%d) under bSimulcastAVC(%d) not supported yet, adjusted to INCREASING_ID",             pCodingParam->eSpsPpsIdStrategy, pCodingParam->bSimulcastAVC);    pCodingParam->eSpsPpsIdStrategy = INCREASING_ID;  }   if (pCodingParam->bSimulcastAVC && pCodingParam->bPrefixNalAddingCtrl) {    WelsLog (pLogCtx, WELS_LOG_INFO,             "ParamValidationExt(), bSimulcastAVC(%d) is not compatible with bPrefixNalAddingCtrl(%d) true, adjusted bPrefixNalAddingCtrl to false",             pCodingParam->eSpsPpsIdStrategy, pCodingParam->bSimulcastAVC);    pCodingParam->bPrefixNalAddingCtrl = false;  }   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) {

Lines 1–500 of 4898.

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