ref: f84f2315abba08e99875853ce12d9159c5e0d415
parent: 25f53a2e3dd3cc978b9bf76fc14467e802c3ebf1
author: Karina <ruil2@cisco.com>
date: Mon Mar 14 05:55:36 EDT 2016
change downsampling logic that downsampling source is from the nearest layer instead of the highest layer
--- a/codec/encoder/core/inc/wels_preprocess.h
+++ b/codec/encoder/core/inc/wels_preprocess.h
@@ -140,7 +140,6 @@
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();
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -3743,7 +3743,7 @@
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,12 +3792,7 @@
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];
@@ -3804,7 +3799,11 @@
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 @@
}
}
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 @@
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;
--- a/codec/encoder/core/src/wels_preprocess.cpp
+++ b/codec/encoder/core/src/wels_preprocess.cpp
@@ -252,10 +252,6 @@
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 @@
/*
-* 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 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 @@
(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 @@
}
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 @@
}
}
}
-
- 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 @@
int32_t iSpatialIdx = pParam->iSpatialLayerNum - 1;
if (kiDstPicWidth >= kiInputPicWidth && kiDstPicHeight >= kiInputPicHeight) {
- iSpatialIdx --; // highest D layer do not need downsampling
bNeedDownsampling = false;
}
--- a/test/api/decode_api_test.cpp
+++ b/test/api/decode_api_test.cpp
@@ -759,7 +759,7 @@
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"
};
--- a/test/api/encoder_test.cpp
+++ b/test/api/encoder_test.cpp
@@ -131,7 +131,7 @@
},
{
"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
{