1376 lines · 56.3 KB · C++
RawDownload
/*! * \copy *     Copyright (c)  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. * */ #include "wels_preprocess.h"#include "picture_handle.h"#include "encoder_context.h"#include "utils.h"#include "encoder.h" namespace WelsEnc {   //***** entry API declaration ************************************************************************// int32_t WelsInitScaledPic (SWelsSvcCodingParam* pParam,  Scaled_Picture*  pScaledPic, CMemoryAlign* pMemoryAlign);bool  JudgeNeedOfScaling (SWelsSvcCodingParam* pParam, Scaled_Picture* pScaledPic);void    FreeScaledPic (Scaled_Picture*  pScaledPic, CMemoryAlign* pMemoryAlign);void  WelsMoveMemory_c (uint8_t* pDstY, uint8_t* pDstU, uint8_t* pDstV,  int32_t iDstStrideY, int32_t iDstStrideUV,                        uint8_t* pSrcY, uint8_t* pSrcU, uint8_t* pSrcV, int32_t iSrcStrideY, int32_t iSrcStrideUV, int32_t iWidth,                        int32_t iHeight); //******* table definition ***********************************************************************//const uint8_t g_kuiRefTemporalIdx[MAX_TEMPORAL_LEVEL][MAX_GOP_SIZE] = {  {  0, }, // 0  {  0,  0, }, // 1  {  0,  0,  0,  1, }, // 2  {  0,  0,  0,  2,  0,  1,  1,  2, }, // 3}; const int32_t g_kiPixMapSizeInBits = sizeof (uint8_t) * 8;  inline  void   WelsUpdateSpatialIdxMap (sWelsEncCtx* pEncCtx, int32_t iPos, SPicture* pPic, int32_t iDidx) {  pEncCtx->sSpatialIndexMap[iPos].pSrc = pPic;  pEncCtx->sSpatialIndexMap[iPos].iDid = iDidx;}  /*****************************************************************************   implement of the interface****************************************************************************/ CWelsPreProcess::CWelsPreProcess (sWelsEncCtx* pEncCtx) {  m_pInterfaceVp = NULL;  m_bInitDone = false;  m_pEncCtx = pEncCtx;  memset (&m_sScaledPicture, 0, sizeof (m_sScaledPicture));  memset (m_pSpatialPic, 0, sizeof (m_pSpatialPic));  memset (m_uiSpatialLayersInTemporal, 0, sizeof (m_uiSpatialLayersInTemporal));  memset (m_uiSpatialPicNum, 0, sizeof (m_uiSpatialPicNum));} CWelsPreProcess::~CWelsPreProcess() {  FreeScaledPic (&m_sScaledPicture,  m_pEncCtx->pMemAlign);  WelsPreprocessDestroy();} int32_t CWelsPreProcess::WelsPreprocessCreate() {  if (m_pInterfaceVp == NULL) {    WelsCreateVpInterface ((void**) &m_pInterfaceVp, WELSVP_INTERFACE_VERION);    if (!m_pInterfaceVp)      goto exit;  } else    goto exit;   return 0; exit:  WelsPreprocessDestroy();  return 1;} int32_t CWelsPreProcess::WelsPreprocessDestroy() {  WelsDestroyVpInterface (m_pInterfaceVp, WELSVP_INTERFACE_VERION);  m_pInterfaceVp = NULL;   return 0;} int32_t CWelsPreProcess::WelsPreprocessReset (sWelsEncCtx* pCtx) {  int32_t iRet = -1;   if (pCtx) {    FreeScaledPic (&m_sScaledPicture, pCtx->pMemAlign);    iRet = InitLastSpatialPictures (pCtx);    iRet = WelsInitScaledPic (pCtx->pSvcParam, &m_sScaledPicture, pCtx->pMemAlign);  }   return iRet;} int32_t CWelsPreProcess::AllocSpatialPictures (sWelsEncCtx* pCtx, SWelsSvcCodingParam* pParam) {  CMemoryAlign* pMa             = pCtx->pMemAlign;  const int32_t kiDlayerCount   = pParam->iSpatialLayerNum;  int32_t iDlayerIndex          = 0;   // spatial pictures  iDlayerIndex = 0;  do {    const int32_t kiPicWidth = pParam->sSpatialLayers[iDlayerIndex].iVideoWidth;    const int32_t kiPicHeight   = pParam->sSpatialLayers[iDlayerIndex].iVideoHeight;    const uint8_t kuiLayerInTemporal = 2 + WELS_MAX (pParam->sDependencyLayers[iDlayerIndex].iHighestTemporalId, 1);    const uint8_t kuiRefNumInTemporal = kuiLayerInTemporal + pParam->iLTRRefNum;    uint8_t i = 0;     m_uiSpatialPicNum[iDlayerIndex] = kuiRefNumInTemporal;    do {      SPicture* pPic = AllocPicture (pMa, kiPicWidth, kiPicHeight, false, 0);      WELS_VERIFY_RETURN_IF (1, (NULL == pPic))      m_pSpatialPic[iDlayerIndex][i] = pPic;      ++ i;    } while (i < kuiRefNumInTemporal);     if (pParam->iUsageType == SCREEN_CONTENT_REAL_TIME)      m_uiSpatialLayersInTemporal[iDlayerIndex] = 1;    else      m_uiSpatialLayersInTemporal[iDlayerIndex] = kuiLayerInTemporal;     ++ iDlayerIndex;  } while (iDlayerIndex < kiDlayerCount);   return 0;} void CWelsPreProcess::FreeSpatialPictures (sWelsEncCtx* pCtx) {  CMemoryAlign* pMa = pCtx->pMemAlign;  int32_t j = 0;  while (j < pCtx->pSvcParam->iSpatialLayerNum) {    uint8_t i = 0;    uint8_t uiRefNumInTemporal = m_uiSpatialPicNum[j];     while (i < uiRefNumInTemporal) {      if (NULL != m_pSpatialPic[j][i]) {        FreePicture (pMa, &m_pSpatialPic[j][i]);      }      ++ i;    }    m_uiSpatialLayersInTemporal[j] = 0;    ++ j;  }} int32_t CWelsPreProcess::BuildSpatialPicList (sWelsEncCtx* pCtx, const SSourcePicture* kpSrcPic) {  SWelsSvcCodingParam* pSvcParam = pCtx->pSvcParam;  int32_t iSpatialNum = 0;   if (!m_bInitDone) {    if (WelsPreprocessCreate() != 0)      return -1;     //init source width and height    pSvcParam->SUsedPicRect.iLeft = 0;    pSvcParam->SUsedPicRect.iTop  = 0;    pSvcParam->SUsedPicRect.iWidth = ((kpSrcPic->iPicWidth >> 1) << 1);    pSvcParam->SUsedPicRect.iHeight = ((kpSrcPic->iPicHeight >> 1) << 1);    if ((pSvcParam->SUsedPicRect.iWidth < 16) || ((pSvcParam->SUsedPicRect.iHeight < 16))) {      WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "Don't support width(%d) or height(%d) which is less than 16 ",               pSvcParam->SUsedPicRect.iWidth, pSvcParam->SUsedPicRect.iHeight);      return -1;    }    if (WelsPreprocessReset (pCtx) != 0)      return -1;     m_iAvaliableRefInSpatialPicList = pSvcParam->iNumRefFrame;     m_bInitDone = true;  }   if (m_pInterfaceVp == NULL)    return -1;   pCtx->pVaa->bSceneChangeFlag = pCtx->pVaa->bIdrPeriodFlag = false;   iSpatialNum = SingleLayerPreprocess (pCtx, kpSrcPic, &m_sScaledPicture);   return iSpatialNum;} int32_t CWelsPreProcess::AnalyzeSpatialPic (sWelsEncCtx* pCtx, const int32_t kiDidx) {  SWelsSvcCodingParam* pSvcParam = pCtx->pSvcParam;  bool bNeededMbAq = (pSvcParam->bEnableAdaptiveQuant && (pCtx->eSliceType == P_SLICE));  bool bCalculateBGD = (pCtx->eSliceType == P_SLICE && pSvcParam->bEnableBackgroundDetection);  SSpatialLayerInternal* pParamInternal = &pSvcParam->sDependencyLayers[kiDidx];  int32_t iCurTemporalIdx  = m_uiSpatialLayersInTemporal[kiDidx] - 1;   int32_t iRefTemporalIdx = (int32_t)g_kuiRefTemporalIdx[pSvcParam->iDecompStages][pParamInternal->iCodingIndex &                            (pSvcParam->uiGopSize - 1)];  if (pCtx->uiTemporalId == 0 && pCtx->pLtr[pCtx->uiDependencyId].bReceivedT0LostFlag)    iRefTemporalIdx = m_uiSpatialLayersInTemporal[kiDidx] + pCtx->pVaa->uiValidLongTermPicIdx;   SPicture* pCurPic = m_pSpatialPic[kiDidx][iCurTemporalIdx];  bool bCalculateVar = (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == I_SLICE);   if (pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {    SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (m_pEncCtx->pVaa);    SRefInfoParam* BestRefCandidateParam = (pCtx->bCurFrameMarkedAsSceneLtr) ? (& (pVaaExt->sVaaLtrBestRefCandidate[0])) :                                           (& (pVaaExt->sVaaStrBestRefCandidate[0]));    SPicture* pRefPic = m_pSpatialPic[0][BestRefCandidateParam->iSrcListIdx];     VaaCalculation (pCtx->pVaa, pCurPic, pRefPic, false, bCalculateVar, bCalculateBGD);     if (pSvcParam->bEnableBackgroundDetection) {      BackgroundDetection (pCtx->pVaa, pCurPic, pRefPic, bCalculateBGD && pRefPic->iPictureType != I_SLICE);    }    if (bNeededMbAq) {      AdaptiveQuantCalculation (pCtx->pVaa, pCurPic, pRefPic);    }  } else {    SPicture* pRefPic = m_pSpatialPic[kiDidx][iRefTemporalIdx];    SPicture* pLastPic = m_pLastSpatialPicture[kiDidx][0];    bool bCalculateSQDiff = ((pLastPic->pData[0] == pRefPic->pData[0]) && bNeededMbAq);    bool bCalculateVar = (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == I_SLICE);     VaaCalculation (pCtx->pVaa, pCurPic, pRefPic, bCalculateSQDiff, bCalculateVar, bCalculateBGD);     if (pSvcParam->bEnableBackgroundDetection) {      BackgroundDetection (pCtx->pVaa, pCurPic, pRefPic, bCalculateBGD && pRefPic->iPictureType != I_SLICE);    }     if (bNeededMbAq) {      SPicture* pCurPic = m_pLastSpatialPicture[kiDidx][1];      SPicture* pRefPic = m_pLastSpatialPicture[kiDidx][0];      //printf("pCurPicDid = %d,pCurPicTid = %d,pRefPicDid = %d,pRefPicTid = %d,kiDidx = %d,pCurPic = %x,pRefPic = %x,bbCurPic = %x\n",      //         pCurPic->uiSpatialId,pCurPic->uiTemporalId,pCurPic->uiSpatialId,pCurPic->uiTemporalId,kiDidx,pCurPic,pRefPic,m_pSpatialPic[kiDidx][iCurTemporalIdx]);        AdaptiveQuantCalculation (pCtx->pVaa, pCurPic, pRefPic);    }  }  return 0;} int32_t CWelsPreProcess::GetCurPicPosition (const int32_t kiDidx) {  return (m_uiSpatialLayersInTemporal[kiDidx] - 1);} int32_t CWelsPreProcess::UpdateSpatialPictures (sWelsEncCtx* pCtx, SWelsSvcCodingParam* pParam,    const int8_t iCurTid, const int32_t kiDidx) {  if (pCtx->pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME)    return 0;   WelsExchangeSpatialPictures (&m_pLastSpatialPicture[kiDidx][1], &m_pLastSpatialPicture[kiDidx][0]);   const int32_t kiCurPos = GetCurPicPosition (kiDidx);  if (iCurTid < kiCurPos || pParam->iDecompStages == 0) {    if ((iCurTid >= MAX_TEMPORAL_LEVEL) || (kiCurPos > MAX_TEMPORAL_LEVEL)) {      InitLastSpatialPictures (pCtx);      return 1;    }    if (pCtx->bRefOfCurTidIsLtr[kiDidx][iCurTid]) {      const int32_t kiAvailableLtrPos = m_uiSpatialLayersInTemporal[kiDidx] + pCtx->pVaa->uiMarkLongTermPicIdx;      WelsExchangeSpatialPictures (&m_pSpatialPic[kiDidx][kiAvailableLtrPos],                                   &m_pSpatialPic[kiDidx][iCurTid]);      pCtx->bRefOfCurTidIsLtr[kiDidx][iCurTid] = false;    }    WelsExchangeSpatialPictures (&m_pSpatialPic[kiDidx][kiCurPos],                                 &m_pSpatialPic[kiDidx][iCurTid]);    }  return 0;}  /**   SingleLayerPreprocess: down sampling if applicable*  @return: exact number of spatial layers need to encoder indeed*/bool CWelsPreProcess::BuildSpatialLayer (sWelsEncCtx* pCtx, const SSourcePicture* kpSrc, int32_t iDependencyId) {  SWelsSvcCodingParam* pSvcParam    = pCtx->pSvcParam;  int32_t iMaxDid = pSvcParam->iSpatialLayerNum - 1;  SSpatialPicIndex* pSpatialIndexMap = &pCtx->sSpatialIndexMap[0];  SSpatialLayerConfig* pDlayerParam = &pSvcParam->sSpatialLayers[iDependencyId];  SSpatialLayerInternal* pDlayerParamInternal = &pSvcParam->sDependencyLayers[iDependencyId];  int32_t iTemporalId = pDlayerParamInternal->uiCodingIdx2TemporalId[pDlayerParamInternal->iCodingIndex &                        (pSvcParam->uiGopSize - 1)];    if (iTemporalId != INVALID_TEMPORAL_ID) {    if (iDependencyId == iMaxDid) {      return true;    } else {      int32_t iPicturePos               = m_uiSpatialLayersInTemporal[iDependencyId] - 1;      Scaled_Picture*  pScaledPicture = &m_sScaledPicture;       int32_t iTargetWidth              = pDlayerParam->iVideoWidth;      int32_t iTargetHeight             = pDlayerParam->iVideoHeight;       SPicture* pSrcPic                 = (pSpatialIndexMap + iMaxDid)->pSrc;; // large      SPicture* pDstPic                 = m_pSpatialPic[iDependencyId][iPicturePos]; // small       int32_t iSrcWidth                 = pSrcPic->iWidthInPixel;      int32_t iSrcHeight                = pSrcPic->iHeightInPixel;      int32_t iShrinkWidth = pScaledPicture->iScaledWidth[iDependencyId];      int32_t iShrinkHeight = pScaledPicture->iScaledHeight[iDependencyId];      DownsamplePadding (pSrcPic, pDstPic, iSrcWidth, iSrcHeight, iShrinkWidth, iShrinkHeight, iTargetWidth, iTargetHeight,                         true);      WelsUpdateSpatialIdxMap (pCtx, iDependencyId, pDstPic, iDependencyId);      m_pLastSpatialPicture[iDependencyId][1] = m_pSpatialPic[iDependencyId][iPicturePos];      return true;    }  }  return false;} int32_t CWelsPreProcess::SingleLayerPreprocess (sWelsEncCtx* pCtx, const SSourcePicture* kpSrc,    Scaled_Picture* pScaledPicture) {  SWelsSvcCodingParam* pSvcParam    = pCtx->pSvcParam;  int8_t  iDependencyId             = pSvcParam->iSpatialLayerNum - 1;  int32_t iPicturePos               = m_uiSpatialLayersInTemporal[iDependencyId] - 1;   SPicture* pSrcPic                 = NULL; // large  SPicture* pDstPic                 = NULL; // small  SSpatialLayerConfig* pDlayerParam = NULL;  SSpatialLayerInternal* pDlayerParamInternal = NULL;  int32_t iSpatialNum               = 0;  int32_t iSrcWidth                 = 0;  int32_t iSrcHeight                = 0;  int32_t iTargetWidth              = 0;  int32_t iTargetHeight             = 0;  int32_t iTemporalId = 0;   pDlayerParamInternal = &pSvcParam->sDependencyLayers[iDependencyId];  pDlayerParam = &pSvcParam->sSpatialLayers[iDependencyId];  iTargetWidth   = pDlayerParam->iVideoWidth;  iTargetHeight  = pDlayerParam->iVideoHeight;  iTemporalId    = pDlayerParamInternal->uiCodingIdx2TemporalId[pDlayerParamInternal->iCodingIndex &                   (pSvcParam->uiGopSize - 1)];  iSrcWidth   = pSvcParam->SUsedPicRect.iWidth;  iSrcHeight  = pSvcParam->SUsedPicRect.iHeight;   if (pSvcParam->uiIntraPeriod)    pCtx->pVaa->bIdrPeriodFlag = (1 + pDlayerParamInternal->iFrameIndex >= (int32_t)pSvcParam->uiIntraPeriod) ? true :                                 false;   pSrcPic = pScaledPicture->pScaledInputPicture ? pScaledPicture->pScaledInputPicture :            m_pSpatialPic[iDependencyId][iPicturePos];  WelsMoveMemoryWrapper (pSvcParam, pSrcPic, kpSrc, iSrcWidth, iSrcHeight);   if (pSvcParam->bEnableDenoise)    BilateralDenoising (pSrcPic, iSrcWidth, iSrcHeight);   // different scaling in between input picture and dst highest spatial picture.  int32_t iShrinkWidth  = iSrcWidth;  int32_t iShrinkHeight = iSrcHeight;  pDstPic = pSrcPic;  if (pScaledPicture->pScaledInputPicture) {    // for highest downsampling    pDstPic = m_pSpatialPic[iDependencyId][iPicturePos];    iShrinkWidth = pScaledPicture->iScaledWidth[iDependencyId];    iShrinkHeight = pScaledPicture->iScaledHeight[iDependencyId];  }  DownsamplePadding (pSrcPic, pDstPic, iSrcWidth, iSrcHeight, iShrinkWidth, iShrinkHeight, iTargetWidth, iTargetHeight,                     false);  if (pSvcParam->bEnableSceneChangeDetect && !pCtx->pVaa->bIdrPeriodFlag) {    if (pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {      pCtx->pVaa->eSceneChangeIdc = (pDlayerParamInternal->bEncCurFrmAsIdrFlag ? LARGE_CHANGED_SCENE :                                     DetectSceneChangeScreen (pCtx,                                         pDstPic));      pCtx->pVaa->bSceneChangeFlag = (LARGE_CHANGED_SCENE == pCtx->pVaa->eSceneChangeIdc);    } else {      if ((!pDlayerParamInternal->bEncCurFrmAsIdrFlag)          && ! (pDlayerParamInternal->iCodingIndex & (pSvcParam->uiGopSize - 1))) {        SPicture* pRefPic = pCtx->pLtr[iDependencyId].bReceivedT0LostFlag ?                            m_pSpatialPic[iDependencyId][m_uiSpatialLayersInTemporal[iDependencyId] +                                pCtx->pVaa->uiValidLongTermPicIdx] : m_pLastSpatialPicture[iDependencyId][0];         pCtx->pVaa->bSceneChangeFlag = DetectSceneChange (pDstPic, pRefPic);      }    }  }   WelsUpdateSpatialIdxMap (pCtx, iDependencyId, pDstPic, iDependencyId);  m_pLastSpatialPicture[iDependencyId][1] = m_pSpatialPic[iDependencyId][iPicturePos];   if (iTemporalId != INVALID_TEMPORAL_ID) {    ++ iSpatialNum;  }  -- iDependencyId;  if (pSvcParam->iSpatialLayerNum > 1) {    while (iDependencyId >= 0) {      pDlayerParamInternal = &pSvcParam->sDependencyLayers[iDependencyId];      iTemporalId = pDlayerParamInternal->uiCodingIdx2TemporalId[pDlayerParamInternal->iCodingIndex &                    (pSvcParam->uiGopSize - 1)];       if ((iTemporalId != INVALID_TEMPORAL_ID)) {        ++ iSpatialNum;      }      -- iDependencyId;    }  }  return iSpatialNum; }/*! * \brief   Whether input picture need be scaled? */bool JudgeNeedOfScaling (SWelsSvcCodingParam* pParam, Scaled_Picture* pScaledPicture) {  const int32_t kiInputPicWidth  = pParam->SUsedPicRect.iWidth;  const int32_t kiInputPicHeight = pParam->SUsedPicRect.iHeight;  const int32_t kiDstPicWidth    = pParam->sDependencyLayers[pParam->iSpatialLayerNum - 1].iActualWidth;  const int32_t kiDstPicHeight   = pParam->sDependencyLayers[pParam->iSpatialLayerNum - 1].iActualHeight;  bool bNeedDownsampling = true;   int32_t iSpatialIdx = pParam->iSpatialLayerNum - 1;   if (kiDstPicWidth >= kiInputPicWidth && kiDstPicHeight >= kiInputPicHeight) {    iSpatialIdx --;  // highest D layer do not need downsampling    bNeedDownsampling = false;  }   for (; iSpatialIdx >= 0; iSpatialIdx --) {    SSpatialLayerInternal* pCurLayer = &pParam->sDependencyLayers[iSpatialIdx];    int32_t iCurDstWidth             = pCurLayer->iActualWidth;    int32_t iCurDstHeight            = pCurLayer->iActualHeight;    int32_t iInputWidthXDstHeight    = kiInputPicWidth * iCurDstHeight;    int32_t iInputHeightXDstWidth    = kiInputPicHeight * iCurDstWidth;     if (iInputWidthXDstHeight > iInputHeightXDstWidth) {      pScaledPicture->iScaledWidth[iSpatialIdx] = WELS_MAX (iCurDstWidth, 4);      pScaledPicture->iScaledHeight[iSpatialIdx] = WELS_MAX (iInputHeightXDstWidth / kiInputPicWidth, 4);    } else {      pScaledPicture->iScaledWidth[iSpatialIdx] = WELS_MAX (iInputWidthXDstHeight / kiInputPicHeight, 4);      pScaledPicture->iScaledHeight[iSpatialIdx] = WELS_MAX (iCurDstHeight, 4);    }  }   return bNeedDownsampling;} int32_t  WelsInitScaledPic (SWelsSvcCodingParam* pParam,  Scaled_Picture*  pScaledPicture, CMemoryAlign* pMemoryAlign) {  bool bInputPicNeedScaling = JudgeNeedOfScaling (pParam, pScaledPicture);  if (bInputPicNeedScaling) {    pScaledPicture->pScaledInputPicture = AllocPicture (pMemoryAlign, pParam->SUsedPicRect.iWidth,                                          pParam->SUsedPicRect.iHeight, false, 0);    if (pScaledPicture->pScaledInputPicture == NULL)      return -1;  }  return 0;} void  FreeScaledPic (Scaled_Picture*  pScaledPicture, CMemoryAlign* pMemoryAlign) {  if (pScaledPicture->pScaledInputPicture) {    FreePicture (pMemoryAlign, &pScaledPicture->pScaledInputPicture);    pScaledPicture->pScaledInputPicture = NULL;  }} int32_t CWelsPreProcess::InitLastSpatialPictures (sWelsEncCtx* pCtx) {  SWelsSvcCodingParam* pParam   = pCtx->pSvcParam;  const int32_t kiDlayerCount   = pParam->iSpatialLayerNum;  int32_t iDlayerIndex          = 0;  if (pParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {    for (; iDlayerIndex < MAX_DEPENDENCY_LAYER; iDlayerIndex++) {      m_pLastSpatialPicture[iDlayerIndex][0] = m_pLastSpatialPicture[iDlayerIndex][1] = NULL;    }  } else {    for (; iDlayerIndex < kiDlayerCount; iDlayerIndex++) {      const int32_t kiLayerInTemporal = m_uiSpatialLayersInTemporal[iDlayerIndex];      m_pLastSpatialPicture[iDlayerIndex][0] = m_pSpatialPic[iDlayerIndex][kiLayerInTemporal - 2];      m_pLastSpatialPicture[iDlayerIndex][1] = NULL;    }    for (; iDlayerIndex < MAX_DEPENDENCY_LAYER; iDlayerIndex++) {      m_pLastSpatialPicture[iDlayerIndex][0] = m_pLastSpatialPicture[iDlayerIndex][1] = NULL;    }  }  return 0;}

Lines 1–500 of 1376.

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