ref: 2c468b96a9a1e669bd295c5f5b8d2acf6399d81e
parent: ecc8ae6ebba6bb22d19ee905e22fc7fbeb25f2c7
author: dong zhang <dongzha@cisco.com>
date: Tue Dec 9 05:50:02 EST 2014
add flag to count EC Mbs due to ref error add UT
--- a/codec/api/svc/codec_app_def.h
+++ b/codec/api/svc/codec_app_def.h
@@ -619,7 +619,9 @@
unsigned int uiIDRCorrectNum; ///< number of correct IDR received
//EC on related
unsigned int
- uiAvgEcRatio; ///< when EC is on, the average ratio of correct or EC areas, can be an indicator of reconstruction quality
+ uiAvgEcRatio; ///< when EC is on, the average ratio of total EC areas, can be an indicator of reconstruction quality
+ unsigned int
+ uiAvgEcPropRatio; ///< when EC is on, the rough average ratio of propogate EC areas, can be an indicator of reconstruction quality
unsigned int uiEcIDRNum; ///< number of actual unintegrity IDR or not received but eced
unsigned int uiEcFrameNum; ///<
unsigned int uiIDRLostNum; ///< number of whole lost IDR
--- a/codec/decoder/core/inc/dec_frame.h
+++ b/codec/decoder/core/inc/dec_frame.h
@@ -77,6 +77,7 @@
int8_t* pResidualPredFlag;
int8_t* pInterPredictionDoneFlag;
bool* pMbCorrectlyDecodedFlag;
+ bool* pMbRefConcealedFlag;
int16_t (*pScaledTCoeff)[MB_COEFF_LIST_SIZE];
int8_t (*pIntraPredMode)[8]; //0~3 top4x4 ; 4~6 left 4x4; 7 intra16x16
int8_t (*pIntra4x4FinalMode)[MB_BLOCK4x4_NUM];
--- a/codec/decoder/core/inc/decoder_context.h
+++ b/codec/decoder/core/inc/decoder_context.h
@@ -276,6 +276,7 @@
int8_t* pResidualPredFlag[LAYER_NUM_EXCHANGEABLE];
int8_t* pInterPredictionDoneFlag[LAYER_NUM_EXCHANGEABLE];
bool* pMbCorrectlyDecodedFlag[LAYER_NUM_EXCHANGEABLE];
+ bool* pMbRefConcealedFlag[LAYER_NUM_EXCHANGEABLE];
uint32_t iMbWidth;
uint32_t iMbHeight;
} sMb;
@@ -401,7 +402,10 @@
double dDecTime;
SDecoderStatistics sDecoderStatistics;// For real time debugging
int32_t iMbEcedNum;
+int32_t iMbEcedPropNum;
int32_t iMbNum;
+bool bMbRefConcealed;
+bool bRPLRError;
int32_t iECMVs[16][2];
PPicture pECRefPic[16];
unsigned long long uiTimeStamp;
--- a/codec/decoder/core/inc/picture.h
+++ b/codec/decoder/core/inc/picture.h
@@ -78,6 +78,9 @@
int32_t iSpsId; //against mosaic caused by cross-IDR interval reference.
int32_t iPpsId;
unsigned long long uiTimeStamp;
+int32_t iMbEcedNum;
+int32_t iMbEcedPropNum;
+int32_t iMbNum;
} SPicture, *PPicture; // "Picture" declaration is comflict with Mac system
} // namespace WelsDec
--- a/codec/decoder/core/src/decode_slice.cpp
+++ b/codec/decoder/core/src/decode_slice.cpp
@@ -101,6 +101,7 @@
++iCountNumMb;
if (!pCurLayer->pMbCorrectlyDecodedFlag[iNextMbXyIndex]) { //already con-ed, overwrite
pCurLayer->pMbCorrectlyDecodedFlag[iNextMbXyIndex] = true;
+ pCtx->pDec->iMbEcedPropNum += (pCurLayer->pMbRefConcealedFlag[iNextMbXyIndex]? 1 : 0);
++pCtx->iTotalNumMbRec;
}
@@ -839,6 +840,7 @@
PDqLayer pCurLayer = pCtx->pCurDqLayer;
PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer;
PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
+ PPicture* ppRefPic = pCtx->sRefPic.pRefList[LIST_0];
uint32_t uiCode;
int32_t iMbXy = pCurLayer->iMbXyIndex;
int32_t i;
@@ -861,7 +863,7 @@
pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;
memset (pCurLayer->pRefIndex[0][iMbXy], 0, sizeof (int8_t) * 16);
-
+ pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || !(ppRefPic[0]&&ppRefPic[0]->bIsComplete);
//predict mv
PredPSkipMvFromNeighbor (pCurLayer, pMv);
for (i = 0; i < 16; i++) {
@@ -963,8 +965,9 @@
}
pCurLayer->pSliceIdc[iNextMbXyIndex] = iSliceIdc;
+ pCtx->bMbRefConcealed = false;
iRet = pDecMbFunc (pCtx, pNalCur, uiEosFlag);
-
+ pCurLayer->pMbRefConcealedFlag[iNextMbXyIndex] = pCtx->bMbRefConcealed;
if (iRet != ERR_NONE) {
return iRet;
}
@@ -1520,6 +1523,7 @@
PBitStringAux pBs = pCurLayer->pBitStringAux;
PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer;
PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
+ PPicture* ppRefPic = pCtx->sRefPic.pRefList[LIST_0];
intX_t iUsedBits;
const int32_t iMbXy = pCurLayer->iMbXyIndex;
int8_t* pNzc = pCurLayer->pNzc[iMbXy];
@@ -1547,7 +1551,7 @@
pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;
memset (pCurLayer->pRefIndex[0][iMbXy], 0, sizeof (int8_t) * 16);
-
+ pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || !(ppRefPic[0]&&ppRefPic[0]->bIsComplete);
//predict iMv
PredPSkipMvFromNeighbor (pCurLayer, iMv);
for (i = 0; i < 16; i++) {
--- a/codec/decoder/core/src/decoder_core.cpp
+++ b/codec/decoder/core/src/decoder_core.cpp
@@ -127,6 +127,9 @@
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "DecodeFrameConstruction():New sequence detected, but freezed.");
}
}
+ pCtx->iMbEcedNum = pPic->iMbEcedNum;
+ pCtx->iMbNum = pPic->iMbNum;
+ pCtx->iMbEcedPropNum = pPic->iMbEcedPropNum;
UpdateDecStat (pCtx, pDstInfo->iBufferStatus != 0);
return 0;
@@ -1079,6 +1082,8 @@
pCtx->sMb.pMbCorrectlyDecodedFlag[i] = (bool*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (bool),
"pCtx->sMb.pMbCorrectlyDecodedFlag[]");
+ pCtx->sMb.pMbRefConcealedFlag[i] = (bool*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (bool),
+ "pCtx->pMbRefConcealedFlag[]");
// check memory block valid due above allocated..
WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY,
@@ -1100,6 +1105,7 @@
(NULL == pCtx->sMb.pSliceIdc[i]) ||
(NULL == pCtx->sMb.pResidualPredFlag[i]) ||
(NULL == pCtx->sMb.pInterPredictionDoneFlag[i]) ||
+ (NULL == pCtx->sMb.pMbRefConcealedFlag[i]) ||
(NULL == pCtx->sMb.pMbCorrectlyDecodedFlag[i])
)
)
@@ -1243,6 +1249,10 @@
pCtx->sMb.pMbCorrectlyDecodedFlag[i] = NULL;
}
+ if (pCtx->sMb.pMbRefConcealedFlag[i]) {
+ WelsFree (pCtx->sMb.pMbRefConcealedFlag[i], "pCtx->sMb.pMbRefConcealedFlag[]");
+ pCtx->sMb.pMbRefConcealedFlag[i] = NULL;
+ }
WelsFree (pDq, "pDq");
pDq = NULL;
@@ -1683,8 +1693,6 @@
int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
int32_t iErr;
PAccessUnit pCurAu = pCtx->pAccessUnitList;
- pCtx->iMbEcedNum = 0;
- pCtx->iMbNum = 0;
pCtx->bAuReadyFlag = false;
pCtx->bLastHasMmco5 = false;
bool bTmpNewSeqBegin = CheckNewSeqBeginAndUpdateActiveLayerSps (pCtx);
@@ -1858,6 +1866,7 @@
pCurDq->pInterPredictionDoneFlag = pCtx->sMb.pInterPredictionDoneFlag[0];
pCurDq->pResidualPredFlag = pCtx->sMb.pResidualPredFlag[0];
pCurDq->pMbCorrectlyDecodedFlag = pCtx->sMb.pMbCorrectlyDecodedFlag[0];
+ pCurDq->pMbRefConcealedFlag = pCtx->sMb.pMbRefConcealedFlag[0];
}
}
@@ -1916,8 +1925,13 @@
if (pCtx->iTotalNumMbRec == 0) { //Picture start to decode
for (int32_t i = 0; i < LAYER_NUM_EXCHANGEABLE; ++ i)
memset (pCtx->sMb.pSliceIdc[i], 0xff, (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t)));
- memset (pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag, 0, pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight);
+ memset (pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag, 0, pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight * sizeof (bool));
+ memset (pCtx->pCurDqLayer->pMbRefConcealedFlag, 0, pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight * sizeof (bool));
+ pCtx->pDec->iMbNum = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
+ pCtx->pDec->iMbEcedNum = 0;
+ pCtx->pDec->iMbEcedPropNum = 0;
}
+ pCtx->bRPLRError = false;
GetI4LumaIChromaAddrTable (pCtx->iDecBlockOffsetArray, pCtx->pDec->iLinesize[0], pCtx->pDec->iLinesize[1]);
if (pNalCur->sNalHeaderExt.uiLayerDqId > kuiTargetLayerDqId) { // confirmed pNalCur will never be NULL
@@ -1935,7 +1949,7 @@
iCurrIdD = pNalCur->sNalHeaderExt.uiDependencyId;
pSh = &pNalCur->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader;
pShExt = &pNalCur->sNalData.sVclNal.sSliceHeaderExt;
-
+ pCtx->bRPLRError = false;
bReconstructSlice = CheckSliceNeedReconstruct (pNalCur->sNalHeaderExt.uiLayerDqId, kuiTargetLayerDqId);
memcpy (&pLayerInfo.sNalHeaderExt, &pNalCur->sNalHeaderExt, sizeof (SNalUnitHeaderExt)); //confirmed_safe_unsafe_usage
@@ -2006,6 +2020,7 @@
if (iCurrIdD == kuiDependencyIdMax && iCurrIdQ == BASE_QUALITY_ID) {
iRet = InitRefPicList (pCtx, uiNalRefIdc, pSh->iPicOrderCntLsb);
if (iRet) {
+ pCtx->bRPLRError = true;
bAllRefComplete = false; // RPLR error, set ref pictures complete flag false
HandleReferenceLost (pCtx, pNalCur);
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
--- a/codec/decoder/core/src/error_concealment.cpp
+++ b/codec/decoder/core/src/error_concealment.cpp
@@ -82,8 +82,7 @@
uint32_t uiHeightInPixelY = (pCtx->pSps->iMbHeight) << 4;
int32_t iStrideY = pDstPic->iLinesize[0];
int32_t iStrideUV = pDstPic->iLinesize[1];
- pCtx->iMbNum = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
- pCtx->iMbEcedNum = pCtx->iMbNum;
+ pCtx->pDec->iMbEcedNum = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
if ((pCtx->eErrorConMethod == ERROR_CON_FRAME_COPY) && (pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.bIdrFlag))
pSrcPic = NULL; //no cross IDR method, should fill in data instead of copy
if (pSrcPic == NULL) { //no ref pic, assign specific data to picture
@@ -107,10 +106,8 @@
if ((pCtx->eErrorConMethod == ERROR_CON_SLICE_COPY) && (pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.bIdrFlag))
pSrcPic = NULL; //no cross IDR method, should fill in data instead of copy
- pCtx->iMbNum = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
//uint8_t *pDstData[3], *pSrcData[3];
bool* pMbCorrectlyDecodedFlag = pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag;
- pCtx->iMbEcedNum = 0;
//Do slice copy late
int32_t iMbXyIndex;
uint8_t* pSrcData, *pDstData;
@@ -120,7 +117,7 @@
for (int32_t iMbX = 0; iMbX < iMbWidth; ++iMbX) {
iMbXyIndex = iMbY * iMbWidth + iMbX;
if (!pMbCorrectlyDecodedFlag[iMbXyIndex]) {
- pCtx->iMbEcedNum++;
+ pCtx->pDec->iMbEcedNum++;
if (pSrcPic != NULL) {
iSrcStride = pSrcPic->iLinesize[0];
//Y component
@@ -366,9 +363,7 @@
PPicture pDstPic = pCtx->pDec;
PPicture pSrcPic = pCtx->pPreviousDecodedPictureInDpb;
- pCtx->iMbNum = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
bool* pMbCorrectlyDecodedFlag = pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag;
- pCtx->iMbEcedNum = 0;
int32_t iMbXyIndex;
uint8_t* pDstData;
uint32_t iDstStride = pDstPic->iLinesize[0];
@@ -393,7 +388,7 @@
for (int32_t iMbX = 0; iMbX < iMbWidth; ++iMbX) {
iMbXyIndex = iMbY * iMbWidth + iMbX;
if (!pMbCorrectlyDecodedFlag[iMbXyIndex]) {
- pCtx->iMbEcedNum++;
+ pCtx->pDec->iMbEcedNum++;
if (pSrcPic != NULL) {
DoMbECMvCopy (pCtx, pDstPic, pSrcPic, iMbXyIndex, iMbX, iMbY, &sMCRefMem);
} else { //pSrcPic == NULL
--- a/codec/decoder/core/src/parse_mb_syn_cabac.cpp
+++ b/codec/decoder/core/src/parse_mb_syn_cabac.cpp
@@ -377,6 +377,7 @@
WELS_READ_VERIFY (ParseRefIdxCabac (pCtx, pNeighAvail, pNonZeroCount, pRefIndex, LIST_0, iPartIdx, pRefCount[0], 0,
iRef[0]));
if ((iRef[0] < 0) || (iRef[0] >= pRefCount[0]) || (ppRefPic[iRef[0]] == NULL)) { //error ref_idx
+ pCtx->bMbRefConcealed = true;
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
iRef[0] = 0;
pCtx->iErrorCode |= dsBitstreamError;
@@ -384,6 +385,7 @@
return ERR_INFO_INVALID_REF_INDEX;
}
}
+ pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || !(ppRefPic[iRef[0]]&&ppRefPic[iRef[0]]->bIsComplete);
PredMv (pMotionVector, pRefIndex, 0, 4, iRef[0], pMv);
WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 0, pMvd[0]));
WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 1, pMvd[1]));
@@ -400,6 +402,7 @@
WELS_READ_VERIFY (ParseRefIdxCabac (pCtx, pNeighAvail, pNonZeroCount, pRefIndex, LIST_0, iPartIdx, pRefCount[0], 0,
iRef[i]));
if ((iRef[i] < 0) || (iRef[i] >= pRefCount[0]) || (ppRefPic[iRef[i]] == NULL)) { //error ref_idx
+ pCtx->bMbRefConcealed = true;
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
iRef[i] = 0;
pCtx->iErrorCode |= dsBitstreamError;
@@ -407,6 +410,7 @@
return ERR_INFO_INVALID_REF_INDEX;
}
}
+ pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || !(ppRefPic[iRef[i]]&&ppRefPic[iRef[i]]->bIsComplete);
UpdateP16x8RefIdxCabac (pCurDqLayer, pRefIndex, iPartIdx, iRef[i], LIST_0);
}
for (i = 0; i < 2; i++) {
@@ -427,6 +431,7 @@
WELS_READ_VERIFY (ParseRefIdxCabac (pCtx, pNeighAvail, pNonZeroCount, pRefIndex, LIST_0, iPartIdx, pRefCount[0], 0,
iRef[i]));
if ((iRef[i] < 0) || (iRef[i] >= pRefCount[0]) || (ppRefPic[iRef[i]] == NULL)) { //error ref_idx
+ pCtx->bMbRefConcealed = true;
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
iRef[i] = 0;
pCtx->iErrorCode |= dsBitstreamError;
@@ -434,6 +439,7 @@
return ERR_INFO_INVALID_REF_INDEX;
}
}
+ pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || !(ppRefPic[iRef[i]]&&ppRefPic[iRef[i]]->bIsComplete);
UpdateP8x16RefIdxCabac (pCurDqLayer, pRefIndex, iPartIdx, iRef[i], LIST_0);
}
for (i = 0; i < 2; i++) {
@@ -469,6 +475,7 @@
WELS_READ_VERIFY (ParseRefIdxCabac (pCtx, pNeighAvail, pNonZeroCount, pRefIndex, LIST_0, iIdx8, pRefCount[0], 1,
pRefIdx[i]));
if ((pRefIdx[i] < 0) || (pRefIdx[i] >= pRefCount[0]) || (ppRefPic[pRefIdx[i]] == NULL)) { //error ref_idx
+ pCtx->bMbRefConcealed = true;
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
pRefIdx[i] = 0;
pCtx->iErrorCode |= dsBitstreamError;
@@ -476,6 +483,7 @@
return ERR_INFO_INVALID_REF_INDEX;
}
}
+ pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || !(ppRefPic[iRef[i]]&&ppRefPic[iRef[i]]->bIsComplete);
UpdateP8x8RefIdxCabac (pCurDqLayer, pRefIndex, iIdx8, pRefIdx[i], LIST_0);
}
//mv
--- a/codec/decoder/core/src/parse_mb_syn_cavlc.cpp
+++ b/codec/decoder/core/src/parse_mb_syn_cavlc.cpp
@@ -921,6 +921,7 @@
// Security check: iRefIdx should be in range 0 to num_ref_idx_l0_active_minus1, includsive
// ref to standard section 7.4.5.1. iRefCount[0] is 1 + num_ref_idx_l0_active_minus1.
if ((iRefIdx < 0) || (iRefIdx >= iRefCount[0]) || (ppRefPic[iRefIdx] == NULL)) { //error ref_idx
+ pCtx->bMbRefConcealed = true;
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
iRefIdx = 0;
pCtx->iErrorCode |= dsBitstreamError;
@@ -928,6 +929,7 @@
return ERR_INFO_INVALID_REF_INDEX;
}
}
+ pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || !(ppRefPic[iRefIdx]&&ppRefPic[iRefIdx]->bIsComplete);
} else {
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "inter parse: iMotionPredFlag = 1 not supported. ");
return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_UNSUPPORTED_ILP);
@@ -959,6 +961,7 @@
WELS_READ_VERIFY (BsGetTe0 (pBs, iRefCount[0], &uiCode)); //ref_idx_l0[ mbPartIdx ]
iRefIdx[i] = uiCode;
if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx
+ pCtx->bMbRefConcealed = true;
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
iRefIdx[i] = 0;
pCtx->iErrorCode |= dsBitstreamError;
@@ -966,6 +969,7 @@
return ERR_INFO_INVALID_REF_INDEX;
}
}
+ pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || !(ppRefPic[iRefIdx[i]]&&ppRefPic[iRefIdx[i]]->bIsComplete);
}
for (i = 0; i < 2; i++) {
PredInter16x8Mv (iMvArray, iRefIdxArray, i << 3, iRefIdx[i], iMv);
@@ -993,6 +997,7 @@
WELS_READ_VERIFY (BsGetTe0 (pBs, iRefCount[0], &uiCode)); //ref_idx_l0[ mbPartIdx ]
iRefIdx[i] = uiCode;
if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx
+ pCtx->bMbRefConcealed = true;
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
iRefIdx[i] = 0;
pCtx->iErrorCode |= dsBitstreamError;
@@ -1000,6 +1005,7 @@
return ERR_INFO_INVALID_REF_INDEX;
}
}
+ pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || !(ppRefPic[iRefIdx[i]]&&ppRefPic[iRefIdx[i]]->bIsComplete);
} else {
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "inter parse: iMotionPredFlag = 1 not supported. ");
return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_UNSUPPORTED_ILP);
@@ -1059,6 +1065,7 @@
WELS_READ_VERIFY (BsGetTe0 (pBs, iRefCount[0], &uiCode)); //ref_idx_l0[ mbPartIdx ]
iRefIdx[i] = uiCode;
if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx
+ pCtx->bMbRefConcealed = true;
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
iRefIdx[i] = 0;
pCtx->iErrorCode |= dsBitstreamError;
@@ -1066,6 +1073,7 @@
return ERR_INFO_INVALID_REF_INDEX;
}
}
+ pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || !(ppRefPic[iRefIdx[i]]&&ppRefPic[iRefIdx[i]]->bIsComplete);
pCurDqLayer->pRefIndex[0][iMbXy][uiScan4Idx ] = pCurDqLayer->pRefIndex[0][iMbXy][uiScan4Idx + 1] =
pCurDqLayer->pRefIndex[0][iMbXy][uiScan4Idx + 4] = pCurDqLayer->pRefIndex[0][iMbXy][uiScan4Idx + 5] = iRefIdx[i];
--- a/codec/decoder/plus/src/welsDecoderExt.cpp
+++ b/codec/decoder/plus/src/welsDecoderExt.cpp
@@ -385,8 +385,6 @@
const int kiSrcLen,
unsigned char** ppDst,
SBufferInfo* pDstInfo) {
- m_pDecContext->iMbEcedNum = 0;
- m_pDecContext->iMbNum = 0;
if (CheckBsBuffer (m_pDecContext, kiSrcLen)) {
return dsOutOfMemory;
}
@@ -480,10 +478,12 @@
ResetDecStatNums (&m_pDecContext->sDecoderStatistics);
m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
}
- m_pDecContext->sDecoderStatistics.uiAvgEcRatio = m_pDecContext->iMbEcedNum == 0 ? (m_pDecContext->sDecoderStatistics.uiAvgEcRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) :((m_pDecContext->sDecoderStatistics.uiAvgEcRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) + ((m_pDecContext->iMbEcedNum * 100) / m_pDecContext->iMbNum));
- m_pDecContext->sDecoderStatistics.uiEcFrameNum++;
- m_pDecContext->sDecoderStatistics.uiAvgEcRatio = m_pDecContext->sDecoderStatistics.uiAvgEcRatio /
- m_pDecContext->sDecoderStatistics.uiEcFrameNum;
+ int32_t iMbConcealedNum = m_pDecContext->iMbEcedNum + m_pDecContext->iMbEcedPropNum;
+ m_pDecContext->sDecoderStatistics.uiAvgEcRatio = iMbConcealedNum == 0 ? (m_pDecContext->sDecoderStatistics.uiAvgEcRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) :((m_pDecContext->sDecoderStatistics.uiAvgEcRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) + ((iMbConcealedNum * 100) / m_pDecContext->iMbNum));
+ m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio = m_pDecContext->iMbEcedPropNum == 0 ? (m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) :((m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) + ((m_pDecContext->iMbEcedPropNum * 100) / m_pDecContext->iMbNum));
+ m_pDecContext->sDecoderStatistics.uiEcFrameNum += (iMbConcealedNum == 0 ? 0 : 1);
+ m_pDecContext->sDecoderStatistics.uiAvgEcRatio = m_pDecContext->sDecoderStatistics.uiEcFrameNum == 0? 0 : m_pDecContext->sDecoderStatistics.uiAvgEcRatio / m_pDecContext->sDecoderStatistics.uiEcFrameNum;
+ m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio = m_pDecContext->sDecoderStatistics.uiEcFrameNum == 0? 0 : m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio / m_pDecContext->sDecoderStatistics.uiEcFrameNum;
}
iEnd = WelsTime();
m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;
--- a/test/decoder/DecUT_DecExt.cpp
+++ b/test/decoder/DecUT_DecExt.cpp
@@ -413,7 +413,8 @@
//Decoder error bs
DecoderBs ("res/Error_I_P.264");
m_pDec->GetOption (DECODER_OPTION_GET_STATISTICS, &sDecStatic);
- EXPECT_EQ (57u, sDecStatic.uiAvgEcRatio);
+ EXPECT_EQ (65u, sDecStatic.uiAvgEcRatio);
+ EXPECT_EQ (7u, sDecStatic.uiAvgEcPropRatio);
EXPECT_EQ (5u, sDecStatic.uiDecodedFrameCount);
EXPECT_EQ (288u, sDecStatic.uiHeight);
EXPECT_EQ (1u, sDecStatic.uiIDRCorrectNum);
@@ -430,7 +431,8 @@
m_pDec->SetOption (DECODER_OPTION_ERROR_CON_IDC, &iError);
DecoderBs ("res/BA_MW_D_IDR_LOST.264");
m_pDec->GetOption (DECODER_OPTION_GET_STATISTICS, &sDecStatic);
- EXPECT_EQ (0u, sDecStatic.uiAvgEcRatio);
+ EXPECT_EQ (88u, sDecStatic.uiAvgEcRatio);
+ EXPECT_EQ (88u, sDecStatic.uiAvgEcPropRatio);
EXPECT_EQ (97u, sDecStatic.uiDecodedFrameCount);
EXPECT_EQ (144u, sDecStatic.uiHeight);
EXPECT_EQ (3u, sDecStatic.uiIDRCorrectNum);
@@ -449,7 +451,8 @@
DecoderBs ("res/BA_MW_D_P_LOST.264");
m_pDec->GetOption (DECODER_OPTION_GET_STATISTICS, &sDecStatic);
- EXPECT_EQ (0u, sDecStatic.uiAvgEcRatio);
+ EXPECT_EQ (85u, sDecStatic.uiAvgEcRatio);
+ EXPECT_EQ (85u, sDecStatic.uiAvgEcPropRatio);
EXPECT_EQ (99u, sDecStatic.uiDecodedFrameCount);
EXPECT_EQ (144u, sDecStatic.uiHeight);
EXPECT_EQ (4u, sDecStatic.uiIDRCorrectNum);
@@ -470,6 +473,7 @@
m_pDec->GetOption (DECODER_OPTION_GET_STATISTICS, &sDecStatic);
EXPECT_EQ (0u, sDecStatic.uiAvgEcRatio);
+ EXPECT_EQ (0u, sDecStatic.uiAvgEcPropRatio);
EXPECT_EQ (9u, sDecStatic.uiDecodedFrameCount);
EXPECT_EQ (192u, sDecStatic.uiHeight);
EXPECT_EQ (1u, sDecStatic.uiIDRCorrectNum);