change downsampling logic that downsampling source is from the nearest layer instead of the highest layer

This commit is contained in:
Karina 2016-03-14 09:55:36 +08:00
parent 25f53a2e3d
commit f84f2315ab
5 changed files with 53 additions and 72 deletions

View File

@ -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();

View File

@ -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;

View File

@ -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;
}

View File

@ -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"
};

View File

@ -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
{