ref: 67f925674a327479273b1e3327c1798dcfb65803
parent: 7bfb96b2b6ac2466294081eb73c4c0c5a27ec932
parent: 0f0d54ef51cdf3443cc7b98d756ab0a766fc624e
author: HaiboZhu <haibozhu@cisco.com>
date: Fri Jan 15 04:27:58 EST 2016
Merge pull request #2329 from ruil2/layer4 using independent encoder control logic for SAVC case
--- a/codec/encoder/core/inc/encoder.h
+++ b/codec/encoder/core/inc/encoder.h
@@ -82,11 +82,11 @@
/*!
* \brief initialize frame coding
*/
-void InitFrameCoding (sWelsEncCtx* pEncCtx, const EVideoFrameType keFrameType);
-void LoadBackFrameNum(sWelsEncCtx* pEncCtx);
+void InitFrameCoding (sWelsEncCtx* pEncCtx, const EVideoFrameType keFrameType,const int32_t kiDidx);
+void LoadBackFrameNum(sWelsEncCtx* pEncCtx,const int32_t kiDidx);
-EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum);
-
+EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum,const int32_t kiDidx);
+void InitBitStream(sWelsEncCtx* pEncCtx);
int32_t GetTemporalLevel (SSpatialLayerInternal* fDlp, const int32_t kiFrameNum, const int32_t kiGopSize);
/*!
* \brief Dump reconstruction for dependency layer
--- a/codec/encoder/core/inc/encoder_context.h
+++ b/codec/encoder/core/inc/encoder_context.h
@@ -149,10 +149,7 @@
SLTRState* pLtr;//[MAX_DEPENDENCY_LAYER];
bool bCurFrameMarkedAsSceneLtr;
// Derived
- int32_t iCodingIndex;
- int32_t iFrameIndex; // count how many frames elapsed during coding context currently
- int32_t iFrameNum; // current frame number coding
- int32_t iPOC; // frame iPOC
+
EWelsSliceType eSliceType; // currently coding slice type
EWelsNalUnitType eNalType; // NAL type
EWelsNalRefIdc eNalPriority; // NAL_Reference_Idc currently
@@ -162,7 +159,6 @@
uint8_t uiDependencyId; // Idc of dependecy layer to be coded
uint8_t uiTemporalId; // Idc of temporal layer to be coded
bool bNeedPrefixNalFlag; // whether add prefix nal
- bool bEncCurFrmAsIdrFlag;
// Rate control routine
SWelsSvcRc* pWelsSvcRc;
@@ -202,7 +198,6 @@
bool bRefOfCurTidIsLtr[MAX_DEPENDENCY_LAYER][MAX_TEMPORAL_LEVEL];
uint16_t uiIdrPicId; // IDR picture id: [0, 65535], this one is used for LTR
-
int32_t iMaxSliceCount;// maximal count number of slices for all layers observation
int16_t iActiveThreadsNum; // number of threads active so far
--- a/codec/encoder/core/inc/param_svc.h
+++ b/codec/encoder/core/inc/param_svc.h
@@ -86,7 +86,13 @@
int8_t iHighestTemporalId;
float fInputFrameRate; // input frame rate
float fOutputFrameRate; // output frame rate
-
+ // uint16_t uiIdrPicId; // IDR picture id: [0, 65535], this one is used for LTR
+ int32_t iSkipFrameFlag; //_GOM_RC_
+ int32_t iCodingIndex;
+ int32_t iFrameIndex; // count how many frames elapsed during coding context currently
+ bool bEncCurFrmAsIdrFlag;
+ int32_t iFrameNum; // current frame number coding
+ int32_t iPOC; // frame iPOC
#ifdef ENABLE_FRAME_DUMP
char sRecFileName[MAX_FNAME_LEN]; // file to be constructed
#endif//ENABLE_FRAME_DUMP
--- a/codec/encoder/core/inc/wels_preprocess.h
+++ b/codec/encoder/core/inc/wels_preprocess.h
@@ -140,7 +140,7 @@
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.cpp
+++ b/codec/encoder/core/src/encoder.cpp
@@ -211,7 +211,7 @@
/*init pixel average function*/
/*get one column or row pixel when refinement*/
InitMcFunc (&pFuncList->sMcFuncs, uiCpuFlag);
- InitCoeffFunc (pFuncList,uiCpuFlag,pParam->iEntropyCodingModeFlag);
+ InitCoeffFunc (pFuncList, uiCpuFlag, pParam->iEntropyCodingModeFlag);
WelsInitEncodingFuncs (pFuncList, uiCpuFlag);
WelsInitReconstructionFuncs (pFuncList, uiCpuFlag);
@@ -226,45 +226,48 @@
return iReturn;
}
-void UpdateFrameNum(sWelsEncCtx* pEncCtx) {
+void UpdateFrameNum (sWelsEncCtx* pEncCtx, const int32_t kiDidx) {
+ SSpatialLayerInternal* pParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[kiDidx];
bool bNeedFrameNumIncreasing = false;
- for (int32_t i=0; i<MAX_DEPENDENCY_LAYER; i++) {
- if (NRI_PRI_LOWEST != pEncCtx->eLastNalPriority[i]) {
- bNeedFrameNumIncreasing = true;
- }
+
+ if (NRI_PRI_LOWEST != pEncCtx->eLastNalPriority[kiDidx]) {
+ bNeedFrameNumIncreasing = true;
}
+
if (bNeedFrameNumIncreasing) {
- if (pEncCtx->iFrameNum < (1 << pEncCtx->pSps->uiLog2MaxFrameNum) - 1)
- ++ pEncCtx->iFrameNum;
+ if (pParamInternal->iFrameNum < (1 << pEncCtx->pSps->uiLog2MaxFrameNum) - 1)
+ ++ pParamInternal->iFrameNum;
else
- pEncCtx->iFrameNum = 0; // if iFrameNum overflow
+ pParamInternal->iFrameNum = 0; // if iFrameNum overflow
}
- for (int32_t i=0; i<MAX_DEPENDENCY_LAYER; i++) {
- pEncCtx->eLastNalPriority[i] = NRI_PRI_LOWEST;
- }
+
+ pEncCtx->eLastNalPriority[kiDidx] = NRI_PRI_LOWEST;
+ WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "UpdateFrameNum,bNeedFrameNumIncreasing = %d,iFrameNum = %d,kiDidx = %d",
+ bNeedFrameNumIncreasing, pParamInternal->iFrameNum, kiDidx);
}
-void LoadBackFrameNum(sWelsEncCtx* pEncCtx) {
- bool bNeedFrameNumIncreasing = false;
- for (int32_t i=0; i<MAX_DEPENDENCY_LAYER; i++) {
- if (NRI_PRI_LOWEST != pEncCtx->eLastNalPriority[i]) {
- bNeedFrameNumIncreasing = true;
- }
+void LoadBackFrameNum (sWelsEncCtx* pEncCtx, const int32_t kiDidx) {
+ SSpatialLayerInternal* pParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[kiDidx];
+ bool bNeedFrameNumIncreasing = false;
+
+ if (NRI_PRI_LOWEST != pEncCtx->eLastNalPriority[kiDidx]) {
+ bNeedFrameNumIncreasing = true;
+ }
+
+ if (bNeedFrameNumIncreasing) {
+ if (pParamInternal->iFrameNum != 0) {
+ pParamInternal->iFrameNum --;
+ } else {
+ pParamInternal->iFrameNum = (1 << pEncCtx->pSps->uiLog2MaxFrameNum) - 1;
}
- if (bNeedFrameNumIncreasing) {
- if (pEncCtx->iFrameNum != 0) {
- pEncCtx->iFrameNum --;
- } else {
- pEncCtx->iFrameNum = (1 << pEncCtx->pSps->uiLog2MaxFrameNum) - 1;
- }
- }
+ }
+ WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO,
+ "LoadBackFrameNum,bNeedFrameNumIncreasing = %d,iFrameNum = %d,kiDidx = %d", bNeedFrameNumIncreasing,
+ pParamInternal->iFrameNum, kiDidx);
}
-/*!
- * \brief initialize frame coding
- */
-void InitFrameCoding (sWelsEncCtx* pEncCtx, const EVideoFrameType keFrameType) {
+void InitBitStream (sWelsEncCtx* pEncCtx) {
// for bitstream writing
pEncCtx->iPosBsBuffer = 0; // reset bs pBuffer position
pEncCtx->pOut->iNalIndex = 0; // reset NAL index
@@ -271,42 +274,49 @@
pEncCtx->pOut->iLayerBsIndex = 0; // reset index of Layer Bs
InitBits (&pEncCtx->pOut->sBsWrite, pEncCtx->pOut->pBsBuffer, pEncCtx->pOut->uiSize);
-
+}
+/*!
+ * \brief initialize frame coding
+ */
+void InitFrameCoding (sWelsEncCtx* pEncCtx, const EVideoFrameType keFrameType, const int32_t kiDidx) {
+ SSpatialLayerInternal* pParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[kiDidx];
if (keFrameType == videoFrameTypeP) {
- ++pEncCtx->iFrameIndex;
+ ++pParamInternal->iFrameIndex;
- if (pEncCtx->iPOC < (1 << pEncCtx->pSps->iLog2MaxPocLsb) - 2) // if iPOC type is no 0, this need be modification
- pEncCtx->iPOC += 2; // for POC type 0
+ if (pParamInternal->iPOC < (1 << pEncCtx->pSps->iLog2MaxPocLsb) -
+ 2) // if iPOC type is no 0, this need be modification
+ pParamInternal->iPOC += 2; // for POC type 0
else
- pEncCtx->iPOC = 0;
+ pParamInternal->iPOC = 0;
- UpdateFrameNum(pEncCtx);
+ UpdateFrameNum (pEncCtx, kiDidx);
pEncCtx->eNalType = NAL_UNIT_CODED_SLICE;
pEncCtx->eSliceType = P_SLICE;
pEncCtx->eNalPriority = NRI_PRI_HIGH;
} else if (keFrameType == videoFrameTypeIDR) {
- pEncCtx->iFrameNum = 0;
- pEncCtx->iPOC = 0;
- pEncCtx->bEncCurFrmAsIdrFlag = false;
- pEncCtx->iFrameIndex = 0;
+ pParamInternal->iFrameNum = 0;
+ pParamInternal->iPOC = 0;
+ pParamInternal->bEncCurFrmAsIdrFlag = false;
+ pParamInternal->iFrameIndex = 0;
pEncCtx->eNalType = NAL_UNIT_CODED_SLICE_IDR;
pEncCtx->eSliceType = I_SLICE;
pEncCtx->eNalPriority = NRI_PRI_HIGHEST;
- pEncCtx->iCodingIndex = 0;
+ pParamInternal->iCodingIndex = 0;
// reset_ref_list
// rc_init_gop
} else if (keFrameType == videoFrameTypeI) {
- if (pEncCtx->iPOC < (1 << pEncCtx->pSps->iLog2MaxPocLsb) - 2) // if iPOC type is no 0, this need be modification
- pEncCtx->iPOC += 2; // for POC type 0
+ if (pParamInternal->iPOC < (1 << pEncCtx->pSps->iLog2MaxPocLsb) -
+ 2) // if iPOC type is no 0, this need be modification
+ pParamInternal->iPOC += 2; // for POC type 0
else
- pEncCtx->iPOC = 0;
+ pParamInternal->iPOC = 0;
- UpdateFrameNum(pEncCtx);
+ UpdateFrameNum (pEncCtx, kiDidx);
pEncCtx->eNalType = NAL_UNIT_CODED_SLICE;
pEncCtx->eSliceType = I_SLICE;
@@ -322,11 +332,12 @@
#endif//FRAME_INFO_OUTPUT
}
-EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum) {
+EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum, const int32_t kiDidx) {
SWelsSvcCodingParam* pSvcParam = pEncCtx->pSvcParam;
+ SSpatialLayerInternal* pParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[kiDidx];
EVideoFrameType iFrameType = videoFrameTypeInvalid;
bool bSceneChangeFlag = false;
-
+ int32_t iSkipFrameFlag = pSvcParam->bSimulcastAVC?pParamInternal->iSkipFrameFlag:pEncCtx->iSkipFrameFlag;
if (pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {
if ((!pSvcParam->bEnableSceneChangeDetect) || pEncCtx->pVaa->bIdrPeriodFlag ||
(kiSpatialNum < pSvcParam->iSpatialLayerNum)) {
@@ -334,7 +345,7 @@
} else {
bSceneChangeFlag = pEncCtx->pVaa->bSceneChangeFlag;
}
- if (pEncCtx->pVaa->bIdrPeriodFlag || pEncCtx->bEncCurFrmAsIdrFlag || (!pSvcParam->bEnableLongTermReference
+ if (pEncCtx->pVaa->bIdrPeriodFlag || pParamInternal->bEncCurFrmAsIdrFlag || (!pSvcParam->bEnableLongTermReference
&& bSceneChangeFlag)) {
iFrameType = videoFrameTypeIDR;
} else if (pSvcParam->bEnableLongTermReference && (bSceneChangeFlag
@@ -356,11 +367,11 @@
} else {
iFrameType = videoFrameTypeP;
}
- if (videoFrameTypeP == iFrameType && pEncCtx->iSkipFrameFlag > 0) {
- -- pEncCtx->iSkipFrameFlag;
+ if (videoFrameTypeP == iFrameType && iSkipFrameFlag > 0) {
+ pParamInternal->iSkipFrameFlag = 0;
iFrameType = videoFrameTypeSkip;
} else if (videoFrameTypeIDR == iFrameType) {
- pEncCtx->iCodingIndex = 0;
+ pParamInternal->iCodingIndex = 0;
pEncCtx->bCurFrameMarkedAsSceneLtr = true;
}
@@ -368,7 +379,7 @@
// perform scene change detection
if ((!pSvcParam->bEnableSceneChangeDetect) || pEncCtx->pVaa->bIdrPeriodFlag ||
(kiSpatialNum < pSvcParam->iSpatialLayerNum)
- || (pEncCtx->iFrameIndex < (VGOP_SIZE << 1))) { // avoid too frequent I frame coding, rc control
+ || (pParamInternal->iFrameIndex < (VGOP_SIZE << 1))) { // avoid too frequent I frame coding, rc control
bSceneChangeFlag = false;
} else {
bSceneChangeFlag = pEncCtx->pVaa->bSceneChangeFlag;
@@ -378,13 +389,13 @@
//bIdrPeriodFlag: RC disable || iSpatialNum != pSvcParam->iSpatialLayerNum
//pEncCtx->bEncCurFrmAsIdrFlag: 1. first frame should be IDR; 2. idr pause; 3. idr request
iFrameType = (pEncCtx->pVaa->bIdrPeriodFlag || bSceneChangeFlag
- || pEncCtx->bEncCurFrmAsIdrFlag) ? videoFrameTypeIDR : videoFrameTypeP;
+ || pParamInternal->bEncCurFrmAsIdrFlag) ? videoFrameTypeIDR : videoFrameTypeP;
- if (videoFrameTypeP == iFrameType && pEncCtx->iSkipFrameFlag > 0) { // for frame skip, 1/5/2010
- -- pEncCtx->iSkipFrameFlag;
+ if (videoFrameTypeP == iFrameType && iSkipFrameFlag > 0) { // for frame skip, 1/5/2010
+ pParamInternal->iSkipFrameFlag = 0;
iFrameType = videoFrameTypeSkip;
} else if (videoFrameTypeIDR == iFrameType) {
- pEncCtx->iCodingIndex = 0;
+ pParamInternal->iCodingIndex = 0;
}
}
return iFrameType;
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -1206,6 +1206,7 @@
while (iDlayerIndex < iDlayerCount) {
SDqLayer* pDqLayer = NULL;
SSpatialLayerConfig* pDlayer = &pParam->sSpatialLayers[iDlayerIndex];
+ SSpatialLayerInternal* pParamInternal = &pParam->sDependencyLayers[iDlayerIndex];
const int32_t kiMbW = (pDlayer->iVideoWidth + 0x0f) >> 4;
const int32_t kiMbH = (pDlayer->iVideoHeight + 0x0f) >> 4;
int32_t iMaxSliceNum = 1;
@@ -1213,6 +1214,12 @@
if (iMaxSliceNum < kiSliceNum)
iMaxSliceNum = kiSliceNum;
+ pParamInternal->iSkipFrameFlag = 0;
+ pParamInternal->iCodingIndex = 0;
+ pParamInternal->iFrameIndex = 0;
+ pParamInternal->iFrameNum = 0;
+ pParamInternal->iPOC = 0;
+ pParamInternal->bEncCurFrmAsIdrFlag = true; // make sure first frame is IDR
// pDq layers list
pDqLayer = (SDqLayer*)pMa->WelsMallocz (sizeof (SDqLayer), "pDqLayer");
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == pDqLayer), FreeMemorySvc (ppCtx))
@@ -1900,7 +1907,6 @@
(pMa->WelsMallocz (iCountMaxMbNum * sizeof (int32_t), "pSadCostMb"));
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSadCostMb), FreeMemorySvc (ppCtx))
- (*ppCtx)->bEncCurFrmAsIdrFlag = true; // make sure first frame is IDR
(*ppCtx)->iGlobalQp = 26; // global qp in default
(*ppCtx)->pLtr = (SLTRState*)pMa->WelsMalloc (kiNumDependencyLayers * sizeof (SLTRState), "SLTRState");
@@ -2802,7 +2808,7 @@
SDqIdc* pDqIdc = &pCtx->pDqIdcMap[kiCurDid];
int32_t iIdx = 0;
int32_t iSliceCount = 0;
-
+ SSpatialLayerInternal* pParamInternal = &pParam->sDependencyLayers[kiCurDid];
if (NULL == pCurDq)
return;
@@ -2856,8 +2862,9 @@
pNalHdExt->uiDependencyId = kiCurDid;
pNalHdExt->bDiscardableFlag = (pCtx->bNeedPrefixNalFlag) ? (pNalHd->uiNalRefIdc == NRI_PRI_LOWEST) : false;
- pNalHdExt->bIdrFlag = (pCtx->iFrameNum == 0) && ((pCtx->eNalType == NAL_UNIT_CODED_SLICE_IDR)
- || (pCtx->eSliceType == I_SLICE));
+ pNalHdExt->bIdrFlag = (pParamInternal->iFrameNum == 0)
+ && ((pCtx->eNalType == NAL_UNIT_CODED_SLICE_IDR)
+ || (pCtx->eSliceType == I_SLICE));
pNalHdExt->uiTemporalId = pCtx->uiTemporalId;
// pEncPic pData
@@ -3398,9 +3405,16 @@
int32_t ForceCodingIDR (sWelsEncCtx* pCtx) {
if (NULL == pCtx)
return 1;
+ for (int32_t iDid = 0; iDid < pCtx->pSvcParam->iSpatialLayerNum; iDid++) {
+ SSpatialLayerInternal* pParamInternal = &pCtx->pSvcParam->sDependencyLayers[iDid];
+ pParamInternal->iCodingIndex = 0;
+ pParamInternal->iSkipFrameFlag = 0;
+ pParamInternal->iFrameIndex = 0;
+ pParamInternal->iFrameNum = 0;
+ pParamInternal->iPOC = 0;
+ pParamInternal->bEncCurFrmAsIdrFlag = true;
+ }
- pCtx->bEncCurFrmAsIdrFlag = true;
- pCtx->iCodingIndex = 0;
pCtx->bCheckWindowStatusRefreshFlag = false;
WelsLog (&pCtx->sLogCtx, WELS_LOG_INFO, "ForceCodingIDR at InputFrameCount=%d\n",
@@ -3427,11 +3441,10 @@
pLayerBsInfo->uiQualityId = 0;
pLayerBsInfo->uiLayerType = NON_VIDEO_CODING_LAYER;
pLayerBsInfo->iNalCount = iCountNal;
- pLayerBsInfo->eFrameType = videoFrameTypeIDR;
+ pLayerBsInfo->eFrameType = videoFrameTypeInvalid;
//pCtx->eLastNalPriority = NRI_PRI_HIGHEST;
pFbi->iLayerNum = 1;
pFbi->eFrameType = videoFrameTypeInvalid;
-
WelsEmms();
return ENC_RETURN_SUCCESS;
@@ -3479,7 +3492,7 @@
}
// writing parasets for simulcast avc
-int32_t WriteSavcParaset (sWelsEncCtx* pCtx, const int32_t kiSpatialNum,
+int32_t WriteSavcParaset (sWelsEncCtx* pCtx, const int32_t iIdx,
SLayerBSInfo*& pLayerBsInfo, int32_t& iLayerNum, int32_t& iFrameSize) {
int32_t iNonVclSize = 0, iCountNal = 0, iReturn = ENC_RETURN_SUCCESS;
@@ -3486,68 +3499,62 @@
// write SPS
iNonVclSize = 0;
- assert ((kiSpatialNum == pCtx->iSpsNum) || (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy));
+ //writing one NAL
+ int32_t iNalSize = 0;
+ iCountNal = 0;
- for (int32_t iIdx = 0; iIdx < pCtx->iSpsNum; iIdx++) {
- //writing one NAL
- int32_t iNalSize = 0;
- iCountNal = 0;
+ iReturn = WelsWriteOneSPS (pCtx, iIdx, iNalSize);
+ WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
- iReturn = WelsWriteOneSPS (pCtx, iIdx, iNalSize);
- WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
+ pLayerBsInfo->pNalLengthInByte[iCountNal] = iNalSize;
+ iNonVclSize += iNalSize;
+ iCountNal = 1;
- pLayerBsInfo->pNalLengthInByte[iCountNal] = iNalSize;
- iNonVclSize += iNalSize;
- iCountNal = 1;
- //finish writing one NAL
+ //finish writing one NAL
- pLayerBsInfo->uiSpatialId = iIdx;
- pLayerBsInfo->uiTemporalId = 0;
- pLayerBsInfo->uiQualityId = 0;
- pLayerBsInfo->uiLayerType = NON_VIDEO_CODING_LAYER;
- pLayerBsInfo->iNalCount = iCountNal;
- pLayerBsInfo->eFrameType = videoFrameTypeIDR;
- //point to next pLayerBsInfo
- ++ pLayerBsInfo;
- ++ pCtx->pOut->iLayerBsIndex;
- pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer;
- pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal;
- //update for external countings
- ++ iLayerNum;
+ pLayerBsInfo->uiSpatialId = iIdx;
+ pLayerBsInfo->uiTemporalId = 0;
+ pLayerBsInfo->uiQualityId = 0;
+ pLayerBsInfo->uiLayerType = NON_VIDEO_CODING_LAYER;
+ pLayerBsInfo->iNalCount = iCountNal;
+ pLayerBsInfo->eFrameType = videoFrameTypeIDR;
+ //point to next pLayerBsInfo
+ ++ pLayerBsInfo;
+ ++ pCtx->pOut->iLayerBsIndex;
+ pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer;
+ pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal;
+ //update for external countings
+ ++ iLayerNum;
- }
-
// write PPS
//TODO: under new strategy, will PPS be correctly updated?
- for (int32_t iIdx = 0; iIdx < pCtx->iPpsNum; iIdx++) {
- //writing one NAL
- int32_t iNalSize = 0;
- iCountNal = 0;
+ //writing one NAL
+ iNalSize = 0;
+ iCountNal = 0;
- iReturn = WelsWriteOnePPS (pCtx, iIdx, iNalSize);
- WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
+ iReturn = WelsWriteOnePPS (pCtx, iIdx, iNalSize);
+ WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
- pLayerBsInfo->pNalLengthInByte[iCountNal] = iNalSize;
- iNonVclSize += iNalSize;
- iCountNal = 1;
- //finish writing one NAL
+ pLayerBsInfo->pNalLengthInByte[iCountNal] = iNalSize;
+ iNonVclSize += iNalSize;
+ iCountNal = 1;
+ //finish writing one NAL
- pLayerBsInfo->uiSpatialId = iIdx;
- pLayerBsInfo->uiTemporalId = 0;
- pLayerBsInfo->uiQualityId = 0;
- pLayerBsInfo->uiLayerType = NON_VIDEO_CODING_LAYER;
- pLayerBsInfo->iNalCount = iCountNal;
- pLayerBsInfo->eFrameType = videoFrameTypeIDR;
- //point to next pLayerBsInfo
- ++ pLayerBsInfo;
- ++ pCtx->pOut->iLayerBsIndex;
- pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer;
- pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal;
- //update for external countings
- ++ iLayerNum;
- }
+ pLayerBsInfo->uiSpatialId = iIdx;
+ pLayerBsInfo->uiTemporalId = 0;
+ pLayerBsInfo->uiQualityId = 0;
+ pLayerBsInfo->uiLayerType = NON_VIDEO_CODING_LAYER;
+ pLayerBsInfo->iNalCount = iCountNal;
+ pLayerBsInfo->eFrameType = videoFrameTypeIDR;
+ //point to next pLayerBsInfo
+ ++ pLayerBsInfo;
+ ++ pCtx->pOut->iLayerBsIndex;
+ pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer;
+ pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal;
+ //update for external countings
+ ++ iLayerNum;
// to check number of layers / nals / slices dependencies
if (iLayerNum > MAX_LAYER_NUM_OF_FRAME) {
@@ -3645,6 +3652,7 @@
void StackBackEncoderStatus (sWelsEncCtx* pEncCtx,
EVideoFrameType keFrameType) {
+ SSpatialLayerInternal* pParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
// for bitstream writing
pEncCtx->iPosBsBuffer = 0; // reset bs pBuffer position
pEncCtx->pOut->iNalIndex = 0; // reset NAL index
@@ -3652,14 +3660,15 @@
InitBits (&pEncCtx->pOut->sBsWrite, pEncCtx->pOut->pBsBuffer, pEncCtx->pOut->uiSize);
if ((keFrameType == videoFrameTypeP) || (keFrameType == videoFrameTypeI)) {
- pEncCtx->iFrameIndex --;
- if (pEncCtx->iPOC != 0) {
- pEncCtx->iPOC -= 2;
+ pParamInternal->iFrameIndex --;
+ if (pParamInternal->iPOC != 0) {
+ pParamInternal->iPOC -= 2;
} else {
- pEncCtx->iPOC = (1 << pEncCtx->pSps->iLog2MaxPocLsb) - 2;
+ pParamInternal->iPOC = (1 << pEncCtx->pSps->iLog2MaxPocLsb) - 2;
}
- LoadBackFrameNum (pEncCtx);
+ LoadBackFrameNum (pEncCtx, pEncCtx->uiDependencyId);
+
pEncCtx->eNalType = NAL_UNIT_CODED_SLICE;
pEncCtx->eSliceType = P_SLICE;
//pEncCtx->eNalPriority = pEncCtx->eLastNalPriority; //not need this since eNalPriority will be updated at the beginning of coding a frame
@@ -3682,10 +3691,10 @@
for (int i = 0; i < pFbi->iLayerNum; i++) {
pFbi->sLayerInfo[i].iNalCount = 0;
+ pFbi->sLayerInfo[i].eFrameType = videoFrameTypeSkip;
}
pFbi->iLayerNum = 0;
pFbi->iFrameSizeInBytes = 0;
- pFbi->eFrameType = videoFrameTypeSkip;
}
/*!
@@ -3725,6 +3734,7 @@
int8_t iCurTid = 0;
bool bAvcBased = false;
SLogContext* pLogCtx = & (pCtx->sLogCtx);
+ bool bFinishedWriteHeader = false;
#if defined(ENABLE_PSNR_CALC)
float fSnrY = .0f, fSnrU = .0f, fSnrV = .0f;
#endif//ENABLE_PSNR_CALC
@@ -3732,7 +3742,6 @@
#if defined(_DEBUG)
int32_t i = 0, j = 0, k = 0;
#endif//_DEBUG
-
pCtx->iEncoderError = ENC_RETURN_SUCCESS;
pCtx->bCurFrameMarkedAsSceneLtr = false;
pFbi->iLayerNum = 0; // for initialization
@@ -3746,8 +3755,9 @@
pCtx->pFuncList->pfRc.pfWelsUpdateMaxBrWindowStatus (pCtx, iSpatialNum, pSrcPic->uiTimeStamp);
}
- if (iSpatialNum < 1) { // skip due to temporal layer settings (different frame rate)
- ++ pCtx->iCodingIndex;
+ if (iSpatialNum < 1) {
+ // ++ pCtx->iCodingIndex;
+ pLayerBsInfo->eFrameType = videoFrameTypeSkip;
pFbi->eFrameType = videoFrameTypeSkip;
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
"[Rc] Frame timestamp = %lld, skip one frame due to preprocessing return (temporal layer settings or else), continual skipped %d frames",
@@ -3754,68 +3764,107 @@
pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
return ENC_RETURN_SUCCESS;
}
-
- eFrameType = DecideFrameType (pCtx, iSpatialNum);
- if (eFrameType == videoFrameTypeSkip) {
- if (pCtx->pFuncList->pfRc.pfWelsUpdateBufferWhenSkip)
- pCtx->pFuncList->pfRc.pfWelsUpdateBufferWhenSkip (pCtx, iSpatialNum);
- pFbi->eFrameType = eFrameType;
- WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
- "[Rc] Frame timestamp = %lld, skip one frame due to target_br, continual skipped %d frames",
- pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
- return ENC_RETURN_SUCCESS;
- }
-
- //loop each layer to check if have skip frame when RC and frame skip enable
- if (pCtx->pFuncList->pfRc.pfWelsCheckSkipBasedMaxbr) {
- bool bSkip = pCtx->pFuncList->pfRc.pfWelsCheckSkipBasedMaxbr (pCtx, iSpatialNum, eFrameType,
- (uint32_t)pSrcPic->uiTimeStamp);
- if (bSkip) {
- pFbi->eFrameType = videoFrameTypeSkip;
- WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
- "[Rc] Frame timestamp = %lld, skip one frame due to max_br, continual skipped %d frames",
- pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
- return ENC_RETURN_SUCCESS;
+ if (!pSvcParam->bSimulcastAVC) {
+ pCtx->iSkipFrameFlag = false;
+ for (int32_t iDid = 0; iDid < iSpatialNum; iDid++) {
+ if (pCtx->pSvcParam->sDependencyLayers[iDid].iSkipFrameFlag)
+ pCtx->iSkipFrameFlag = 1;
}
}
- pCtx->iContinualSkipFrames = 0;
- InitFrameCoding (pCtx, eFrameType);
-
- iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[pSpatialIndexMap->iDid], pCtx->iCodingIndex,
- pSvcParam->uiGopSize);
- pCtx->uiTemporalId = iCurTid;
-
+ InitBitStream (pCtx);
pLayerBsInfo->pBsBuf = pCtx->pFrameBs ;
pLayerBsInfo->pNalLengthInByte = pCtx->pOut->pNalLen;
- if (eFrameType == videoFrameTypeIDR) {
- ++ pCtx->uiIdrPicId;
- // write parameter sets bitstream or SEI/SSEI (if any) here
- // TODO: use function pointer instead
- if (! (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy)) {
- pCtx->iEncoderError = ((!pSvcParam->bSimulcastAVC)
- ? (WriteSsvcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize))
- : (WriteSavcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize)));
- } else {
- pCtx->iEncoderError = WriteSavcParaset_Listing (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize);
- }
- WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS)
- }
-
pCtx->pCurDqLayer = pCtx->ppDqLayerList[pSpatialIndexMap->iDid];
pCtx->pCurDqLayer->pRefLayer = NULL;
while (iSpatialIdx < iSpatialNum) {
- const int32_t iDidIdx = (pSpatialIndexMap + iSpatialIdx)->iDid; // get iDid
+ bool bEncoding = pCtx->pVpp->BuildSpatialLayer (pCtx, pSrcPic, iSpatialIdx);
+ if (!bEncoding) {
+ ++iSpatialIdx;
+ continue;
+ }
+ 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;
+
+ eFrameType = DecideFrameType (pCtx, iSpatialNum, iDidIdx);
+ if (eFrameType == videoFrameTypeSkip) {
+ eFrameType = videoFrameTypeSkip;
+ pLayerBsInfo->eFrameType = eFrameType;
+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
+ "[Rc] Frame timestamp = %lld, skip one frame due to target_br, continual skipped %d frames",
+ pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
+ ++ iSpatialIdx;
+ if (pSvcParam->bSimulcastAVC) {
+ if (pCtx->pFuncList->pfRc.pfWelsUpdateBufferWhenSkip)
+ pCtx->pFuncList->pfRc.pfWelsUpdateBufferWhenSkip (pCtx, iDidIdx);
+ continue;
+ }
+
+ else {
+ if (pCtx->pFuncList->pfRc.pfWelsUpdateBufferWhenSkip) {
+ for (int32_t i = 0; i < iSpatialNum; i++) {
+ pCtx->pSvcParam->sDependencyLayers[i].iSkipFrameFlag = false;
+ pCtx->pFuncList->pfRc.pfWelsUpdateBufferWhenSkip (pCtx, (pSpatialIndexMap + i)->iDid);
+ }
+ }
+ return ENC_RETURN_SUCCESS;
+ }
+ }
+ //loop each layer to check if have skip frame when RC and frame skip enable
+ if (pCtx->pFuncList->pfRc.pfWelsCheckSkipBasedMaxbr) {
+ bool bSkip = pCtx->pFuncList->pfRc.pfWelsCheckSkipBasedMaxbr (pCtx, iSpatialNum, eFrameType,
+ (uint32_t)pSrcPic->uiTimeStamp);
+ if (bSkip) {
+ eFrameType = videoFrameTypeSkip;
+ pLayerBsInfo->eFrameType = videoFrameTypeSkip;
+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
+ "[Rc] Frame timestamp = %lld, skip one frame due to max_br, continual skipped %d frames",
+ pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
+ ++ iSpatialIdx;
+ if (pSvcParam->bSimulcastAVC)
+ continue;
+ else
+ return ENC_RETURN_SUCCESS;
+ }
+ }
+ pCtx->iContinualSkipFrames = 0;
+
+ InitFrameCoding (pCtx, eFrameType, iDidIdx);
+ iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[iSpatialIdx], pParamInternal->iCodingIndex,
+ pSvcParam->uiGopSize);
+ pCtx->uiTemporalId = iCurTid;
+
+ if (eFrameType == videoFrameTypeIDR) {
+ // write parameter sets bitstream or SEI/SSEI (if any) here
+ // TODO: use function pointer instead
+ if (! (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy)) {
+ if (pSvcParam->bSimulcastAVC) {
+ pCtx->iEncoderError = WriteSavcParaset (pCtx, iCurDid, pLayerBsInfo, iLayerNum, iFrameSize);
+ ++ pCtx->uiIdrPicId;
+ } else if (!bFinishedWriteHeader) {
+ pCtx->iEncoderError = WriteSsvcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize);
+ ++ pCtx->uiIdrPicId;
+ bFinishedWriteHeader = true;
+ }
+ } else if (!bFinishedWriteHeader) {
+ pCtx->iEncoderError = WriteSavcParaset_Listing (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize);
+ bFinishedWriteHeader = true;
+ ++ pCtx->uiIdrPicId;
+ }
+ WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS)
+ }
+
pCtx->pVpp->AnalyzeSpatialPic (pCtx, iDidIdx);
pCtx->pEncPic = pEncPic = (pSpatialIndexMap + iSpatialIdx)->pSrc;
pCtx->pEncPic->iPictureType = pCtx->eSliceType;
- pCtx->pEncPic->iFramePoc = pCtx->iPOC;
+ pCtx->pEncPic->iFramePoc = pParamInternal->iPOC;
iCurWidth = pParam->iVideoWidth;
iCurHeight = pParam->iVideoHeight;
@@ -3880,12 +3929,12 @@
fsnr = pCtx->pDecPic;
#endif//#if defined(ENABLE_FRAME_DUMP) || defined(ENABLE_PSNR_CALC)
pCtx->pDecPic->iPictureType = pCtx->eSliceType;
- pCtx->pDecPic->iFramePoc = pCtx->iPOC;
+ pCtx->pDecPic->iFramePoc = pParamInternal->iPOC;
WelsInitCurrentLayer (pCtx, iCurWidth, iCurHeight);
pCtx->pFuncList->pMarkPic (pCtx);
- if (!pCtx->pFuncList->pBuildRefList (pCtx, pCtx->iPOC, 0)) {
+ if (!pCtx->pFuncList->pBuildRefList (pCtx, pParamInternal->iPOC, 0)) {
WelsLog (pLogCtx, WELS_LOG_WARNING,
"WelsEncoderEncodeExt(), WelsBuildRefList failed for P frames, pCtx->iNumRef0= %d. ForceCodingIDR!",
pCtx->iNumRef0);
@@ -3904,7 +3953,7 @@
pCtx->pVpp->AnalyzePictureComplexity (pCtx, pCtx->pEncPic, ((pCtx->eSliceType == P_SLICE)
&& (pCtx->iNumRef0 > 0)) ? pCtx->pRefList0[0] : NULL,
iCurDid, (pCtx->eSliceType == P_SLICE) && pSvcParam->bEnableBackgroundDetection);
- WelsUpdateRefSyntax (pCtx, pCtx->iPOC,
+ WelsUpdateRefSyntax (pCtx, pParamInternal->iPOC,
eFrameType); //get reordering syntax used for writing slice header and transmit to encoder.
PrefetchReferencePicture (pCtx, eFrameType); // update reference picture for current pDq layer
@@ -4033,6 +4082,7 @@
pLbi->uiQualityId = 0;
pLbi->iNalCount = 0;
pLbi->eFrameType = eFrameType;
+
int32_t iIdx = 0;
while (iIdx < kiPartitionCnt) {
pCtx->pSliceThreading->pThreadPEncCtx[iIdx].pFrameBsInfo = pFbi;
@@ -4252,7 +4302,8 @@
++ iLayerNum;
++ pLayerBsInfo;
++ pCtx->pOut->iLayerBsIndex;
-
+ WelsLog (pLogCtx, WELS_LOG_DEBUG,
+ "WelsEncoderEncodeExt() test iLayerNum = %d,iCountNal = %d,iLayerSize = %d", iLayerNum, iCountNal, iLayerSize);
pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer;
pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal;
@@ -4321,6 +4372,7 @@
&& (pCtx->pLtr[pCtx->uiDependencyId].iLTRMarkMode == LTR_DIRECT_MARK)) || eFrameType == videoFrameTypeIDR)) {
pCtx->bRefOfCurTidIsLtr[iDidIdx][iCurTid] = true;
}
+ ++ pParamInternal->iCodingIndex;
}//end of (iSpatialIdx/iSpatialNum)
if (ENC_RETURN_CORRECTED == pCtx->iEncoderError) {
@@ -4361,7 +4413,7 @@
return 1;
}
- ++ pCtx->iCodingIndex;
+
pFbi->iLayerNum = iLayerNum;
pFbi->iSubSeqId = GetSubSequenceId (pCtx, eFrameType);
@@ -4370,13 +4422,19 @@
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", i,
- pFbi->sLayerInfo[i].uiLayerType, pFbi->sLayerInfo[i].iNalCount, pFbi->sLayerInfo[i].pNalLengthInByte[0]);
+ "WelsEncoderEncodeExt() OutputInfo iLayerId = %d,iNalType = %d,iNalCount = %d, first Nal Length=%d,uiSpatialId = %d", i,
+ pFbi->sLayerInfo[i].uiLayerType, pFbi->sLayerInfo[i].iNalCount, pFbi->sLayerInfo[i].pNalLengthInByte[0],
+ pFbi->sLayerInfo[i].uiSpatialId);
WelsEmms();
- pFbi->eFrameType = eFrameType;
+ pLayerBsInfo->eFrameType = eFrameType;
pFbi->iFrameSizeInBytes = iFrameSize;
-
+ pFbi->eFrameType = eFrameType;
+ for (int32_t k = 0; k < pFbi->iLayerNum; k++) {
+ if (pFbi->eFrameType != pFbi->sLayerInfo[k].eFrameType) {
+ pFbi->eFrameType = videoFrameTypeIPMixed;
+ }
+ }
#ifdef _DEBUG
if (pFbi->iLayerNum > MAX_LAYER_NUM_OF_FRAME) {
WelsLog (& pCtx->sLogCtx, WELS_LOG_ERROR, "WelsEncoderEncodeExt(), iLayerNum(%d) > MAX_LAYER_NUM_OF_FRAME(%d)!",
@@ -4402,7 +4460,7 @@
return ENC_RETURN_UNEXPECTED;
}
#endif
-
+ WelsLog (& pCtx->sLogCtx, WELS_LOG_INFO, "return ENC_RETURN_SUCCESS");
return ENC_RETURN_SUCCESS;
}
@@ -4565,9 +4623,8 @@
// reset the scaled spatial picture size
(*ppCtx)->pVpp->WelsPreprocessReset (*ppCtx);
//if WelsInitEncoderExt succeed
-
//for LTR
- (*ppCtx)->uiIdrPicId = uiTmpIdrPicId;
+ (*ppCtx)->uiIdrPicId = uiTmpIdrPicId ;//this is for LTR!; //this is for LTR!
//for sEncoderStatistics
memcpy ((*ppCtx)->sEncoderStatistics, sTempEncoderStatistics, sizeof (sTempEncoderStatistics));
@@ -4601,7 +4658,8 @@
pOldParam->uiGopSize = pNewParam->uiGopSize;
if (pOldParam->iTemporalLayerNum != pNewParam->iTemporalLayerNum) {
pOldParam->iTemporalLayerNum = pNewParam->iTemporalLayerNum;
- (*ppCtx)->iCodingIndex = 0;
+ for (int32_t iIndexD = 0; iIndexD < MAX_DEPENDENCY_LAYER; iIndexD++)
+ pOldParam->sDependencyLayers[iIndexD].iCodingIndex = 0;
}
pOldParam->iDecompStages = pNewParam->iDecompStages;
/* denoise control */
@@ -4663,7 +4721,6 @@
memcpy (pOldDlpInternal->uiCodingIdx2TemporalId, pNewDlpInternal->uiCodingIdx2TemporalId,
sizeof (pOldDlpInternal->uiCodingIdx2TemporalId)); // confirmed_safe_unsafe_usage
-
++ iIndexD;
} while (iIndexD < pOldParam->iSpatialLayerNum);
}
--- a/codec/encoder/core/src/ratectl.cpp
+++ b/codec/encoder/core/src/ratectl.cpp
@@ -685,6 +685,7 @@
SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc;
const int32_t kiOutputBits = pWelsSvcRc->iBitsPerFrame;
const int32_t kiOutputMaxBits = pWelsSvcRc->iMaxBitsPerFrame;
+ SSpatialLayerInternal* pDLayerParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
//condition 1: whole pBuffer fullness
pWelsSvcRc->iBufferFullnessSkip += (pWelsSvcRc->iFrameDqBits - kiOutputBits);
pWelsSvcRc->iBufferMaxBRFullness[EVEN_TIME_WINDOW] += (pWelsSvcRc->iFrameDqBits - kiOutputMaxBits);
@@ -704,7 +705,7 @@
if ((pWelsSvcRc->iBufferFullnessSkip > pWelsSvcRc->iBufferSizeSkip
&& pWelsSvcRc->iAverageFrameQp > pWelsSvcRc->iSkipQpValue)
|| (dIncPercent > pWelsSvcRc->iRcVaryPercentage)) {
- pEncCtx->iSkipFrameFlag = 1;
+ pDLayerParamInternal->iSkipFrameFlag = 1;
}
}
void WelsRcFrameDelayJudge (sWelsEncCtx* pEncCtx, EVideoFrameType eFrameType, long long uiTimeStamp) {
@@ -772,35 +773,38 @@
//loop each layer to check if have skip frame when RC and frame skip enable (maxbr>0)
bool CheckFrameSkipBasedMaxbr (sWelsEncCtx* pEncCtx, int32_t iSpatialNum, EVideoFrameType eFrameType,
const uint32_t uiTimeStamp) {
- SSpatialPicIndex* pSpatialIndexMap = &pEncCtx->sSpatialIndexMap[0];
bool bSkipMustFlag = false;
if (!pEncCtx->pFuncList->pfRc.pfWelsRcPicDelayJudge)
return false;
- for (int32_t i = 0; i < iSpatialNum; i++) {
- if (UNSPECIFIED_BIT_RATE == pEncCtx->pSvcParam->sSpatialLayers[i].iMaxSpatialBitrate) {
- break;
- }
- pEncCtx->uiDependencyId = (uint8_t) (pSpatialIndexMap + i)->iDid;
+ if( pEncCtx->pSvcParam->bSimulcastAVC){
+ int32_t iDidIdx = pEncCtx->uiDependencyId;
+ if (UNSPECIFIED_BIT_RATE == pEncCtx->pSvcParam->sSpatialLayers[iDidIdx].iMaxSpatialBitrate)
+ return false;
pEncCtx->pFuncList->pfRc.pfWelsRcPicDelayJudge (pEncCtx, eFrameType, uiTimeStamp);
- if (true == pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId].bSkipFlag) {
- bSkipMustFlag = true;
- pEncCtx->iContinualSkipFrames++;
- break;
+ if (true == pEncCtx->pWelsSvcRc[iDidIdx].bSkipFlag) {
+ bSkipMustFlag = true;
+ pEncCtx->pWelsSvcRc[iDidIdx].uiLastTimeStamp = uiTimeStamp;
+ pEncCtx->iContinualSkipFrames++;
}
+ }else{
+ for(int32_t i = 0;i<iSpatialNum;i++){
+ if (UNSPECIFIED_BIT_RATE == pEncCtx->pSvcParam->sSpatialLayers[i].iMaxSpatialBitrate)
+ break;
+
+ pEncCtx->pFuncList->pfRc.pfWelsRcPicDelayJudge (pEncCtx, eFrameType, uiTimeStamp);
+ if (true == pEncCtx->pWelsSvcRc[i].bSkipFlag) {
+ bSkipMustFlag = true;
+ pEncCtx->pWelsSvcRc[i].uiLastTimeStamp = uiTimeStamp;
+ pEncCtx->iContinualSkipFrames++;
+ break;
+ }
+ }
}
- if (bSkipMustFlag) {
- for (int32_t i = 0; i < iSpatialNum; i++)
- pEncCtx->pWelsSvcRc[i].uiLastTimeStamp = uiTimeStamp;
- }
return bSkipMustFlag;
}
-void UpdateBufferWhenFrameSkipped (sWelsEncCtx* pEncCtx, int32_t iSpatialNum) {
- SSpatialPicIndex* pSpatialIndexMap = &pEncCtx->sSpatialIndexMap[0];
-
- for (int32_t i = 0; i < iSpatialNum; i++) {
- int32_t iCurDid = (pSpatialIndexMap + i)->iDid;
+void UpdateBufferWhenFrameSkipped (sWelsEncCtx* pEncCtx, int32_t iCurDid) {
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[iCurDid];
const int32_t kiOutputBits = pWelsSvcRc->iBitsPerFrame;
const int32_t kiOutputMaxBits = pWelsSvcRc->iMaxBitsPerFrame;
@@ -817,7 +821,6 @@
pWelsSvcRc->iSkipFrameNum++;
pWelsSvcRc->iSkipFrameInVGop++;
- }
pEncCtx->iContinualSkipFrames++;
if ((pEncCtx->iContinualSkipFrames % 3) == 0) {
//output a warning when iContinualSkipFrames is large enough, which may indicate subjective quality problem
@@ -906,7 +909,7 @@
void RcTraceFrameBits (sWelsEncCtx* pEncCtx, long long uiTimeStamp) {
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
-
+ SSpatialLayerInternal *pParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
if (pWelsSvcRc->iPredFrameBit != 0)
pWelsSvcRc->iPredFrameBit = (int32_t) (LAST_FRAME_PREDICT_WEIGHT * pWelsSvcRc->iFrameDqBits +
(1 - LAST_FRAME_PREDICT_WEIGHT) * pWelsSvcRc->iPredFrameBit);
@@ -919,7 +922,7 @@
pEncCtx->uiDependencyId, uiTimeStamp, pEncCtx->eSliceType, pEncCtx->iGlobalQp, pWelsSvcRc->iAverageFrameQp,
pWelsSvcRc->iMaxFrameQp,
pWelsSvcRc->iMinFrameQp,
- pEncCtx->iFrameIndex, pEncCtx->uiTemporalId, pWelsSvcRc->iFrameDqBits, pWelsSvcRc->iBitsPerFrame,
+ pParamInternal->iFrameIndex, pEncCtx->uiTemporalId, pWelsSvcRc->iFrameDqBits, pWelsSvcRc->iBitsPerFrame,
pWelsSvcRc->iTargetBits, pWelsSvcRc->iRemainingBits, pWelsSvcRc->iBufferSizeSkip);
}
--- a/codec/encoder/core/src/ref_list_mgr_svc.cpp
+++ b/codec/encoder/core/src/ref_list_mgr_svc.cpp
@@ -155,6 +155,7 @@
SLTRState* pLtr = &pCtx->pLtr[pCtx->uiDependencyId];
int32_t iMaxFrameNumPlus1 = (1 << pCtx->pSps->uiLog2MaxFrameNum);
int32_t i;
+ SSpatialLayerInternal *pParamInternal = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
SLogContext* pLogCtx = & (pCtx->sLogCtx);
for (i = 0; i < LONG_TERM_REF_NUM; i++) {
@@ -168,7 +169,7 @@
DeleteLTRFromLongList (pCtx, i);
pLtr->bLTRMarkEnable = true;
if (pRefList->uiLongRefCount == 0) {
- pCtx->bEncCurFrmAsIdrFlag = true;
+ pParamInternal->bEncCurFrmAsIdrFlag = true;
}
} else if (CompareFrameNum (pLongRefList[i]->iMarkFrameNum , pLtr->iLastCorFrameNumDec ,
iMaxFrameNumPlus1) == FRAME_NUM_BIGGER
@@ -181,7 +182,7 @@
DeleteLTRFromLongList (pCtx, i);
pLtr->bLTRMarkEnable = true;
if (pRefList->uiLongRefCount == 0) {
- pCtx->bEncCurFrmAsIdrFlag = true;
+ pParamInternal->bEncCurFrmAsIdrFlag = true;
}
}
}
@@ -195,12 +196,13 @@
SRefList* pRefList = pCtx->ppRefPicListExt[pCtx->uiDependencyId];
SPicture** pLongRefList = pRefList->pLongRefList;
SLTRState* pLtr = &pCtx->pLtr[pCtx->uiDependencyId];
+ SSpatialLayerInternal *pParamInternal = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
int32_t i, j;
if (pLtr->uiLtrMarkState == LTR_MARKING_SUCCESS) {
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
"pLtr->uiLtrMarkState = %d, pLtr.iCurLtrIdx = %d , pLtr->iLtrMarkFbFrameNum = %d ,pCtx->iFrameNum = %d ",
- pLtr->uiLtrMarkState, pLtr->iCurLtrIdx, pLtr->iLtrMarkFbFrameNum, pCtx->iFrameNum);
+ pLtr->uiLtrMarkState, pLtr->iCurLtrIdx, pLtr->iLtrMarkFbFrameNum, pParamInternal->iFrameNum);
for (i = 0; i < pRefList->uiLongRefCount; i++) {
if (pLongRefList[i]->iFrameNum == pLtr->iLtrMarkFbFrameNum && pLongRefList[i]->uiRecieveConfirmed != RECIEVE_SUCCESS) {
@@ -239,7 +241,7 @@
pLtr->bLTRMarkEnable = true;
if (pLtr->iLTRMarkSuccessNum == 0) {
- pCtx->bEncCurFrmAsIdrFlag = true; // no LTR , means IDR recieve failed, force next frame IDR
+ pParamInternal->bEncCurFrmAsIdrFlag = true; // no LTR , means IDR recieve failed, force next frame IDR
}
}
}
@@ -256,6 +258,7 @@
int32_t i = 0;
int32_t j = 0;
bool bMoveLtrFromShortToLong = false;
+ SSpatialLayerInternal *pParamInternal = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
if (pCtx->eSliceType == I_SLICE) {
i = 0;
@@ -265,7 +268,7 @@
if (pLtr->iLTRMarkMode == LTR_DELAY_MARK) {
for (i = 0; i < pRefList->uiShortRefCount; i++) {
- if (CompareFrameNum (pCtx->iFrameNum, pShortRefList[i]->iFrameNum + iGoPFrameNumInterval,
+ if (CompareFrameNum (pParamInternal->iFrameNum, pShortRefList[i]->iFrameNum + iGoPFrameNumInterval,
iMaxFrameNumPlus1) == FRAME_NUM_EQUAL) {
break;
}
@@ -276,7 +279,7 @@
if (pCtx->eSliceType == I_SLICE || pLtr->bLTRMarkingFlag) {
pShortRefList[i]->bIsLongRef = true;
pShortRefList[i]->iLongTermPicNum = pLtr->iCurLtrIdx;
- pShortRefList[i]->iMarkFrameNum = pCtx->iFrameNum;
+ pShortRefList[i]->iMarkFrameNum = pParamInternal->iFrameNum;
}
// delay one gop to move LTR from int16_t list to int32_t list
@@ -376,8 +379,8 @@
// move picture in list
pCtx->pDecPic->uiTemporalId = kuiTid;
pCtx->pDecPic->uiSpatialId = kuiDid;
- pCtx->pDecPic->iFrameNum = pCtx->iFrameNum;
- pCtx->pDecPic->iFramePoc = pCtx->iPOC;
+ pCtx->pDecPic->iFrameNum = pParamD->iFrameNum;
+ pCtx->pDecPic->iFramePoc = pParamD->iPOC;
pCtx->pDecPic->uiRecieveConfirmed = RECIEVE_UNKOWN;
pCtx->pDecPic->bUsedAsRef = true;
@@ -405,7 +408,7 @@
DeleteSTRFromShortList (pCtx, i);
}
if (pRefList->uiShortRefCount > 0 && (pRefList->pShortRefList[0]->uiTemporalId > 0
- || pRefList->pShortRefList[0]->iFrameNum != pCtx->iFrameNum)) {
+ || pRefList->pShortRefList[0]->iFrameNum != pParamD->iFrameNum)) {
pRefList->pShortRefList[0]->SetUnref();
DeleteSTRFromShortList (pCtx, 0);
}
@@ -433,11 +436,12 @@
SPicture** pLongRefList = pRefList->pLongRefList;
int32_t iGoPFrameNumInterval = ((pCtx->pSvcParam->uiGopSize >> 1) > 1) ? (pCtx->pSvcParam->uiGopSize >> 1) : (1);
int32_t iMaxFrameNumPlus1 = (1 << pCtx->pSps->uiLog2MaxFrameNum);
+ SSpatialLayerInternal *pParamInternal = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
int32_t i;
for (i = 0; i < pRefList->uiLongRefCount; i++) {
- if ((pCtx->iFrameNum == pLongRefList[i]->iFrameNum && pLtr->iLTRMarkMode == LTR_DIRECT_MARK) ||
- (CompareFrameNum (pCtx->iFrameNum + iGoPFrameNumInterval, pLongRefList[i]->iFrameNum,
+ if ((pParamInternal->iFrameNum == pLongRefList[i]->iFrameNum && pLtr->iLTRMarkMode == LTR_DIRECT_MARK) ||
+ (CompareFrameNum (pParamInternal->iFrameNum + iGoPFrameNumInterval, pLongRefList[i]->iFrameNum,
iMaxFrameNumPlus1) == FRAME_NUM_EQUAL && pLtr->iLTRMarkMode == LTR_DELAY_MARK)) {
return false;
}
@@ -513,10 +517,11 @@
SLTRRecoverRequest* pRequest = pLTRRecoverRequest;
SLTRState* pLtr = &pCtx->pLtr[pCtx->uiDependencyId];
int32_t iMaxFrameNumPlus1 = (1 << pCtx->pSps->uiLog2MaxFrameNum);
+ SSpatialLayerInternal* pParamInternal = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
if (pCtx->pSvcParam->bEnableLongTermReference) {
if (pRequest->uiFeedbackType == LTR_RECOVERY_REQUEST && pRequest->uiIDRPicId == pCtx->uiIdrPicId) {
if (pRequest->iLastCorrectFrameNum == -1) {
- pCtx->bEncCurFrmAsIdrFlag = true;
+ pParamInternal->bEncCurFrmAsIdrFlag = true;
return true;
} else if (pRequest->iCurrentFrameNum == -1) {
pLtr->bReceivedT0LostFlag = true;
@@ -541,7 +546,7 @@
, pRequest->uiFeedbackType, pRequest->uiIDRPicId, pRequest->iCurrentFrameNum, pRequest->iLastCorrectFrameNum);
}
} else if (!pCtx->pSvcParam->bEnableLongTermReference) {
- pCtx->bEncCurFrmAsIdrFlag = true;
+ pParamInternal->bEncCurFrmAsIdrFlag = true;
}
return true;
}
@@ -577,7 +582,7 @@
const int32_t kiNumRef = pCtx->pSvcParam->iNumRefFrame;
const uint8_t kuiTid = pCtx->uiTemporalId;
uint32_t i = 0;
-
+ SSpatialLayerInternal* pParamD = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
// to support any type of cur_dq->mgs_control
// [ 0: using current layer to do ME/MC;
// -1: using store base layer to do ME/MC;
@@ -586,13 +591,12 @@
// build reference list 0/1 if applicable
pCtx->iNumRef0 = 0;
-
if (pCtx->eSliceType != I_SLICE) {
if (pCtx->pSvcParam->bEnableLongTermReference && pLtr->bReceivedT0LostFlag && pCtx->uiTemporalId == 0) {
for (i = 0; i < pRefList->uiLongRefCount; i++) {
if (pRefList->pLongRefList[i]->uiRecieveConfirmed == RECIEVE_SUCCESS) {
pCtx->pRefList0[pCtx->iNumRef0++] = pRefList->pLongRefList[i];
- pLtr->iLastRecoverFrameNum = pCtx->iFrameNum;
+ pLtr->iLastRecoverFrameNum = pParamD->iFrameNum;
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
"pRef is int32_t !iLastRecoverFrameNum = %d, pRef iFrameNum = %d,LTR number = %d,",
pLtr->iLastRecoverFrameNum, pCtx->pRefList0[0]->iFrameNum, pRefList->uiLongRefCount);
@@ -690,18 +694,18 @@
int32_t iAbsDiffPicNumMinus1 = -1;
SSlice* pSliceList = NULL;
-
+ SSpatialLayerInternal* pParamD = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
/*syntax for ref_pic_list_reordering()*/
- if (pCtx->iNumRef0 > 0) {
- iAbsDiffPicNumMinus1 = pCtx->iFrameNum - (pCtx->pRefList0[0]->iFrameNum) - 1;
+ if (pCtx->iNumRef0 > 0){
+ iAbsDiffPicNumMinus1 = pParamD->iFrameNum - (pCtx->pRefList0[0]->iFrameNum) - 1;
if (iAbsDiffPicNumMinus1 < 0) {
- WelsLog(&(pCtx->sLogCtx), WELS_LOG_INFO, "WelsUpdateRefSyntax():::uiAbsDiffPicNumMinus1:%d", iAbsDiffPicNumMinus1);
- iAbsDiffPicNumMinus1 += (1 << (pCtx->pSps->uiLog2MaxFrameNum));
- WelsLog(&(pCtx->sLogCtx), WELS_LOG_INFO, "WelsUpdateRefSyntax():::uiAbsDiffPicNumMinus1< 0, update as:%d",
+ WelsLog(&(pCtx->sLogCtx), WELS_LOG_INFO, "WelsUpdateRefSyntax():::uiAbsDiffPicNumMinus1:%d", iAbsDiffPicNumMinus1);
+ iAbsDiffPicNumMinus1 += (1 << (pCtx->pSps->uiLog2MaxFrameNum));
+ WelsLog(&(pCtx->sLogCtx), WELS_LOG_INFO, "WelsUpdateRefSyntax():::uiAbsDiffPicNumMinus1< 0, update as:%d",
iAbsDiffPicNumMinus1);
- }
}
+ }
if (pCtx->iActiveThreadsNum >0) {
// to do: will replace with thread based buffer later
@@ -772,8 +776,8 @@
// move picture in list
pCtx->pDecPic->uiTemporalId = pCtx->uiTemporalId;
pCtx->pDecPic->uiSpatialId = pCtx->uiDependencyId;
- pCtx->pDecPic->iFrameNum = pCtx->iFrameNum;
- pCtx->pDecPic->iFramePoc = pCtx->iPOC;
+ pCtx->pDecPic->iFrameNum = pParamD->iFrameNum;
+ pCtx->pDecPic->iFramePoc = pParamD->iPOC;
pCtx->pDecPic->bUsedAsRef = true;
pCtx->pDecPic->bIsLongRef = true;
pCtx->pDecPic->bIsSceneLTR = pLtr->bLTRMarkingFlag || (pCtx->pSvcParam->bEnableLongTermReference
@@ -801,6 +805,7 @@
SWelsSvcCodingParam* pParam = pCtx->pSvcParam;
SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (pCtx->pVaa);
const int32_t iNumRef = pParam->iNumRefFrame;
+ SSpatialLayerInternal* pParamD = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
pCtx->iNumRef0 = 0;
if (pCtx->eSliceType != I_SLICE) {
@@ -816,7 +821,7 @@
pCtx->pRefList0[pCtx->iNumRef0++] = pRefPic;
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
"WelsBuildRefListScreen(), current iFrameNum = %d, current Tid = %d, ref iFrameNum = %d, ref uiTemporalId = %d, ref is Scene LTR = %d, LTR count = %d,iNumRef = %d",
- pCtx->iFrameNum, pCtx->uiTemporalId,
+ pParamD->iFrameNum, pCtx->uiTemporalId,
pRefPic->iFrameNum, pRefPic->uiTemporalId, pRefPic->bIsSceneLTR,
pRefList->uiLongRefCount, iNumRef);
}
@@ -831,7 +836,7 @@
pCtx->pRefList0[pCtx->iNumRef0++] = pRefList->pLongRefList[i];
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
"WelsBuildRefListScreen(), ref !current iFrameNum = %d, ref iFrameNum = %d,LTR number = %d",
- pCtx->iFrameNum, pCtx->pRefList0[pCtx->iNumRef0 - 1]->iFrameNum, pRefList->uiLongRefCount);
+ pParamD->iFrameNum, pCtx->pRefList0[pCtx->iNumRef0 - 1]->iFrameNum, pRefList->uiLongRefCount);
break;
}
}
@@ -902,7 +907,7 @@
int32_t iMaxTid = WELS_LOG2 (pCtx->pSvcParam->uiGopSize);
int32_t iMaxActualLtrIdx = -1;
SSlice* pSliceList = NULL;
-
+ SSpatialLayerInternal* pParamD = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
if (pCtx->pSvcParam->bEnableLongTermReference)
iMaxActualLtrIdx = pCtx->pSvcParam->iNumRefFrame - STR_ROOM - 1 - WELS_MAX (iMaxTid , 1);
@@ -953,9 +958,9 @@
if (ppLongRefList[i]->bUsedAsRef && ppLongRefList[i]->bIsLongRef && (!ppLongRefList[i]->bIsSceneLTR)
&& iMaxMultiRefTid == ppLongRefList[i]->uiTemporalId) {
assert (IsValidFrameNum (ppLongRefList[i]->iFrameNum)); // pLtr->iCurLtrIdx must have a value
- int32_t iDeltaFrameNum = (pCtx->iFrameNum >= ppLongRefList[i]->iFrameNum)
- ? (pCtx->iFrameNum - ppLongRefList[i]->iFrameNum)
- : (pCtx->iFrameNum + iMaxFrameNum - ppLongRefList[i]->iFrameNum);
+ int32_t iDeltaFrameNum = (pParamD->iFrameNum >= ppLongRefList[i]->iFrameNum)
+ ? (pParamD->iFrameNum - ppLongRefList[i]->iFrameNum)
+ : (pParamD->iFrameNum + iMaxFrameNum - ppLongRefList[i]->iFrameNum);
if (iDeltaFrameNum > iLongestDeltaFrameNum) {
pLtr->iCurLtrIdx = ppLongRefList[i]->iLongTermPicNum;
--- a/codec/encoder/core/src/slice_multi_threading.cpp
+++ b/codec/encoder/core/src/slice_multi_threading.cpp
@@ -679,7 +679,7 @@
const int32_t kiFirstMbInPartition = pPrivateData->iStartMbIndex; // inclusive
const int32_t kiEndMbInPartition = pPrivateData->iEndMbIndex; // exclusive
int32_t iAnyMbLeftInPartition = kiEndMbInPartition - kiFirstMbInPartition;
-
+ SSpatialLayerInternal *pParamInternal = &pCodingParam->sDependencyLayers[kiCurDid];
iSliceIdx = pPrivateData->iSliceIndex;
SSliceHeaderExt* pStartSliceHeaderExt = &pCurDq->sLayerInfo.pSliceInLayer[iSliceIdx].sSliceHeaderExt;
pStartSliceHeaderExt->sSliceHeader.iFirstMbInSlice = kiFirstMbInPartition;
@@ -695,7 +695,7 @@
uiThrdRet = 1;
WelsLog (&pEncPEncCtx->sLogCtx, WELS_LOG_WARNING,
"[MT] CodingSliceThreadProc Too many slices: coding_idx %d, iSliceIdx %d, pSliceCtx->iMaxSliceNumConstraint %d",
- pEncPEncCtx->iCodingIndex,
+ pParamInternal->iCodingIndex,
iSliceIdx, pSliceCtx->iMaxSliceNumConstraint);
WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent,
pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent,
@@ -740,7 +740,7 @@
uiThrdRet = iReturn;
WelsLog (&pEncPEncCtx->sLogCtx, WELS_LOG_WARNING,
"[MT] CodingSliceThreadProc, WriteSliceBs not successful: coding_idx %d, iSliceIdx %d, BufferSize %d, m_iSliceSize %d, iPayloadSize %d",
- pEncPEncCtx->iCodingIndex,
+ pParamInternal->iCodingIndex,
iSliceIdx, pSliceBs->uiSize, iSliceSize, pSliceBs->sNalList[0].iPayloadSize);
WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent,
--- a/codec/encoder/core/src/svc_encode_slice.cpp
+++ b/codec/encoder/core/src/svc_encode_slice.cpp
@@ -89,7 +89,7 @@
void WelsSliceHeaderExtInit (sWelsEncCtx* pEncCtx, SDqLayer* pCurLayer, SSlice* pSlice) {
SSliceHeaderExt* pCurSliceExt = &pSlice->sSliceHeaderExt;
SSliceHeader* pCurSliceHeader = &pCurSliceExt->sSliceHeader;
-
+ SSpatialLayerInternal *pParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
pCurSliceHeader->eSliceType = pEncCtx->eSliceType;
pCurSliceExt->bStoreRefBasePicFlag = false;
@@ -96,7 +96,7 @@
pCurSliceHeader->iFirstMbInSlice = WelsGetFirstMbOfSlice (pCurLayer->sLayerInfo.pSliceInLayer, pSlice->uiSliceIdx);
- pCurSliceHeader->iFrameNum = pEncCtx->iFrameNum;
+ pCurSliceHeader->iFrameNum = pParamInternal->iFrameNum;
pCurSliceHeader->uiIdrPicId = pEncCtx->uiIdrPicId;
pCurSliceHeader->iPicOrderCntLsb = pEncCtx->pEncPic->iFramePoc; // 0
--- a/codec/encoder/core/src/wels_preprocess.cpp
+++ b/codec/encoder/core/src/wels_preprocess.cpp
@@ -185,8 +185,9 @@
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);
+ 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)
@@ -201,8 +202,6 @@
return -1;
pCtx->pVaa->bSceneChangeFlag = pCtx->pVaa->bIdrPeriodFlag = false;
- if (pSvcParam->uiIntraPeriod)
- pCtx->pVaa->bIdrPeriodFlag = (1 + pCtx->iFrameIndex >= (int32_t)pSvcParam->uiIntraPeriod) ? true : false;
iSpatialNum = SingleLayerPreprocess (pCtx, kpSrcPic, &m_sScaledPicture);
@@ -213,10 +212,10 @@
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][pCtx->iCodingIndex &
+ 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;
@@ -253,7 +252,10 @@
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);
}
}
@@ -285,6 +287,8 @@
}
WelsExchangeSpatialPictures (&m_pSpatialPic[kiDidx][kiCurPos],
&m_pSpatialPic[kiDidx][iCurTid]);
+
+
}
return 0;
}
@@ -294,6 +298,43 @@
* 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 iSrcWidth = pSvcParam->SUsedPicRect.iWidth;
+ int32_t iSrcHeight = pSvcParam->SUsedPicRect.iHeight;
+ 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 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;
@@ -310,19 +351,22 @@
int32_t iTargetWidth = 0;
int32_t iTargetHeight = 0;
int32_t iTemporalId = 0;
- int32_t iActualSpatialLayerNum = 0;
pDlayerParamInternal = &pSvcParam->sDependencyLayers[iDependencyId];
pDlayerParam = &pSvcParam->sSpatialLayers[iDependencyId];
iTargetWidth = pDlayerParam->iVideoWidth;
iTargetHeight = pDlayerParam->iVideoHeight;
- iTemporalId = pDlayerParamInternal->uiCodingIdx2TemporalId[pCtx->iCodingIndex & (pSvcParam->uiGopSize - 1)];
+ 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)
@@ -343,11 +387,13 @@
if (pSvcParam->bEnableSceneChangeDetect && !pCtx->pVaa->bIdrPeriodFlag) {
if (pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {
- pCtx->pVaa->eSceneChangeIdc = (pCtx->bEncCurFrmAsIdrFlag ? LARGE_CHANGED_SCENE : DetectSceneChangeScreen (pCtx,
- pDstPic));
+ pCtx->pVaa->eSceneChangeIdc = (pDlayerParamInternal->bEncCurFrmAsIdrFlag ? LARGE_CHANGED_SCENE :
+ DetectSceneChangeScreen (pCtx,
+ pDstPic));
pCtx->pVaa->bSceneChangeFlag = (LARGE_CHANGED_SCENE == pCtx->pVaa->eSceneChangeIdc);
} else {
- if ((!pCtx->bEncCurFrmAsIdrFlag) && ! (pCtx->iCodingIndex & (pSvcParam->uiGopSize - 1))) {
+ 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];
@@ -357,61 +403,28 @@
}
}
- for (int32_t i = 0; i < pSvcParam->iSpatialLayerNum; i++) {
- if (pSvcParam->sDependencyLayers[i].uiCodingIdx2TemporalId[pCtx->iCodingIndex & (pSvcParam->uiGopSize - 1)]
- != INVALID_TEMPORAL_ID) {
- ++ iActualSpatialLayerNum;
- }
- }
+ WelsUpdateSpatialIdxMap (pCtx, iDependencyId, pDstPic, iDependencyId);
+ m_pLastSpatialPicture[iDependencyId][1] = m_pSpatialPic[iDependencyId][iPicturePos];
if (iTemporalId != INVALID_TEMPORAL_ID) {
- WelsUpdateSpatialIdxMap (pCtx, iActualSpatialLayerNum - 1, pDstPic, iDependencyId);
++ iSpatialNum;
- -- iActualSpatialLayerNum;
}
-
- 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];
- iTargetWidth = pDlayerParam->iVideoWidth;
- iTargetHeight = pDlayerParam->iVideoHeight;
- iTemporalId = pDlayerParamInternal->uiCodingIdx2TemporalId[pCtx->iCodingIndex & (pSvcParam->uiGopSize - 1)];
- iPicturePos = m_uiSpatialLayersInTemporal[iDependencyId] - 1;
+ iTemporalId = pDlayerParamInternal->uiCodingIdx2TemporalId[pDlayerParamInternal->iCodingIndex &
+ (pSvcParam->uiGopSize - 1)];
- // NOT work for CGS, FIXME
- // spatial layer is able to encode indeed
if ((iTemporalId != INVALID_TEMPORAL_ID)) {
- // down sampling performed
-
- 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, iActualSpatialLayerNum - 1, pDstPic, iDependencyId);
-
- -- iActualSpatialLayerNum;
++ iSpatialNum;
-
- m_pLastSpatialPicture[iDependencyId][1] = m_pSpatialPic[iDependencyId][iPicturePos];
}
-- iDependencyId;
}
}
-
return iSpatialNum;
-}
-
+}
/*!
* \brief Whether input picture need be scaled?
*/
@@ -999,6 +1012,7 @@
#define STATIC_SCENE_MOTION_RATIO 0.01f
SWelsSvcCodingParam* pSvcParam = pCtx->pSvcParam;
SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (pCtx->pVaa);
+ SSpatialLayerInternal* pParamInternal = &pSvcParam->sDependencyLayers[0];
if (NULL == pCtx || NULL == pVaaExt || NULL == pCurPicture) {
return LARGE_CHANGED_SCENE;
}
@@ -1040,7 +1054,7 @@
const int32_t iNegligibleMotionBlocks = (static_cast<int32_t> ((pCurPicture->iWidthInPixel >> 3) *
(pCurPicture->iHeightInPixel >> 3) * STATIC_SCENE_MOTION_RATIO));
const uint8_t iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[m_pEncCtx->sSpatialIndexMap[0].iDid],
- m_pEncCtx->iCodingIndex, pSvcParam->uiGopSize);
+ pParamInternal->iCodingIndex, pSvcParam->uiGopSize);
if (iCurTid == INVALID_TEMPORAL_ID) {
return LARGE_CHANGED_SCENE;
}
@@ -1135,7 +1149,7 @@
}
WelsLog (pLogCtx, WELS_LOG_DEBUG, "iVaaFrameSceneChangeIdc = %d,codingIdx = %d", iVaaFrameSceneChangeIdc,
- pCtx->iCodingIndex);
+ pParamInternal->iCodingIndex);
SaveBestRefToVaa (sLtrSaved, & (pVaaExt->sVaaStrBestRefCandidate[0]));
pVaaExt->iVaaBestRefFrameNum = sLtrSaved.pRefPicture->iFrameNum;
--- a/codec/encoder/core/src/wels_task_encoder.cpp
+++ b/codec/encoder/core/src/wels_task_encoder.cpp
@@ -145,7 +145,7 @@
#if MT_DEBUG_BS_WR
m_pSliceBs->bSliceCodedFlag = false;
#endif//MT_DEBUG_BS_WR
-
+ SSpatialLayerInternal *pParamInternal = &m_pCtx->pSvcParam->sDependencyLayers[m_pCtx->uiDependencyId];
if (m_bNeedPrefix) {
if (m_eNalRefIdc != NRI_PRI_LOWEST) {
WelsLoadNalForSlice (m_pSliceBs, NAL_UNIT_PREFIX, m_eNalRefIdc);
@@ -171,7 +171,7 @@
if (ENC_RETURN_SUCCESS != iReturn) {
WelsLog (&m_pCtx->sLogCtx, WELS_LOG_WARNING,
"[MT] CWelsSliceEncodingTask ExecuteTask(), WriteSliceBs not successful: coding_idx %d, um_iSliceIdx %d",
- m_pCtx->iCodingIndex,
+ pParamInternal->iCodingIndex,
m_iSliceIdx);
return iReturn;
}
@@ -209,11 +209,11 @@
void CWelsLoadBalancingSlicingEncodingTask::FinishTask() {
CWelsSliceEncodingTask::FinishTask();
-
+ SSpatialLayerInternal *pParamInternal = &m_pCtx->pSvcParam->sDependencyLayers[m_pCtx->uiDependencyId];
m_pSlice->uiSliceConsumeTime = (uint32_t) (WelsTime() - m_iSliceStart);
WelsLog (&m_pCtx->sLogCtx, WELS_LOG_DEBUG,
"[MT] CWelsLoadBalancingSlicingEncodingTask()FinishTask, coding_idx %d, um_iSliceIdx %d, uiSliceConsumeTime %d, m_iSliceSize %d, iFirstMbInSlice %d, count_num_mb_in_slice %d at time=%" PRId64,
- m_pCtx->iCodingIndex,
+ pParamInternal->iCodingIndex,
m_iSliceIdx,
m_pSlice->uiSliceConsumeTime,
m_iSliceSize,
@@ -230,7 +230,7 @@
SSliceCtx* pSliceCtx = &pCurDq->sSliceEncCtx;
const int32_t kiSliceIdxStep = m_pCtx->iActiveThreadsNum;
-
+ SSpatialLayerInternal *pParamInternal = &m_pCtx->pSvcParam->sDependencyLayers[m_pCtx->uiDependencyId];
SSliceHeaderExt* pStartSliceHeaderExt = &pCurDq->sLayerInfo.pSliceInLayer[m_iSliceIdx].sSliceHeaderExt;
//deal with partition: TODO: here SSliceThreadPrivateData is just for parition info and actually has little relationship with threadbuffer, and iThreadIndex is not used in threadpool model, need renaming after removing old logic to avoid confusion
@@ -252,7 +252,7 @@
if (iLocalSliceIdx >= pSliceCtx->iMaxSliceNumConstraint) {
WelsLog (&m_pCtx->sLogCtx, WELS_LOG_WARNING,
"[MT] CWelsConstrainedSizeSlicingEncodingTask ExecuteTask() coding_idx %d, uiLocalSliceIdx %d, pSliceCtx->iMaxSliceNumConstraint %d",
- m_pCtx->iCodingIndex,
+ pParamInternal->iCodingIndex,
iLocalSliceIdx, pSliceCtx->iMaxSliceNumConstraint);
return ENC_RETURN_KNOWN_ISSUE;
}
@@ -288,7 +288,7 @@
if (ENC_RETURN_SUCCESS != iReturn) {
WelsLog (&m_pCtx->sLogCtx, WELS_LOG_WARNING,
"[MT] CWelsConstrainedSizeSlicingEncodingTask ExecuteTask(), WriteSliceBs not successful: coding_idx %d, uiLocalSliceIdx %d, BufferSize %d, m_iSliceSize %d, iPayloadSize %d",
- m_pCtx->iCodingIndex,
+ pParamInternal->iCodingIndex,
iLocalSliceIdx, m_pSliceBs->uiSize, m_iSliceSize, m_pSliceBs->sNalList[0].iPayloadSize);
return iReturn;
}
@@ -305,7 +305,7 @@
WelsLog (&m_pCtx->sLogCtx, WELS_LOG_DEBUG,
"[MT] CWelsConstrainedSizeSlicingEncodingTask(), coding_idx %d, iPartitionId %d, m_iThreadIdx %d, iLocalSliceIdx %d, m_iSliceSize %d, ParamValidationExt(), invalid uiMaxNalSizeiEndMbInPartition %d, pCurDq->pLastCodedMbIdxOfPartition[%d] %d\n",
- m_pCtx->iCodingIndex, kiPartitionId, m_iThreadIdx, iLocalSliceIdx, m_iSliceSize,
+ pParamInternal->iCodingIndex, kiPartitionId, m_iThreadIdx, iLocalSliceIdx, m_iSliceSize,
kiEndMbInPartition, kiPartitionId, pCurDq->pLastCodedMbIdxOfPartition[kiPartitionId]);
iAnyMbLeftInPartition = kiEndMbInPartition - (1 + pCurDq->pLastCodedMbIdxOfPartition[kiPartitionId]);
--- a/test/api/encode_options_test.cpp
+++ b/test/api/encode_options_test.cpp
@@ -1391,6 +1391,7 @@
sParam.sSpatialLayers[2].sSliceArgument.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
sParam.sSpatialLayers[2].sSliceArgument.uiSliceNum = (rand() % 30) + 1;
+
int rv = encoder_->InitializeExt (&sParam);
ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam: rv = " << rv;;