From f84f2315abba08e99875853ce12d9159c5e0d415 Mon Sep 17 00:00:00 2001 From: Karina Date: Mon, 14 Mar 2016 09:55:36 +0800 Subject: [PATCH] change downsampling logic that downsampling source is from the nearest layer instead of the highest layer --- codec/encoder/core/inc/wels_preprocess.h | 1 - codec/encoder/core/src/encoder_ext.cpp | 26 +++--- codec/encoder/core/src/wels_preprocess.cpp | 94 +++++++++------------- test/api/decode_api_test.cpp | 2 +- test/api/encoder_test.cpp | 2 +- 5 files changed, 53 insertions(+), 72 deletions(-) diff --git a/codec/encoder/core/inc/wels_preprocess.h b/codec/encoder/core/inc/wels_preprocess.h index f04ea44b..0987420e 100644 --- a/codec/encoder/core/inc/wels_preprocess.h +++ b/codec/encoder/core/inc/wels_preprocess.h @@ -140,7 +140,6 @@ class CWelsPreProcess { const uint32_t kuiShortRefCount); void UpdateSrcListLosslessScreenRefSelectionWithLtr (SPicture* pCurPicture, const int32_t kiCurDid, const int32_t kuiMarkLongTermPicIdx, SPicture** pLongRefList); - bool BuildSpatialLayer(sWelsEncCtx* pCtx, const SSourcePicture* kpSrc,int32_t iSpatialLayer); private: int32_t WelsPreprocessCreate(); int32_t WelsPreprocessDestroy(); diff --git a/codec/encoder/core/src/encoder_ext.cpp b/codec/encoder/core/src/encoder_ext.cpp index 5c755768..7a68919d 100644 --- a/codec/encoder/core/src/encoder_ext.cpp +++ b/codec/encoder/core/src/encoder_ext.cpp @@ -3743,7 +3743,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour EWelsNalUnitType eNalType = NAL_UNIT_UNSPEC_0; EWelsNalRefIdc eNalRefIdc = NRI_PRI_LOWEST; int8_t iCurDid = 0; - int8_t iCurTid = 0; + int32_t iCurTid = 0; bool bAvcBased = false; SLogContext* pLogCtx = & (pCtx->sLogCtx); bool bFinishedWriteHeader = false; @@ -3792,19 +3792,18 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour pCtx->pCurDqLayer = pCtx->ppDqLayerList[pSpatialIndexMap->iDid]; pCtx->pCurDqLayer->pRefLayer = NULL; - while (iSpatialIdx < iSpatialNum) { - bool bEncoding = pCtx->pVpp->BuildSpatialLayer (pCtx, pSrcPic, iSpatialIdx); - if (!bEncoding) { - ++iSpatialIdx; - continue; - } + while (iSpatialIdx < pSvcParam->iSpatialLayerNum) { const int32_t iDidIdx = (pSpatialIndexMap + iSpatialIdx)->iDid; SSpatialLayerConfig* pParam = &pSvcParam->sSpatialLayers[iDidIdx]; SSpatialLayerInternal* pParamInternal = &pSvcParam->sDependencyLayers[iDidIdx]; int32_t iDecompositionStages = pSvcParam->sDependencyLayers[iDidIdx].iDecompositionStages; pCtx->pCurDqLayer = pCtx->ppDqLayerList[iDidIdx]; pCtx->uiDependencyId = iCurDid = (int8_t)iDidIdx; - + //skip this spatial layer + if(GetTemporalLevel (pParamInternal, pParamInternal->iCodingIndex,pSvcParam->uiGopSize) == INVALID_TEMPORAL_ID){ + ++iSpatialIdx; + continue; + } eFrameType = DecideFrameType (pCtx, iSpatialNum, iDidIdx); if (eFrameType == videoFrameTypeSkip) { eFrameType = videoFrameTypeSkip; @@ -3847,11 +3846,10 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour } } pCtx->iContinualSkipFrames = 0; - - InitFrameCoding (pCtx, eFrameType, iDidIdx); - iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[iSpatialIdx], pParamInternal->iCodingIndex, - pSvcParam->uiGopSize); + iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[iDidIdx], pParamInternal->iCodingIndex, + pSvcParam->uiGopSize); pCtx->uiTemporalId = iCurTid; + InitFrameCoding (pCtx, eFrameType, iDidIdx); if (eFrameType == videoFrameTypeIDR) { // write parameter sets bitstream or SEI/SSEI (if any) here @@ -4433,9 +4431,9 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour pFbi->iSubSeqId, iFrameSize); for (int32_t i = 0; i < iLayerNum; i++) WelsLog (pLogCtx, WELS_LOG_DEBUG, - "WelsEncoderEncodeExt() OutputInfo iLayerId = %d,iNalType = %d,iNalCount = %d, first Nal Length=%d,uiSpatialId = %d", i, + "WelsEncoderEncodeExt() OutputInfo iLayerId = %d,iNalType = %d,iNalCount = %d, first Nal Length=%d,uiSpatialId = %d,uiTemporalId = %d", i, pFbi->sLayerInfo[i].uiLayerType, pFbi->sLayerInfo[i].iNalCount, pFbi->sLayerInfo[i].pNalLengthInByte[0], - pFbi->sLayerInfo[i].uiSpatialId); + pFbi->sLayerInfo[i].uiSpatialId,pFbi->sLayerInfo[i].uiTemporalId); WelsEmms(); pLayerBsInfo->eFrameType = eFrameType; diff --git a/codec/encoder/core/src/wels_preprocess.cpp b/codec/encoder/core/src/wels_preprocess.cpp index 3ba55026..f7e79bae 100644 --- a/codec/encoder/core/src/wels_preprocess.cpp +++ b/codec/encoder/core/src/wels_preprocess.cpp @@ -252,10 +252,6 @@ int32_t CWelsPreProcess::AnalyzeSpatialPic (sWelsEncCtx* pCtx, const int32_t kiD 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); } } @@ -295,46 +291,9 @@ int32_t CWelsPreProcess::UpdateSpatialPictures (sWelsEncCtx* pCtx, SWelsSvcCodin /* -* 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; -} - + * SingleLayerPreprocess: down sampling if applicable + * @return: exact number of spatial layers need to encoder indeed + */ int32_t CWelsPreProcess::SingleLayerPreprocess (sWelsEncCtx* pCtx, const SSourcePicture* kpSrc, Scaled_Picture* pScaledPicture) { SWelsSvcCodingParam* pSvcParam = pCtx->pSvcParam; @@ -351,7 +310,8 @@ int32_t CWelsPreProcess::SingleLayerPreprocess (sWelsEncCtx* pCtx, const SSource int32_t iTargetWidth = 0; int32_t iTargetHeight = 0; int32_t iTemporalId = 0; - + SSpatialPicIndex* pSpatialIndexMap = &pCtx->sSpatialIndexMap[0]; + int32_t iClosestDid = iDependencyId; pDlayerParamInternal = &pSvcParam->sDependencyLayers[iDependencyId]; pDlayerParam = &pSvcParam->sSpatialLayers[iDependencyId]; iTargetWidth = pDlayerParam->iVideoWidth; @@ -360,13 +320,12 @@ int32_t CWelsPreProcess::SingleLayerPreprocess (sWelsEncCtx* pCtx, const SSource (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; - + false; pSrcPic = pScaledPicture->pScaledInputPicture ? pScaledPicture->pScaledInputPicture : m_pSpatialPic[iDependencyId][iPicturePos]; + WelsMoveMemoryWrapper (pSvcParam, pSrcPic, kpSrc, iSrcWidth, iSrcHeight); if (pSvcParam->bEnableDenoise) @@ -384,6 +343,7 @@ int32_t CWelsPreProcess::SingleLayerPreprocess (sWelsEncCtx* pCtx, const SSource } 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 : @@ -401,29 +361,54 @@ int32_t CWelsPreProcess::SingleLayerPreprocess (sWelsEncCtx* pCtx, const SSource } } } - - WelsUpdateSpatialIdxMap (pCtx, iDependencyId, pDstPic, iDependencyId); - m_pLastSpatialPicture[iDependencyId][1] = m_pSpatialPic[iDependencyId][iPicturePos]; - if (iTemporalId != INVALID_TEMPORAL_ID) { ++ iSpatialNum; } + + WelsUpdateSpatialIdxMap (pCtx, iDependencyId, pDstPic, iDependencyId); + m_pLastSpatialPicture[iDependencyId][1] = m_pSpatialPic[iDependencyId][iPicturePos]; -- iDependencyId; + + // generate other spacial layer + // pSrc is + // -- padded input pic, if downsample should be applied to generate highest layer, [if] block above + // -- highest layer, if no downsampling, [else] block above if (pSvcParam->iSpatialLayerNum > 1) { while (iDependencyId >= 0) { pDlayerParamInternal = &pSvcParam->sDependencyLayers[iDependencyId]; + pDlayerParam = &pSvcParam->sSpatialLayers[iDependencyId]; + SPicture* pSrcPic = (pSpatialIndexMap + iClosestDid)->pSrc;; // large + //SPicture* pSrcPic = (pSpatialIndexMap + (pSvcParam->iSpatialLayerNum - 1))->pSrc;; // large + iTargetWidth = pDlayerParam->iVideoWidth; + iTargetHeight = pDlayerParam->iVideoHeight; iTemporalId = pDlayerParamInternal->uiCodingIdx2TemporalId[pDlayerParamInternal->iCodingIndex & (pSvcParam->uiGopSize - 1)]; + iPicturePos = m_uiSpatialLayersInTemporal[iDependencyId] - 1; - if ((iTemporalId != INVALID_TEMPORAL_ID)) { + // down sampling performed + int32_t iSrcWidth = pScaledPicture->iScaledWidth[iClosestDid]; + int32_t iSrcHeight = pScaledPicture->iScaledHeight[iClosestDid]; + pDstPic = m_pSpatialPic[iDependencyId][iPicturePos]; // small + iShrinkWidth = pScaledPicture->iScaledWidth[iDependencyId]; + iShrinkHeight = pScaledPicture->iScaledHeight[iDependencyId]; + DownsamplePadding (pSrcPic, pDstPic, iSrcWidth, iSrcHeight, iShrinkWidth, iShrinkHeight, iTargetWidth, iTargetHeight, + true); + + WelsUpdateSpatialIdxMap (pCtx, iDependencyId, pDstPic, iDependencyId); + if ((iTemporalId != INVALID_TEMPORAL_ID)) ++ iSpatialNum; - } + m_pLastSpatialPicture[iDependencyId][1] = m_pSpatialPic[iDependencyId][iPicturePos]; + + iClosestDid = iDependencyId; -- iDependencyId; + } } return iSpatialNum; } + + /*! * \brief Whether input picture need be scaled? */ @@ -437,7 +422,6 @@ bool JudgeNeedOfScaling (SWelsSvcCodingParam* pParam, Scaled_Picture* pScaledPic int32_t iSpatialIdx = pParam->iSpatialLayerNum - 1; if (kiDstPicWidth >= kiInputPicWidth && kiDstPicHeight >= kiInputPicHeight) { - iSpatialIdx --; // highest D layer do not need downsampling bNeedDownsampling = false; } diff --git a/test/api/decode_api_test.cpp b/test/api/decode_api_test.cpp index 086cff80..35c7b5af 100644 --- a/test/api/decode_api_test.cpp +++ b/test/api/decode_api_test.cpp @@ -759,7 +759,7 @@ const uint32_t kiHeight = 96; //DO NOT CHANGE! const uint32_t kiFrameRate = 12; //DO NOT CHANGE! const uint32_t kiFrameNum = 100; //DO NOT CHANGE! const char* pHashStr[] = { //DO NOT CHANGE! - "585663f78cadb70d9c9f179b9b53b90ffddf3178", + "9c4e6146b29bac5d5d4be3c5bbab9c072dcb3f3f", "f350001c333902029800bd291fbed915a4bdf19a", "eb9d853b7daec03052c4850027ac94adc84c3a7e" }; diff --git a/test/api/encoder_test.cpp b/test/api/encoder_test.cpp index aa53d222..1a510f82 100644 --- a/test/api/encoder_test.cpp +++ b/test/api/encoder_test.cpp @@ -131,7 +131,7 @@ static const EncodeFileParam kFileParamArray[] = { }, { "res/Cisco_Absolute_Power_1280x720_30fps.yuv", - "b5f42875a550551d81e460017d2691d3c104cf2f", CAMERA_VIDEO_REAL_TIME, 1280, 720, 30.0f, SM_SINGLE_SLICE, false, 4, false, false, false + "3943145545a2bd27a642b2045d4e3dbae55c6870", CAMERA_VIDEO_REAL_TIME, 1280, 720, 30.0f, SM_SINGLE_SLICE, false, 4, false, false, false }, // the following values may be adjusted for times since we start tuning the strategy {