From 6b707ffb14d63751712976ea3eba8a214b21bb5f Mon Sep 17 00:00:00 2001 From: ruil2 Date: Thu, 17 Apr 2014 17:33:44 +0800 Subject: [PATCH] add complexity calculation in workflow --- codec/encoder/core/inc/rc.h | 2 +- codec/encoder/core/inc/wels_preprocess.h | 5 +- codec/encoder/core/src/encoder_ext.cpp | 4 + codec/encoder/core/src/wels_preprocess.cpp | 163 ++++++++++++++------- 4 files changed, 114 insertions(+), 60 deletions(-) diff --git a/codec/encoder/core/inc/rc.h b/codec/encoder/core/inc/rc.h index 7ece26de..84026294 100644 --- a/codec/encoder/core/inc/rc.h +++ b/codec/encoder/core/inc/rc.h @@ -51,7 +51,7 @@ namespace WelsSVCEnc { //trace #define GOM_TRACE_FLAG 1 - +#define GOM_H_SCC 8 #define WELS_RC_DISABLE 0 #define WELS_RC_GOM 1 diff --git a/codec/encoder/core/inc/wels_preprocess.h b/codec/encoder/core/inc/wels_preprocess.h index b2e5f18d..6a8761d5 100644 --- a/codec/encoder/core/inc/wels_preprocess.h +++ b/codec/encoder/core/inc/wels_preprocess.h @@ -127,6 +127,9 @@ class CWelsPreProcess { int32_t AnalyzeSpatialPic (sWelsEncCtx* pEncCtx, const int32_t kiDIdx); int32_t UpdateSpatialPictures(sWelsEncCtx* pEncCtx, SWelsSvcCodingParam* pParam, const int8_t iCurTid, const int32_t d_idx); int32_t GetRefCandidateLtrIndex(int32_t iRefIdx); + void AnalyzePictureComplexity (sWelsEncCtx* pCtx, SPicture* pCurPicture, SPicture* pRefPicture, + const int32_t kiDependencyId, const bool kbCalculateBGD); + private: int32_t WelsPreprocessCreate(); int32_t WelsPreprocessDestroy(); @@ -144,8 +147,6 @@ class CWelsPreProcess { bool bCalculateVar, bool bCalculateBGD); void BackgroundDetection (SVAAFrameInfo* pVaaInfo, SPicture* pCurPicture, SPicture* pRefPicture, bool bDetectFlag); void AdaptiveQuantCalculation (SVAAFrameInfo* pVaaInfo, SPicture* pCurPicture, SPicture* pRefPicture); - void AnalyzePictureComplexity (sWelsEncCtx* pCtx, SPicture* pCurPicture, SPicture* pRefPicture, - const int32_t kiDependencyId, const bool kbCalculateBGD); void Padding (uint8_t* pSrcY, uint8_t* pSrcU, uint8_t* pSrcV, int32_t iStrideY, int32_t iStrideUV, int32_t iActualWidth, int32_t iPaddingWidth, int32_t iActualHeight, int32_t iPaddingHeight); void SetRefMbType (sWelsEncCtx* pCtx, uint32_t** pRefMbTypeArray, int32_t iRefPicType); diff --git a/codec/encoder/core/src/encoder_ext.cpp b/codec/encoder/core/src/encoder_ext.cpp index d7c0d4d2..99e2e287 100644 --- a/codec/encoder/core/src/encoder_ext.cpp +++ b/codec/encoder/core/src/encoder_ext.cpp @@ -3002,6 +3002,10 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour #ifdef LONG_TERM_REF_DUMP dump_ref (pCtx); #endif + if((pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME)&&(pSvcParam->iRCMode != RC_OFF_MODE)) + pCtx->pVpp->AnalyzePictureComplexity(pCtx,pCtx->pEncPic,((pCtx->eSliceType == P_SLICE)&&(pCtx->iNumRef0>0))?pCtx->pRefList0[0]:NULL, + iCurDid,pSvcParam->bEnableBackgroundDetection); + WelsUpdateRefSyntax (pCtx, pCtx->iPOC, eFrameType); //get reordering syntax used for writing slice header and transmit to encoder. PrefetchReferencePicture (pCtx, eFrameType); // update reference picture for current pDq layer diff --git a/codec/encoder/core/src/wels_preprocess.cpp b/codec/encoder/core/src/wels_preprocess.cpp index c0ef9492..28b4c8b7 100644 --- a/codec/encoder/core/src/wels_preprocess.cpp +++ b/codec/encoder/core/src/wels_preprocess.cpp @@ -140,7 +140,7 @@ int32_t CWelsPreProcess::AllocSpatialPictures (sWelsEncCtx* pCtx, SWelsSvcCoding ++ i; } while (i < kuiRefNumInTemporal); - if(pParam->iUsageType == SCREEN_CONTENT_REAL_TIME) + if (pParam->iUsageType == SCREEN_CONTENT_REAL_TIME) m_uiSpatialLayersInTemporal[iDlayerIndex] = 1; else m_uiSpatialLayersInTemporal[iDlayerIndex] = kuiLayerInTemporal; @@ -210,20 +210,20 @@ int32_t CWelsPreProcess::AnalyzeSpatialPic (sWelsEncCtx* pCtx, const int32_t kiD 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 (m_pEncCtx->pVaa); - SRefInfoParam* BestRefCandidateParam =&(pVaaExt->sVaaStrBestRefCandidate[0]); - SPicture *pRefPic= m_pSpatialPic[0][BestRefCandidateParam->iSrcListIdx]; + if (pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) { + SVAAFrameInfoExt* pVaaExt = static_cast (m_pEncCtx->pVaa); + SRefInfoParam* BestRefCandidateParam = & (pVaaExt->sVaaStrBestRefCandidate[0]); + SPicture* pRefPic = m_pSpatialPic[0][BestRefCandidateParam->iSrcListIdx]; - VaaCalculation (pCtx->pVaa, pCurPic, pRefPic, false, bCalculateVar, bCalculateBGD); + VaaCalculation (pCtx->pVaa, pCurPic, pRefPic, false, bCalculateVar, bCalculateBGD); - if (pSvcParam->bEnableBackgroundDetection) { - BackgroundDetection (pCtx->pVaa, pCurPic, pRefPic, bCalculateBGD && pRefPic->iPictureType != I_SLICE); - } + if (pSvcParam->bEnableBackgroundDetection) { + BackgroundDetection (pCtx->pVaa, pCurPic, pRefPic, bCalculateBGD && pRefPic->iPictureType != I_SLICE); + } - if (bNeededMbAq) { - AdaptiveQuantCalculation (pCtx->pVaa, pCurPic, pRefPic); - } + if (bNeededMbAq) { + AdaptiveQuantCalculation (pCtx->pVaa, pCurPic, pRefPic); + } } else { SPicture* pRefPic = m_pSpatialPic[kiDidx][iRefTemporalIdx]; SPicture* pLastPic = m_pLastSpatialPicture[kiDidx][0]; @@ -242,21 +242,16 @@ int32_t CWelsPreProcess::AnalyzeSpatialPic (sWelsEncCtx* pCtx, const int32_t kiD AdaptiveQuantCalculation (pCtx->pVaa, pCurPic, pRefPic); } - - if(pSvcParam->iUsageType != SCREEN_CONTENT_REAL_TIME){ - if (pSvcParam->iRCMode != RC_OFF_MODE) { - AnalyzePictureComplexity (pCtx, pCurPic, pRefPic, kiDidx, bCalculateBGD); - } - WelsExchangeSpatialPictures (&m_pLastSpatialPicture[kiDidx][1], &m_pLastSpatialPicture[kiDidx][0]); - } + AnalyzePictureComplexity (pCtx, pCurPic, pRefPic, kiDidx, bCalculateBGD); + WelsExchangeSpatialPictures (&m_pLastSpatialPicture[kiDidx][1], &m_pLastSpatialPicture[kiDidx][0]); } return 0; } int32_t CWelsPreProcess::UpdateSpatialPictures (sWelsEncCtx* pCtx, SWelsSvcCodingParam* pParam, const int8_t iCurTid, const int32_t d_idx) { - if(pCtx->pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) - return 0; + if (pCtx->pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) + return 0; if (iCurTid < m_uiSpatialLayersInTemporal[d_idx] - 1 || pParam->iDecompStages == 0) { if ((iCurTid >= MAX_TEMPORAL_LEVEL) || (m_uiSpatialLayersInTemporal[d_idx] - 1 > MAX_TEMPORAL_LEVEL)) { InitLastSpatialPictures (pCtx); @@ -723,39 +718,35 @@ void CWelsPreProcess::SetRefMbType (sWelsEncCtx* pCtx, uint32_t** pRefMbTypeArra void CWelsPreProcess::AnalyzePictureComplexity (sWelsEncCtx* pCtx, SPicture* pCurPicture, SPicture* pRefPicture, const int32_t kiDependencyId, const bool bCalculateBGD) { SWelsSvcCodingParam* pSvcParam = pCtx->pSvcParam; - SVAAFrameInfo* pVaaInfo = pCtx->pVaa; - - SComplexityAnalysisParam* sComplexityAnalysisParam = & (pVaaInfo->sComplexityAnalysisParam); - SWelsSvcRc* SWelsSvcRc = &pCtx->pWelsSvcRc[kiDependencyId]; int32_t iComplexityAnalysisMode = 0; - if (pSvcParam->iRCMode == RC_QUALITY_MODE && pCtx->eSliceType == P_SLICE) { - iComplexityAnalysisMode = FRAME_SAD; - } else if (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == P_SLICE) { - iComplexityAnalysisMode = GOM_SAD; - } else if (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == I_SLICE) { - iComplexityAnalysisMode = GOM_VAR; - } else { + if (pSvcParam->iRCMode == RC_OFF_MODE) return; - } + if (pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) { + SVAAFrameInfoExt* pVaaExt = static_cast (pCtx->pVaa); + SComplexityAnalysisScreenParam* sComplexityAnalysisParam = &pVaaExt->sComplexityScreenParam; + SWelsSvcRc* pWelsSvcRc = &pCtx->pWelsSvcRc[kiDependencyId]; - sComplexityAnalysisParam->iComplexityAnalysisMode = iComplexityAnalysisMode; - sComplexityAnalysisParam->pCalcResult = & (pVaaInfo->sVaaCalcInfo); - sComplexityAnalysisParam->pBackgroundMbFlag = pVaaInfo->pVaaBackgroundMbFlag; - SetRefMbType (pCtx, & (sComplexityAnalysisParam->uiRefMbType), pRefPicture->iPictureType); - sComplexityAnalysisParam->iCalcBgd = bCalculateBGD; - sComplexityAnalysisParam->iFrameComplexity = 0; + if (pCtx->eSliceType == P_SLICE) + iComplexityAnalysisMode = GOM_SAD; + else if (pCtx->eSliceType == I_SLICE) + iComplexityAnalysisMode = GOM_VAR; + else + return; - memset (SWelsSvcRc->pGomForegroundBlockNum, 0, SWelsSvcRc->iGomSize * sizeof (int32_t)); - if (iComplexityAnalysisMode != FRAME_SAD) - memset (SWelsSvcRc->pCurrentFrameGomSad, 0, SWelsSvcRc->iGomSize * sizeof (int32_t)); + memset (pWelsSvcRc->pGomForegroundBlockNum, 0, pWelsSvcRc->iGomSize * sizeof (int32_t)); + memset (pWelsSvcRc->pCurrentFrameGomSad, 0, pWelsSvcRc->iGomSize * sizeof (int32_t)); - sComplexityAnalysisParam->pGomComplexity = SWelsSvcRc->pCurrentFrameGomSad; - sComplexityAnalysisParam->pGomForegroundBlockNum = SWelsSvcRc->pGomForegroundBlockNum; - sComplexityAnalysisParam->iMbNumInGom = SWelsSvcRc->iNumberMbGom; + sComplexityAnalysisParam->iFrameComplexity = 0; + sComplexityAnalysisParam->pGomComplexity = pWelsSvcRc->pCurrentFrameGomSad; + sComplexityAnalysisParam->iGomNumInFrame = pWelsSvcRc->iGomSize; + sComplexityAnalysisParam->iIdrFlag = (pCtx->eSliceType == I_SLICE); + sComplexityAnalysisParam->iMbRowInGom = GOM_H_SCC; + sComplexityAnalysisParam->sScrollResult.bScrollDetectFlag = false; + sComplexityAnalysisParam->sScrollResult.iScrollMvX = 0; + sComplexityAnalysisParam->sScrollResult.iScrollMvY = 0; - { - int32_t iMethodIdx = METHOD_COMPLEXITY_ANALYSIS; + const int32_t iMethodIdx = METHOD_COMPLEXITY_ANALYSIS_SCREEN; SPixMap sSrcPixMap; SPixMap sRefPixMap; memset (&sSrcPixMap, 0, sizeof (SPixMap)); @@ -769,17 +760,76 @@ void CWelsPreProcess::AnalyzePictureComplexity (sWelsEncCtx* pCtx, SPicture* pCu sSrcPixMap.sRect.iRectHeight = pCurPicture->iHeightInPixel; sSrcPixMap.eFormat = VIDEO_FORMAT_I420; - sRefPixMap.pPixel[0] = pRefPicture->pData[0]; - sRefPixMap.iSizeInBits = g_kiPixMapSizeInBits; - sRefPixMap.iStride[0] = pRefPicture->iLineSize[0]; - sRefPixMap.sRect.iRectWidth = pRefPicture->iWidthInPixel; - sRefPixMap.sRect.iRectHeight = pRefPicture->iHeightInPixel; - sRefPixMap.eFormat = VIDEO_FORMAT_I420; + if (pRefPicture != NULL) { + sRefPixMap.pPixel[0] = pRefPicture->pData[0]; + sRefPixMap.iSizeInBits = g_kiPixMapSizeInBits; + sRefPixMap.iStride[0] = pRefPicture->iLineSize[0]; + sRefPixMap.sRect.iRectWidth = pRefPicture->iWidthInPixel; + sRefPixMap.sRect.iRectHeight = pRefPicture->iHeightInPixel; + sRefPixMap.eFormat = VIDEO_FORMAT_I420; + } iRet = m_pInterfaceVp->Set (iMethodIdx, (void*)sComplexityAnalysisParam); iRet = m_pInterfaceVp->Process (iMethodIdx, &sSrcPixMap, &sRefPixMap); if (iRet == 0) m_pInterfaceVp->Get (iMethodIdx, (void*)sComplexityAnalysisParam); + + } else { + SVAAFrameInfo* pVaaInfo = pCtx->pVaa; + SComplexityAnalysisParam* sComplexityAnalysisParam = & (pVaaInfo->sComplexityAnalysisParam); + SWelsSvcRc* SWelsSvcRc = &pCtx->pWelsSvcRc[kiDependencyId]; + + if (pSvcParam->iRCMode == RC_QUALITY_MODE && pCtx->eSliceType == P_SLICE) { + iComplexityAnalysisMode = FRAME_SAD; + } else if (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == P_SLICE) { + iComplexityAnalysisMode = GOM_SAD; + } else if (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == I_SLICE) { + iComplexityAnalysisMode = GOM_VAR; + } else { + return; + } + sComplexityAnalysisParam->iComplexityAnalysisMode = iComplexityAnalysisMode; + sComplexityAnalysisParam->pCalcResult = & (pVaaInfo->sVaaCalcInfo); + sComplexityAnalysisParam->pBackgroundMbFlag = pVaaInfo->pVaaBackgroundMbFlag; + SetRefMbType (pCtx, & (sComplexityAnalysisParam->uiRefMbType), pRefPicture->iPictureType); + sComplexityAnalysisParam->iCalcBgd = bCalculateBGD; + sComplexityAnalysisParam->iFrameComplexity = 0; + + memset (SWelsSvcRc->pGomForegroundBlockNum, 0, SWelsSvcRc->iGomSize * sizeof (int32_t)); + if (iComplexityAnalysisMode != FRAME_SAD) + memset (SWelsSvcRc->pCurrentFrameGomSad, 0, SWelsSvcRc->iGomSize * sizeof (int32_t)); + + sComplexityAnalysisParam->pGomComplexity = SWelsSvcRc->pCurrentFrameGomSad; + sComplexityAnalysisParam->pGomForegroundBlockNum = SWelsSvcRc->pGomForegroundBlockNum; + sComplexityAnalysisParam->iMbNumInGom = SWelsSvcRc->iNumberMbGom; + + { + int32_t iMethodIdx = METHOD_COMPLEXITY_ANALYSIS; + SPixMap sSrcPixMap; + SPixMap sRefPixMap; + memset (&sSrcPixMap, 0, sizeof (SPixMap)); + memset (&sRefPixMap, 0, sizeof (SPixMap)); + int32_t iRet = 0; + + sSrcPixMap.pPixel[0] = pCurPicture->pData[0]; + sSrcPixMap.iSizeInBits = g_kiPixMapSizeInBits; + sSrcPixMap.iStride[0] = pCurPicture->iLineSize[0]; + sSrcPixMap.sRect.iRectWidth = pCurPicture->iWidthInPixel; + sSrcPixMap.sRect.iRectHeight = pCurPicture->iHeightInPixel; + sSrcPixMap.eFormat = VIDEO_FORMAT_I420; + + sRefPixMap.pPixel[0] = pRefPicture->pData[0]; + sRefPixMap.iSizeInBits = g_kiPixMapSizeInBits; + sRefPixMap.iStride[0] = pRefPicture->iLineSize[0]; + sRefPixMap.sRect.iRectWidth = pRefPicture->iWidthInPixel; + sRefPixMap.sRect.iRectHeight = pRefPicture->iHeightInPixel; + sRefPixMap.eFormat = VIDEO_FORMAT_I420; + + iRet = m_pInterfaceVp->Set (iMethodIdx, (void*)sComplexityAnalysisParam); + iRet = m_pInterfaceVp->Process (iMethodIdx, &sSrcPixMap, &sRefPixMap); + if (iRet == 0) + m_pInterfaceVp->Get (iMethodIdx, (void*)sComplexityAnalysisParam); + } } } @@ -1007,12 +1057,11 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi return static_cast (iVaaFrameSceneChangeIdc); } -int32_t CWelsPreProcess::GetRefCandidateLtrIndex(int32_t iRefIdx) -{ +int32_t CWelsPreProcess::GetRefCandidateLtrIndex (int32_t iRefIdx) { const int32_t iTargetDid = m_pEncCtx->pSvcParam->iSpatialLayerNum - 1; SVAAFrameInfoExt* pVaaExt = static_cast (m_pEncCtx->pVaa); - SRefInfoParam* BestRefCandidateParam =&(pVaaExt->sVaaStrBestRefCandidate[iRefIdx]); - int32_t iLtrRefIdx = m_pSpatialPic[iTargetDid][BestRefCandidateParam->iSrcListIdx]->iLongTermPicNum; + SRefInfoParam* BestRefCandidateParam = & (pVaaExt->sVaaStrBestRefCandidate[iRefIdx]); + int32_t iLtrRefIdx = m_pSpatialPic[iTargetDid][BestRefCandidateParam->iSrcListIdx]->iLongTermPicNum; return iLtrRefIdx; } void CWelsPreProcess::Padding (uint8_t* pSrcY, uint8_t* pSrcU, uint8_t* pSrcV, int32_t iStrideY, int32_t iStrideUV,