Merge pull request #2329 from ruil2/layer4

using independent encoder control logic for SAVC case
This commit is contained in:
HaiboZhu 2016-01-15 09:27:58 +08:00
commit 67f925674a
13 changed files with 405 additions and 313 deletions

View File

@ -82,11 +82,11 @@ int32_t InitFunctionPointers (sWelsEncCtx* pEncCtx, SWelsSvcCodingParam* _param,
/*!
* \brief initialize frame coding
*/
void InitFrameCoding (sWelsEncCtx* pEncCtx, const EVideoFrameType keFrameType);
void LoadBackFrameNum(sWelsEncCtx* pEncCtx);
EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum);
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,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

View File

@ -149,10 +149,7 @@ typedef struct TagWelsEncCtx {
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 @@ typedef struct TagWelsEncCtx {
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 @@ typedef struct TagWelsEncCtx {
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

View File

@ -86,7 +86,13 @@ typedef struct TagDLayerParam {
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

View File

@ -140,7 +140,7 @@ 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

@ -211,7 +211,7 @@ int32_t InitFunctionPointers (sWelsEncCtx* pEncCtx, SWelsSvcCodingParam* pParam,
/*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,87 +226,97 @@ int32_t InitFunctionPointers (sWelsEncCtx* pEncCtx, SWelsSvcCodingParam* pParam,
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
}
for (int32_t i=0; i<MAX_DEPENDENCY_LAYER; i++) {
pEncCtx->eLastNalPriority[i] = NRI_PRI_LOWEST;
pParamInternal->iFrameNum = 0; // if iFrameNum overflow
}
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;
}
}
if (bNeedFrameNumIncreasing) {
if (pEncCtx->iFrameNum != 0) {
pEncCtx->iFrameNum --;
} else {
pEncCtx->iFrameNum = (1 << pEncCtx->pSps->uiLog2MaxFrameNum) - 1;
}
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;
}
}
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
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 @@ void InitFrameCoding (sWelsEncCtx* pEncCtx, const EVideoFrameType keFrameType) {
#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 @@ EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum
} 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 @@ EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum
} 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 @@ EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum
// 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 @@ EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum
//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;

View File

@ -1206,6 +1206,7 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p
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 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p
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 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx, SExistingParasetList* pExistingPa
(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 @@ void WelsInitCurrentLayer (sWelsEncCtx* pCtx,
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 @@ void WelsInitCurrentLayer (sWelsEncCtx* pCtx,
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 WritePadding (sWelsEncCtx* pCtx, int32_t iLen, int32_t& iSize) {
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 @@ int32_t WelsEncoderEncodeParameterSets (sWelsEncCtx* pCtx, void* pDst) {
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,75 +3492,69 @@ int32_t WriteSsvcParaset (sWelsEncCtx* pCtx, const int32_t kiSpatialNum,
}
// 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;
// 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 @@ int32_t WriteSavcParaset_Listing (sWelsEncCtx* pCtx, const int32_t kiSpatialNum,
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 @@ void StackBackEncoderStatus (sWelsEncCtx* pEncCtx,
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 @@ void ClearFrameBsInfo (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi) {
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 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
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 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
#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,76 +3755,116 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
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",
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 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
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 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
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 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
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 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
++ 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 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
&& (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 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
return 1;
}
++ pCtx->iCodingIndex;
pFbi->iLayerNum = iLayerNum;
pFbi->iSubSeqId = GetSubSequenceId (pCtx, eFrameType);
@ -4370,13 +4422,19 @@ 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", 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 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
return ENC_RETURN_UNEXPECTED;
}
#endif
WelsLog (& pCtx->sLogCtx, WELS_LOG_INFO, "return ENC_RETURN_SUCCESS");
return ENC_RETURN_SUCCESS;
}
@ -4565,9 +4623,8 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
// 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 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
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 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
memcpy (pOldDlpInternal->uiCodingIdx2TemporalId, pNewDlpInternal->uiCodingIdx2TemporalId,
sizeof (pOldDlpInternal->uiCodingIdx2TemporalId)); // confirmed_safe_unsafe_usage
++ iIndexD;
} while (iIndexD < pOldParam->iSpatialLayerNum);
}

View File

@ -685,6 +685,7 @@ void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) {
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 @@ void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) {
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 @@ void WelsRcFrameDelayJudge (sWelsEncCtx* pEncCtx, EVideoFrameType eFrameType, lo
//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 @@ void UpdateBufferWhenFrameSkipped (sWelsEncCtx* pEncCtx, int32_t iSpatialNum) {
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 RcVBufferCalculationPadding (sWelsEncCtx* pEncCtx) {
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 @@ void RcTraceFrameBits (sWelsEncCtx* pEncCtx, long long uiTimeStamp) {
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);
}

View File

@ -155,6 +155,7 @@ static inline void DeleteInvalidLTR (sWelsEncCtx* pCtx) {
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 @@ static inline void DeleteInvalidLTR (sWelsEncCtx* pCtx) {
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 @@ static inline void DeleteInvalidLTR (sWelsEncCtx* pCtx) {
DeleteLTRFromLongList (pCtx, i);
pLtr->bLTRMarkEnable = true;
if (pRefList->uiLongRefCount == 0) {
pCtx->bEncCurFrmAsIdrFlag = true;
pParamInternal->bEncCurFrmAsIdrFlag = true;
}
}
}
@ -195,12 +196,13 @@ static inline void HandleLTRMarkFeedback (sWelsEncCtx* pCtx) {
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 @@ static inline void HandleLTRMarkFeedback (sWelsEncCtx* pCtx) {
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 @@ static inline void LTRMarkProcess (sWelsEncCtx* pCtx) {
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 @@ static inline void LTRMarkProcess (sWelsEncCtx* pCtx) {
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 @@ static inline void LTRMarkProcess (sWelsEncCtx* pCtx) {
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 @@ bool WelsUpdateRefList (sWelsEncCtx* pCtx) {
// 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 @@ bool WelsUpdateRefList (sWelsEncCtx* pCtx) {
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 @@ bool CheckCurMarkFrameNumUsed (sWelsEncCtx* pCtx) {
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 @@ int32_t FilterLTRRecoveryRequest (sWelsEncCtx* pCtx, SLTRRecoverRequest* pLTRRec
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 @@ int32_t FilterLTRRecoveryRequest (sWelsEncCtx* pCtx, SLTRRecoverRequest* pLTRRec
, 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 @@ bool WelsBuildRefList (sWelsEncCtx* pCtx, const int32_t iPOC, int32_t iBestLtrRe
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 @@ bool WelsBuildRefList (sWelsEncCtx* pCtx, const int32_t iPOC, int32_t iBestLtrRe
// 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 @@ void WelsUpdateRefSyntax (sWelsEncCtx* pCtx, const int32_t iPOC, const int32_t u
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 @@ bool WelsUpdateRefListScreen (sWelsEncCtx* pCtx) {
// 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 @@ bool WelsBuildRefListScreen (sWelsEncCtx* pCtx, const int32_t iPOC, int32_t iBes
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 @@ bool WelsBuildRefListScreen (sWelsEncCtx* pCtx, const int32_t iPOC, int32_t iBes
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 @@ bool WelsBuildRefListScreen (sWelsEncCtx* pCtx, const int32_t iPOC, int32_t iBes
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 @@ void WelsMarkPicScreen (sWelsEncCtx* pCtx) {
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 @@ void WelsMarkPicScreen (sWelsEncCtx* pCtx) {
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;

View File

@ -679,7 +679,7 @@ WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) {
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 @@ WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) {
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 @@ WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) {
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,

View File

@ -89,14 +89,14 @@ void WelsSliceHeaderScalExtInit (SDqLayer* pCurLayer, SSlice* pSlice) {
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;
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

View File

@ -185,8 +185,9 @@ int32_t CWelsPreProcess::BuildSpatialPicList (sWelsEncCtx* pCtx, const SSourcePi
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 @@ int32_t CWelsPreProcess::BuildSpatialPicList (sWelsEncCtx* pCtx, const SSourcePi
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 @@ int32_t CWelsPreProcess::AnalyzeSpatialPic (sWelsEncCtx* pCtx, const int32_t kiD
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,6 +252,9 @@ 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);
}
@ -285,6 +287,8 @@ int32_t CWelsPreProcess::UpdateSpatialPictures (sWelsEncCtx* pCtx, SWelsSvcCodin
}
WelsExchangeSpatialPictures (&m_pSpatialPic[kiDidx][kiCurPos],
&m_pSpatialPic[kiDidx][iCurTid]);
}
return 0;
}
@ -294,6 +298,43 @@ 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 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 CWelsPreProcess::SingleLayerPreprocess (sWelsEncCtx* pCtx, const SSource
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 @@ int32_t CWelsPreProcess::SingleLayerPreprocess (sWelsEncCtx* pCtx, const SSource
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 @@ int32_t CWelsPreProcess::SingleLayerPreprocess (sWelsEncCtx* pCtx, const SSource
}
}
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 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi
#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 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi
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 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi
}
WelsLog (pLogCtx, WELS_LOG_DEBUG, "iVaaFrameSceneChangeIdc = %d,codingIdx = %d", iVaaFrameSceneChangeIdc,
pCtx->iCodingIndex);
pParamInternal->iCodingIndex);
SaveBestRefToVaa (sLtrSaved, & (pVaaExt->sVaaStrBestRefCandidate[0]));
pVaaExt->iVaaBestRefFrameNum = sLtrSaved.pRefPicture->iFrameNum;

View File

@ -145,7 +145,7 @@ WelsErrorType CWelsSliceEncodingTask::ExecuteTask() {
#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 @@ WelsErrorType CWelsSliceEncodingTask::ExecuteTask() {
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 @@ WelsErrorType CWelsLoadBalancingSlicingEncodingTask::InitTask() {
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 @@ WelsErrorType CWelsConstrainedSizeSlicingEncodingTask::ExecuteTask() {
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 @@ WelsErrorType CWelsConstrainedSizeSlicingEncodingTask::ExecuteTask() {
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 @@ WelsErrorType CWelsConstrainedSizeSlicingEncodingTask::ExecuteTask() {
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 @@ WelsErrorType CWelsConstrainedSizeSlicingEncodingTask::ExecuteTask() {
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]);

View File

@ -1391,6 +1391,7 @@ TEST_F (EncodeDecodeTestAPI, DiffSlicingInDlayer) {
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;;