ref: c7bffb66735df8ea01e268bc906695ee04f007ae
parent: 736128e4e372bc026019b6a1169619ca6cc97a7b
parent: 8652028620269cb9f3415cc405c67e5af1492621
author: huili2 <huili2@cisco.com>
date: Tue Dec 20 04:27:13 EST 2016
Merge pull request #2623 from ruil2/lrt1 modify LTR interface and support LTR request for each layer
--- a/codec/api/svc/codec_app_def.h
+++ b/codec/api/svc/codec_app_def.h
@@ -235,6 +235,7 @@
unsigned int uiIDRPicId; ///< distinguish request from different IDR
int iLastCorrectFrameNum;
int iCurrentFrameNum; ///< specify current decoder frame_num.
+ int iLayerId; //specify the layer for recovery request
} SLTRRecoverRequest;
/**
@@ -244,6 +245,7 @@
unsigned int uiFeedbackType; ///< mark failed or successful
unsigned int uiIDRPicId; ///< distinguish request from different IDR
int iLTRFrameNum; ///< specify current decoder frame_num
+ int iLayerId; //specify the layer for LTR marking feedback
} SLTRMarkingFeedback;
/**
--- a/codec/encoder/core/inc/encoder_context.h
+++ b/codec/encoder/core/inc/encoder_context.h
@@ -199,7 +199,7 @@
int32_t iSliceBufferSize[MAX_DEPENDENCY_LAYER];
bool bRefOfCurTidIsLtr[MAX_DEPENDENCY_LAYER][MAX_TEMPORAL_LEVEL];
- uint16_t uiIdrPicId; // IDR picture id: [0, 65535], this one is used for LTR
+ // 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,7 @@
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
+ uint16_t uiIdrPicId; // IDR picture id: [0, 65535], this one is used for LTR
int32_t iCodingIndex;
int32_t iFrameIndex; // count how many frames elapsed during coding context currently
bool bEncCurFrmAsIdrFlag;
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -1170,6 +1170,7 @@
pParamInternal->iFrameIndex = 0;
pParamInternal->iFrameNum = 0;
pParamInternal->iPOC = 0;
+ pParamInternal->uiIdrPicId = 0;
pParamInternal->bEncCurFrmAsIdrFlag = true; // make sure first frame is IDR
// pDq layers list
pDqLayer = (SDqLayer*)pMa->WelsMallocz (sizeof (SDqLayer), "pDqLayer");
@@ -2658,7 +2659,7 @@
int32_t iCurSpsId = pDqIdc->iSpsId;
iCurPpsId = pCtx->pFuncList->pParametersetStrategy->GetCurrentPpsId (iCurPpsId,
- WELS_ABS (pCtx->uiIdrPicId - 1) % MAX_PPS_COUNT);
+ WELS_ABS (pParamInternal->uiIdrPicId - 1) % MAX_PPS_COUNT);
pBaseSlice->sSliceHeaderExt.sSliceHeader.iPpsId = iCurPpsId;
pCurDq->sLayerInfo.pPpsP =
@@ -3243,7 +3244,14 @@
int32_t iNonVclSize = 0, iCountNal = 0, iReturn = ENC_RETURN_SUCCESS;
iReturn = WelsWriteParameterSets (pCtx, &pLayerBsInfo->pNalLengthInByte[0], &iCountNal, &iNonVclSize);
WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
-
+ for (int32_t iSpatialId = 0; iSpatialId < kiSpatialNum; iSpatialId++) {
+ SSpatialLayerInternal* pParamInternal = &pCtx->pSvcParam->sDependencyLayers[iSpatialId];
+ if (pParamInternal->uiIdrPicId < 65535) {
+ ++ pParamInternal->uiIdrPicId;
+ } else {
+ pParamInternal->uiIdrPicId = 0;
+ }
+ }
pLayerBsInfo->uiSpatialId = 0;
pLayerBsInfo->uiTemporalId = 0;
pLayerBsInfo->uiQualityId = 0;
@@ -3359,7 +3367,15 @@
iNonVclSize = 0;
for (int32_t iSpatialId = 0; iSpatialId < kiSpatialNum; iSpatialId++) {
+ SSpatialLayerInternal* pParamInternal = &pCtx->pSvcParam->sDependencyLayers[iSpatialId];
+ if (pParamInternal->uiIdrPicId < 65535) {
+ ++ pParamInternal->uiIdrPicId;
+ } else {
+ pParamInternal->uiIdrPicId = 0;
+ }
+
iCountNal = 0;
+
for (int32_t iIdx = 0; iIdx < pCtx->iSpsNum; iIdx++) {
//writing one NAL
int32_t iNalSize = 0;
@@ -3456,7 +3472,7 @@
pEncCtx->eSliceType = P_SLICE;
//pEncCtx->eNalPriority = pEncCtx->eLastNalPriority; //not need this since eNalPriority will be updated at the beginning of coding a frame
} else if (keFrameType == videoFrameTypeIDR) {
- pEncCtx->uiIdrPicId --;
+ pParamInternal->uiIdrPicId --;
//set the next frame to be IDR
ForceCodingIDR (pEncCtx, pEncCtx->uiDependencyId);
@@ -3510,7 +3526,7 @@
} else {
SSpatialLayerInternal* pParamInternal = &pSvcParam->sDependencyLayers[iCurDid];
- iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[iCurDid], pParamInternal->iCodingIndex,
+ iCurTid = GetTemporalLevel (pParamInternal, pParamInternal->iCodingIndex,
pSvcParam->uiGopSize);
pCtx->uiTemporalId = iCurTid;
if (eFrameType == videoFrameTypeIDR) {
@@ -3519,15 +3535,14 @@
if (! (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy)) {
if (pSvcParam->bSimulcastAVC) {
pCtx->iEncoderError = WriteSavcParaset (pCtx, iCurDid, pLayerBsInfo, iLayerNum, iFrameSize);
- ++ pCtx->uiIdrPicId;
+ ++ pParamInternal->uiIdrPicId;
} else {
pCtx->iEncoderError = WriteSsvcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize);
- ++ pCtx->uiIdrPicId;
}
} else {
pCtx->iEncoderError = WriteSavcParaset_Listing (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize);
- ++ pCtx->uiIdrPicId;
+
}
}
}
@@ -4331,7 +4346,12 @@
int32_t iOldSpsPpsIdStrategy = pOldParam->eSpsPpsIdStrategy;
SParaSetOffsetVariable sTmpPsoVariable[PARA_SET_TYPE];
int32_t iTmpPpsIdList[MAX_DQ_LAYER_NUM * MAX_PPS_COUNT];
- uint16_t uiTmpIdrPicId = (*ppCtx)->uiIdrPicId;//this is for LTR!
+ //for LTR or SPS,PPS ID update
+ uint16_t uiMaxIdrPicId = 0;
+ for (iIndexD = 0; iIndexD < pOldParam->iSpatialLayerNum; iIndexD++) {
+ if (pOldParam->sDependencyLayers[iIndexD].uiIdrPicId > uiMaxIdrPicId)
+ uiMaxIdrPicId = pOldParam->sDependencyLayers[iIndexD].uiIdrPicId;
+ }
SEncoderStatistics sTempEncoderStatistics[MAX_DEPENDENCY_LAYER];
memcpy (sTempEncoderStatistics, (*ppCtx)->sEncoderStatistics, sizeof (sTempEncoderStatistics));
@@ -4355,8 +4375,10 @@
if (WelsInitEncoderExt (ppCtx, pNewParam, &sLogCtx, pExistingParasetList))
return 1;
//if WelsInitEncoderExt succeed
- //for LTR
- (*ppCtx)->uiIdrPicId = uiTmpIdrPicId ;//this is for LTR!; //this is for LTR!
+ //for LTR or SPS,PPS ID update
+ for (iIndexD = 0; iIndexD < pNewParam->iSpatialLayerNum; iIndexD++) {
+ pNewParam->sDependencyLayers[iIndexD].uiIdrPicId = uiMaxIdrPicId;
+ }
//for sEncoderStatistics
memcpy ((*ppCtx)->sEncoderStatistics, sTempEncoderStatistics, sizeof (sTempEncoderStatistics));
@@ -4446,7 +4468,6 @@
/* Derived variants below */
pOldDlpInternal->iTemporalResolution = pNewDlpInternal->iTemporalResolution;
pOldDlpInternal->iDecompositionStages = pNewDlpInternal->iDecompositionStages;
-
memcpy (pOldDlpInternal->uiCodingIdx2TemporalId, pNewDlpInternal->uiCodingIdx2TemporalId,
sizeof (pOldDlpInternal->uiCodingIdx2TemporalId)); // confirmed_safe_unsafe_usage
++ iIndexD;
--- a/codec/encoder/core/src/ref_list_mgr_svc.cpp
+++ b/codec/encoder/core/src/ref_list_mgr_svc.cpp
@@ -512,12 +512,22 @@
}
int32_t FilterLTRRecoveryRequest (sWelsEncCtx* pCtx, SLTRRecoverRequest* pLTRRecoverRequest) {
- 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 disable LTR, force IDR
+ if (!pCtx->pSvcParam->bEnableLongTermReference) {
+ for (int32_t iDid = 0; iDid < pCtx->pSvcParam->iSpatialLayerNum; iDid++) {
+ SSpatialLayerInternal* pParamInternal = &pCtx->pSvcParam->sDependencyLayers[iDid];
+ pParamInternal->bEncCurFrmAsIdrFlag = true;
+ }
+ } else {
+ SLTRRecoverRequest* pRequest = pLTRRecoverRequest;
+ int32_t iLayerId = pLTRRecoverRequest->iLayerId;
+ if ((iLayerId < 0) || (iLayerId >= pCtx->pSvcParam->iSpatialLayerNum))
+ return false;
+
+ SLTRState* pLtr = &pCtx->pLtr[iLayerId];
+ int32_t iMaxFrameNumPlus1 = (1 << pCtx->pSps->uiLog2MaxFrameNum);
+ SSpatialLayerInternal* pParamInternal = &pCtx->pSvcParam->sDependencyLayers[iLayerId];
+ if (pRequest->uiFeedbackType == LTR_RECOVERY_REQUEST && pRequest->uiIDRPicId == pParamInternal->uiIdrPicId) {
if (pRequest->iLastCorrectFrameNum == -1) {
pParamInternal->bEncCurFrmAsIdrFlag = true;
return true;
@@ -543,16 +553,20 @@
"Receive LTR recovery pRequest,feedback_type = %d ,uiIdrPicId = %d , current_frame_num = %d , last correct frame num = %d"
, pRequest->uiFeedbackType, pRequest->uiIDRPicId, pRequest->iCurrentFrameNum, pRequest->iLastCorrectFrameNum);
}
- } else if (!pCtx->pSvcParam->bEnableLongTermReference) {
- pParamInternal->bEncCurFrmAsIdrFlag = true;
}
+
return true;
}
void FilterLTRMarkingFeedback (sWelsEncCtx* pCtx, SLTRMarkingFeedback* pLTRMarkingFeedback) {
- SLTRState* pLtr = &pCtx->pLtr[pCtx->uiDependencyId];
+ int32_t iLayerId = pLTRMarkingFeedback->iLayerId;
+ if ((iLayerId < 0) || (iLayerId >= pCtx->pSvcParam->iSpatialLayerNum)) {
+ return;
+ }
+ SLTRState* pLtr = &pCtx->pLtr[iLayerId];
assert (pLTRMarkingFeedback);
if (pCtx->pSvcParam->bEnableLongTermReference) {
- if (pLTRMarkingFeedback->uiIDRPicId == pCtx->uiIdrPicId
+ SSpatialLayerInternal* pParamInternal = &pCtx->pSvcParam->sDependencyLayers[iLayerId];
+ if (pLTRMarkingFeedback->uiIDRPicId == pParamInternal->uiIdrPicId
&& (pLTRMarkingFeedback->uiFeedbackType == LTR_MARKING_SUCCESS
|| pLTRMarkingFeedback->uiFeedbackType == LTR_MARKING_FAILED)) { // avoid error pData
pLtr->uiLtrMarkState = pLTRMarkingFeedback->uiFeedbackType;
@@ -560,13 +574,13 @@
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
"Receive valid LTR marking feedback, feedback_type = %d , uiIdrPicId = %d , LTR_frame_num = %d , cur_idr_pic_id = %d",
pLTRMarkingFeedback->uiFeedbackType, pLTRMarkingFeedback->uiIDRPicId, pLTRMarkingFeedback->iLTRFrameNum ,
- pCtx->uiIdrPicId);
+ pParamInternal->uiIdrPicId);
} else {
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
"Receive LTR marking feedback, feedback_type = %d , uiIdrPicId = %d , LTR_frame_num = %d , cur_idr_pic_id = %d",
pLTRMarkingFeedback->uiFeedbackType, pLTRMarkingFeedback->uiIDRPicId, pLTRMarkingFeedback->iLTRFrameNum ,
- pCtx->uiIdrPicId);
+ pParamInternal->uiIdrPicId);
}
}
}
--- a/codec/encoder/core/src/svc_encode_slice.cpp
+++ b/codec/encoder/core/src/svc_encode_slice.cpp
@@ -97,8 +97,7 @@
pCurSliceHeader->iFirstMbInSlice = WelsGetFirstMbOfSlice (pCurLayer->sLayerInfo.pSliceInLayer, pSlice->uiSliceIdx);
pCurSliceHeader->iFrameNum = pParamInternal->iFrameNum;
- pCurSliceHeader->uiIdrPicId = pEncCtx->uiIdrPicId;
-
+ pCurSliceHeader->uiIdrPicId = pParamInternal->uiIdrPicId;
pCurSliceHeader->iPicOrderCntLsb = pEncCtx->pEncPic->iFramePoc; // 0
if (P_SLICE == pEncCtx->eSliceType) {
--- a/test/api/decode_api_test.cpp
+++ b/test/api/decode_api_test.cpp
@@ -190,6 +190,8 @@
SLTRMarkingFeedback m_LTR_Marking_Feedback;
SLTRRecoverRequest m_LTR_Recover_Request;
m_LTR_Recover_Request.uiIDRPicId = 0;
+ m_LTR_Recover_Request.iLayerId = 0;
+ m_LTR_Marking_Feedback.iLayerId = 0;
EncodeDecodeFileParamBase p = GetParam();
prepareParamDefault (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
param_.bPrefixNalAddingCtrl = false;
@@ -259,6 +261,8 @@
SLTRMarkingFeedback m_LTR_Marking_Feedback;
SLTRRecoverRequest m_LTR_Recover_Request;
m_LTR_Recover_Request.uiIDRPicId = 0;
+ m_LTR_Recover_Request.iLayerId = 0;
+ m_LTR_Marking_Feedback.iLayerId = 0;
EncodeDecodeFileParamBase p = GetParam();
prepareParamDefault (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
param_.bPrefixNalAddingCtrl = true;
@@ -314,6 +318,8 @@
SLTRMarkingFeedback m_LTR_Marking_Feedback;
SLTRRecoverRequest m_LTR_Recover_Request;
m_LTR_Recover_Request.uiIDRPicId = 0;
+ m_LTR_Recover_Request.iLayerId = 0;
+ m_LTR_Marking_Feedback.iLayerId = 0;
EncodeDecodeFileParamBase p = GetParam();
prepareParamDefault (2, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
param_.iTemporalLayerNum = (rand() % 4) + 1;
@@ -370,6 +376,8 @@
SLTRMarkingFeedback m_LTR_Marking_Feedback;
SLTRRecoverRequest m_LTR_Recover_Request;
m_LTR_Recover_Request.uiIDRPicId = 0;
+ m_LTR_Recover_Request.iLayerId = 0;
+ m_LTR_Marking_Feedback.iLayerId = 0;
EncodeDecodeFileParamBase p = GetParam();
prepareParamDefault (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
param_.iSpatialLayerNum = 1;
@@ -434,6 +442,8 @@
SLTRMarkingFeedback m_LTR_Marking_Feedback;
SLTRRecoverRequest m_LTR_Recover_Request;
m_LTR_Recover_Request.uiIDRPicId = 0;
+ m_LTR_Recover_Request.iLayerId = 0;
+ m_LTR_Marking_Feedback.iLayerId = 0;
EncodeDecodeFileParamBase p = GetParam();
prepareParamDefault (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
param_.iSpatialLayerNum = 1;
--- a/test/api/decoder_ec_test.cpp
+++ b/test/api/decoder_ec_test.cpp
@@ -14,6 +14,8 @@
SLTRMarkingFeedback m_LTR_Marking_Feedback;
SLTRRecoverRequest m_LTR_Recover_Request;
m_LTR_Recover_Request.uiIDRPicId = 0;
+ m_LTR_Recover_Request.iLayerId = 0;
+ m_LTR_Marking_Feedback.iLayerId = 0;
EncodeDecodeFileParamBase p = GetParam();
prepareParamDefault (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
param_.bEnableLongTermReference = true;
@@ -80,6 +82,8 @@
SLTRMarkingFeedback m_LTR_Marking_Feedback;
SLTRRecoverRequest m_LTR_Recover_Request;
m_LTR_Recover_Request.uiIDRPicId = 0;
+ m_LTR_Recover_Request.iLayerId = 0;
+ m_LTR_Marking_Feedback.iLayerId = 0;
EncodeDecodeFileParamBase p = GetParam();
prepareParamDefault (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
encoder_->Uninitialize();
@@ -660,6 +664,8 @@
SLTRMarkingFeedback m_LTR_Marking_Feedback;
SLTRRecoverRequest m_LTR_Recover_Request;
m_LTR_Recover_Request.uiIDRPicId = 0;
+ m_LTR_Recover_Request.iLayerId = 0;
+ m_LTR_Marking_Feedback.iLayerId = 0;
EncodeDecodeFileParamBase p = kSVCSwitch[0];
p.width = p.width << 2;
p.height = p.height << 2;
@@ -723,6 +729,8 @@
SLTRMarkingFeedback m_LTR_Marking_Feedback;
SLTRRecoverRequest m_LTR_Recover_Request;
m_LTR_Recover_Request.uiIDRPicId = 0;
+ m_LTR_Recover_Request.iLayerId = 0;
+ m_LTR_Marking_Feedback.iLayerId = 0;
EncodeDecodeFileParamBase p = kSVCSwitch[0];
int iTarDid = 0;
int iLastDid = 0;
--- a/test/api/ltr_test.cpp
+++ b/test/api/ltr_test.cpp
@@ -45,6 +45,8 @@
TEST_P (EncodeDecodeTestAPI, GetOptionLTR_ALLLTR) {
SLTRMarkingFeedback m_LTR_Marking_Feedback;
SLTRRecoverRequest m_LTR_Recover_Request;
+ m_LTR_Recover_Request.iLayerId = 0;
+ m_LTR_Marking_Feedback.iLayerId = 0;
EncodeDecodeFileParamBase p = GetParam();
prepareParamDefault (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
encoder_->Uninitialize();
@@ -105,6 +107,8 @@
SLTRMarkingFeedback m_LTR_Marking_Feedback;
SLTRRecoverRequest m_LTR_Recover_Request;
m_LTR_Recover_Request.uiIDRPicId = 0;
+ m_LTR_Recover_Request.iLayerId = 0;
+ m_LTR_Marking_Feedback.iLayerId = 0;
EncodeDecodeFileParamBase p = GetParam();
prepareParamDefault (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
encoder_->Uninitialize();