3901 lines · 163.2 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 "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" namespace WelsSVCEnc {  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                                );  /*! * \brief	validate checking in parameter configuration * \pParam	pParam		SWelsSvcCodingParam* * \return	successful - 0; otherwise none 0 for failed */int32_t ParamValidation (SLogContext* pLogCtx, SWelsSvcCodingParam* pCfg) {  float fMaxFrameRate = 0.0f;  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\n", pCfg->iUsageType);    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..\n",               fDlp->fInputFrameRate, fDlp->fOutputFrameRate, i);      return ENC_RETURN_INVALIDINPUT;    }    if (UINT_MAX == GetLogFactor (fDlp->fOutputFrameRate, fDlp->fInputFrameRate)) {      WelsLog (pLogCtx, WELS_LOG_ERROR,               "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",               fDlp->fInputFrameRate, fDlp->fOutputFrameRate, i);      return ENC_RETURN_INVALIDINPUT;    }  }   for (i = 0; i < pCfg->iSpatialLayerNum; ++ i) {    SSpatialLayerInternal* fDlp = &pCfg->sDependencyLayers[i];    if (fDlp->fInputFrameRate > fMaxFrameRate)      fMaxFrameRate	= fDlp->fInputFrameRate;  }   if (fMaxFrameRate > fEpsn && (fMaxFrameRate - pCfg->fMaxFrameRate > fEpsn                                || fMaxFrameRate - pCfg->fMaxFrameRate < -fEpsn)) {    pCfg->fMaxFrameRate	= fMaxFrameRate;  }//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\n", pCfg->iTargetBitrate);      return ENC_RETURN_INVALIDINPUT;    }    for (i = 0; i < pCfg->iSpatialLayerNum; ++ i) {      SSpatialLayerConfig* pSpatialLayer = &pCfg->sSpatialLayers[i];      iTotalBitrate += pSpatialLayer->iSpatialBitrate;      if (pSpatialLayer->iSpatialBitrate <= 0) {        WelsLog (pLogCtx, WELS_LOG_ERROR, "Invalid bitrate settings in layer %d, bitrate= %d\n", i,                 pSpatialLayer->iSpatialBitrate);        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)\n",               iTotalBitrate, pCfg->iTargetBitrate);      return ENC_RETURN_INVALIDINPUT;    }   }  return ENC_RETURN_SUCCESS;}  int32_t ParamValidationExt (SLogContext* pCtx, 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 (pCtx, WELS_LOG_ERROR, "ParamValidationExt(),Invalid usage type = %d", pCodingParam->iUsageType);    return ENC_RETURN_UNSUPPORTED_PARA;  }  if (pCodingParam->iSpatialLayerNum < 1 || pCodingParam->iSpatialLayerNum > MAX_DEPENDENCY_LAYER) {    WelsLog (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), monitor invalid pCodingParam->iSpatialLayerNum: %d!\n",             pCodingParam->iSpatialLayerNum);    return ENC_RETURN_UNSUPPORTED_PARA;  }   if (pCodingParam->iTemporalLayerNum < 1 || pCodingParam->iTemporalLayerNum > MAX_TEMPORAL_LEVEL) {    WelsLog (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), monitor invalid pCodingParam->iTemporalLayerNum: %d!\n",             pCodingParam->iTemporalLayerNum);    return ENC_RETURN_UNSUPPORTED_PARA;  }   if (pCodingParam->uiGopSize < 1 || pCodingParam->uiGopSize > MAX_GOP_SIZE) {    WelsLog (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), monitor invalid pCodingParam->uiGopSize: %d!\n",             pCodingParam->uiGopSize);    return ENC_RETURN_UNSUPPORTED_PARA;  }    if (pCodingParam->uiIntraPeriod && pCodingParam->uiIntraPeriod < pCodingParam->uiGopSize) {    WelsLog (pCtx, WELS_LOG_ERROR,             "ParamValidationExt(), uiIntraPeriod(%d) should be not less than that of uiGopSize(%d) or -1 specified!\n",             pCodingParam->uiIntraPeriod, pCodingParam->uiGopSize);    return ENC_RETURN_UNSUPPORTED_PARA;  }   if (pCodingParam->uiIntraPeriod && (pCodingParam->uiIntraPeriod & (pCodingParam->uiGopSize - 1)) != 0) {    WelsLog (pCtx, WELS_LOG_ERROR,             "ParamValidationExt(), uiIntraPeriod(%d) should be multiple of uiGopSize(%d) or -1 specified!\n",             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;  }   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) {      WelsLog (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid %d x %d in dependency layer settings!\n", kiPicWidth,               kiPicHeight);      return ENC_RETURN_UNSUPPORTED_PARA;    }    if ((kiPicWidth & 0x0F) != 0 || (kiPicHeight & 0x0F) != 0) {      WelsLog (pCtx, 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!\n",               i, kiPicWidth, kiPicHeight);      return ENC_RETURN_UNSUPPORTED_PARA;    }     if (pSpatialLayer->sSliceCfg.uiSliceMode >= SM_RESERVED) {      WelsLog (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceMode (%d) settings!\n",               pSpatialLayer->sSliceCfg.uiSliceMode);      return ENC_RETURN_UNSUPPORTED_PARA;    }    if ((pCodingParam->uiMaxNalSize != 0) && (pSpatialLayer->sSliceCfg.uiSliceMode != SM_DYN_SLICE)) {      WelsLog (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceMode (%d) settings!,MaxNalSize = %d\n",               pSpatialLayer->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      pSpatialLayer->sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;    }    switch (pSpatialLayer->sSliceCfg.uiSliceMode) {    case SM_SINGLE_SLICE:      pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum = 1;      pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 0;      pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum = 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 (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceNum (%d) settings!\n",                 pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum);        return ENC_RETURN_UNSUPPORTED_PARA;      }      if (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum == 1) {        WelsLog (pCtx, WELS_LOG_DEBUG,                 "ParamValidationExt(), uiSliceNum(%d) you set for SM_FIXEDSLCNUM_SLICE, now turn to SM_SINGLE_SLICE type!\n",                 pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum);        pSpatialLayer->sSliceCfg.uiSliceMode	= SM_SINGLE_SLICE;        break;      }      if (pCodingParam->iRCMode != RC_OFF_MODE) {	// multiple slices verify with gom        //check uiSliceNum        GomValidCheckSliceNum (iMbWidth, iMbHeight, &pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum);        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        WelsLog (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceMbNum (%d) settings!\n",                 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 (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceMbNum (%d) settings!\n",                 pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceMbNum[0]);        return ENC_RETURN_UNSUPPORTED_PARA;      }       if (!CheckRasterMultiSliceSetting (iMbNumInFrame,                                         &pSpatialLayer->sSliceCfg.sSliceArgument)) {	// verify interleave mode settings        WelsLog (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceMbNum (%d) settings!\n",                 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 (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceNum (%d) in SM_RASTER_SLICE settings!\n",                 pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum);        return ENC_RETURN_UNSUPPORTED_PARA;      }      if (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum == 1) {        WelsLog (pCtx, WELS_LOG_ERROR,                 "ParamValidationExt(), pSlice setting for SM_RASTER_SLICE now turn to SM_SINGLE_SLICE!\n");        pSpatialLayer->sSliceCfg.uiSliceMode	= SM_SINGLE_SLICE;        break;      }      if ((pCodingParam->iRCMode != RC_OFF_MODE) && pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum > 1) {        WelsLog (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), WARNING: GOM based RC do not support SM_RASTER_SLICE!\n");      }      // 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 (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceNum (%d) settings more than MAX!\n", iMbHeight);        return ENC_RETURN_UNSUPPORTED_PARA;      }      pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum	= iMbHeight;       if (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum <= 0) {        WelsLog (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceNum (%d) settings!\n",                 pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum);        return ENC_RETURN_UNSUPPORTED_PARA;      }      if (!CheckRowMbMultiSliceSetting (iMbWidth,                                        &pSpatialLayer->sSliceCfg.sSliceArgument)) {	// verify interleave mode settings        WelsLog (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceMbNum (%d) settings!\n",                 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 (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid iSliceSize (%d) settings!\n",                 pSpatialLayer->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 (pSpatialLayer->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",                 pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceSizeConstraint, pCodingParam->uiMaxNalSize);        pSpatialLayer->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) {        pSpatialLayer->sSliceCfg.uiSliceMode	= SM_SINGLE_SLICE;        pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum	= 1;        break;      }    }    break;    default: {      WelsLog (pCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceMode (%d) settings!\n",               pCodingParam->sSpatialLayers[0].sSliceCfg.uiSliceMode);      return ENC_RETURN_UNSUPPORTED_PARA;     }    break;    }  }   return ParamValidation (pCtx, pCodingParam);}  void WelsEncoderApplyFrameRate (SWelsSvcCodingParam* pParam) {  SSpatialLayerInternal* pLayerParam;  const float kfEpsn = 0.000001f;  const int32_t kiNumLayer = pParam->iSpatialLayerNum;  int32_t i;  const float kfMaxFrameRate = pParam->fMaxFrameRate;  float fRatio;  float fTargetOutputFrameRate;   //set input frame rate to each layer  for (i = 0; i < kiNumLayer; i++) {    pLayerParam = & (pParam->sDependencyLayers[i]);     fRatio = pLayerParam->fOutputFrameRate / pLayerParam->fInputFrameRate;    if ((kfMaxFrameRate - pLayerParam->fInputFrameRate) > kfEpsn        || (kfMaxFrameRate - pLayerParam->fInputFrameRate) < -kfEpsn) {      pLayerParam->fInputFrameRate = kfMaxFrameRate;      fTargetOutputFrameRate = kfMaxFrameRate * fRatio;      pLayerParam->fOutputFrameRate = (fTargetOutputFrameRate >= 6) ? fTargetOutputFrameRate : (pLayerParam->fInputFrameRate);      //TODO:{Sijia} from design, there is no sense to have temporal layer when under 6fps even with such setting?    }  }}  void WelsEncoderApplyBitRate (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam, int iLayer) {  //TODO (Sijia):  this is a temporary solution which keep the ratio between layers  //but it is also possible to fulfill the bitrate of lower layer first   SSpatialLayerConfig* pLayerParam;  const int32_t iNumLayers = pParam->iSpatialLayerNum;  int32_t i, iOrigTotalBitrate = 0;  if (iLayer == SPATIAL_LAYER_ALL) {    if (pParam->iMaxBitrate < pParam->iTargetBitrate) {      WelsLog (pLogCtx, WELS_LOG_WARNING,               "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_BITRATE,overall settting,TargetBitrate = %d,iMaxBitrate = %d\n",               pParam->iTargetBitrate, pParam->iMaxBitrate);      pParam->iMaxBitrate  = pParam->iTargetBitrate;    }    //read old BR    for (i = 0; i < iNumLayers; i++) {      iOrigTotalBitrate += pParam->sSpatialLayers[i].iSpatialBitrate;    }    //write new BR    float fRatio = 0.0;    for (i = 0; i < iNumLayers; i++) {      pLayerParam = & (pParam->sSpatialLayers[i]);      fRatio = pLayerParam->iSpatialBitrate / (static_cast<float> (iOrigTotalBitrate));      pLayerParam->iSpatialBitrate = static_cast<int32_t> (pParam->iTargetBitrate * fRatio);    }  } else {    if (pParam->sSpatialLayers[iLayer].iMaxSpatialBitrate < pParam->sSpatialLayers[iLayer].iSpatialBitrate) {      WelsLog (pLogCtx, WELS_LOG_WARNING,               "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_BITRATE,iLayer = %d,iTargetBitrate = %d,iMaxBitrate = %d\n",               iLayer, pParam->sSpatialLayers[iLayer].iSpatialBitrate, pParam->sSpatialLayers[iLayer].iMaxSpatialBitrate);      pParam->sSpatialLayers[iLayer].iMaxSpatialBitrate = pParam->sSpatialLayers[iLayer].iSpatialBitrate;    }   }}/*! * \brief	acquire count number of layers and NALs based on configurable paramters dependency * \pParam	pCtx				sWelsEncCtx* * \pParam	pParam			SWelsSvcCodingParam* * \pParam	pCountLayers	pointer of count number of layers indeed * \pParam	iCountNals		pointer of count number of nals indeed * \return	0 - successful; otherwise failed */static inline int32_t AcquireLayersNals (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pParam, int32_t* pCountLayers,    int32_t* pCountNals) {  int32_t iCountNumLayers		= 0;  int32_t iCountNumNals			= 0;  int32_t iNumDependencyLayers	= 0;  int32_t iDIndex 				= 0;   if (NULL == pParam || NULL == ppCtx || NULL == *ppCtx)    return 1;   iNumDependencyLayers	= pParam->iSpatialLayerNum;   do {    SSpatialLayerConfig* pDLayer = &pParam->sSpatialLayers[iDIndex];//		pDLayer->ptr_cfg = pParam;    int32_t iOrgNumNals = iCountNumNals;     //Note: Sep. 2010    //Review this part and suggest no change, since the memory over-use    //(1) counts little to the overall performance    //(2) should not be critial even under mobile case    if (SM_DYN_SLICE == pDLayer->sSliceCfg.uiSliceMode) {      iCountNumNals += MAX_SLICES_NUM;      // plus prefix NALs      if (iDIndex == 0)        iCountNumNals += MAX_SLICES_NUM;      // MAX_SLICES_NUM < MAX_LAYER_NUM_OF_FRAME ensured at svc_enc_slice_segment.h      assert (iCountNumNals - iOrgNumNals <= MAX_NAL_UNITS_IN_LAYER);    } else { /*if ( SM_SINGLE_SLICE != pDLayer->sSliceCfg.uiSliceMode )*/      const int32_t kiNumOfSlice = GetInitialSliceNum ((pDLayer->iVideoWidth + 0x0f) >> 4,                                   (pDLayer->iVideoHeight + 0x0f) >> 4,

Lines 1–500 of 3901.

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