ref: 789603a8b1df82f0fcf1f8e28f5786d91b08dc56
parent: 0fa667ac5f1dccad32d1fb79b1e6f2fc0d474999
parent: 103fa5bbedc49d9032b014c9b5cc0afb11b8f7bf
author: dongzha <[email protected]>
date: Thu Nov 6 12:24:17 EST 2014
Merge pull request #1503 from huili2/ec_crossIDR enable cross IDR EC method
--- a/codec/api/svc/codec_app_def.h
+++ b/codec/api/svc/codec_app_def.h
@@ -133,7 +133,9 @@
typedef enum {
ERROR_CON_DISABLE = 0,
ERROR_CON_FRAME_COPY,
- ERROR_CON_SLICE_COPY
+ ERROR_CON_SLICE_COPY,
+ ERROR_CON_FRAME_COPY_CROSS_IDR,
+ ERROR_CON_SLICE_COPY_CROSS_IDR
} ERROR_CON_IDC;
typedef enum { //feedback that whether or not have VCL NAL in current AU
--- a/codec/decoder/core/src/decoder.cpp
+++ b/codec/decoder/core/src/decoder.cpp
@@ -160,7 +160,7 @@
pCtx->pPicBuff[LIST_1] = NULL;
pCtx->bAvcBasedFlag = true;
- pCtx->eErrorConMethod = ERROR_CON_SLICE_COPY;
+ pCtx->eErrorConMethod = ERROR_CON_SLICE_COPY_CROSS_IDR;
pCtx->pPreviousDecodedPictureInDpb = NULL;
}
@@ -468,7 +468,8 @@
} else {
iConsumedBytes = 0;
- pDstNal[iDstIdx] = pDstNal[iDstIdx + 1] = pDstNal[iDstIdx + 2] = pDstNal[iDstIdx + 3] = 0; // set 4 reserved bytes to zero
+ pDstNal[iDstIdx] = pDstNal[iDstIdx + 1] = pDstNal[iDstIdx + 2] = pDstNal[iDstIdx + 3] =
+ 0; // set 4 reserved bytes to zero
pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes);
if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) {
CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
@@ -528,7 +529,8 @@
//last NAL decoding
iConsumedBytes = 0;
- pDstNal[iDstIdx] = pDstNal[iDstIdx + 1] = pDstNal[iDstIdx + 2] = pDstNal[iDstIdx + 3] = 0; // set 4 reserved bytes to zero
+ pDstNal[iDstIdx] = pDstNal[iDstIdx + 1] = pDstNal[iDstIdx + 2] = pDstNal[iDstIdx + 3] =
+ 0; // set 4 reserved bytes to zero
pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes);
if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) {
CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
--- a/codec/decoder/core/src/error_concealment.cpp
+++ b/codec/decoder/core/src/error_concealment.cpp
@@ -41,7 +41,7 @@
namespace WelsDec {
//Init
void InitErrorCon (PWelsDecoderContext pCtx) {
- if (pCtx->eErrorConMethod == ERROR_CON_SLICE_COPY) {
+ if ((pCtx->eErrorConMethod == ERROR_CON_SLICE_COPY) || (pCtx->eErrorConMethod == ERROR_CON_SLICE_COPY_CROSS_IDR)) {
pCtx->sCopyFunc.pCopyLumaFunc = WelsCopy16x16_c;
pCtx->sCopyFunc.pCopyChromaFunc = WelsCopy8x8_c;
@@ -79,6 +79,8 @@
uint32_t uiHeightInPixelY = (pCtx->pSps->iMbHeight) << 4;
int32_t iStrideY = pDstPic->iLinesize[0];
int32_t iStrideUV = pDstPic->iLinesize[1];
+ 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
memset (pDstPic->pData[0], 128, uiHeightInPixelY * iStrideY);
memset (pDstPic->pData[1], 128, (uiHeightInPixelY >> 1) * iStrideUV);
@@ -97,6 +99,8 @@
int32_t iMbHeight = (int32_t) pCtx->pSps->iMbHeight;
PPicture pDstPic = pCtx->pDec;
PPicture pSrcPic = pCtx->pPreviousDecodedPictureInDpb;
+ 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
int32_t iMbNum = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
//uint8_t *pDstData[3], *pSrcData[3];
@@ -188,9 +192,11 @@
if (ERROR_CON_DISABLE == pCtx->eErrorConMethod) {
pCtx->iErrorCode |= dsBitstreamError;
return;
- } else if (ERROR_CON_FRAME_COPY == pCtx->eErrorConMethod) {
+ } else if ((ERROR_CON_FRAME_COPY == pCtx->eErrorConMethod)
+ || (ERROR_CON_FRAME_COPY_CROSS_IDR == pCtx->eErrorConMethod)) {
DoErrorConFrameCopy (pCtx);
- } else if (ERROR_CON_SLICE_COPY == pCtx->eErrorConMethod) {
+ } else if ((ERROR_CON_SLICE_COPY == pCtx->eErrorConMethod)
+ || (ERROR_CON_SLICE_COPY_CROSS_IDR == pCtx->eErrorConMethod)) {
DoErrorConSliceCopy (pCtx);
} //TODO add other EC methods here in the future
pCtx->iErrorCode |= dsDataErrorConcealed;
--- a/codec/decoder/core/src/manage_dec_ref.cpp
+++ b/codec/decoder/core/src/manage_dec_ref.cpp
@@ -119,9 +119,19 @@
// IDR lost, set new
pRef->bIsComplete = false; // Set complete flag to false for lost IDR ref picture
pCtx->iErrorCode |= dsDataErrorConcealed;
- memset (pRef->pData[0], 128, pRef->iLinesize[0] * pRef->iHeightInPixel);
- memset (pRef->pData[1], 128, pRef->iLinesize[1] * pRef->iHeightInPixel / 2);
- memset (pRef->pData[2], 128, pRef->iLinesize[2] * pRef->iHeightInPixel / 2);
+ bool bCopyPrevious = ((ERROR_CON_FRAME_COPY_CROSS_IDR == pCtx->eErrorConMethod)
+ || (ERROR_CON_SLICE_COPY_CROSS_IDR == pCtx->eErrorConMethod)) && (NULL != pCtx->pPreviousDecodedPictureInDpb);
+ bCopyPrevious = bCopyPrevious && (pRef->iWidthInPixel == pCtx->pPreviousDecodedPictureInDpb->iWidthInPixel)
+ && (pRef->iHeightInPixel == pCtx->pPreviousDecodedPictureInDpb->iHeightInPixel);
+ if (bCopyPrevious) {
+ memcpy (pRef->pData[0], pCtx->pPreviousDecodedPictureInDpb->pData[0], pRef->iLinesize[0] * pRef->iHeightInPixel);
+ memcpy (pRef->pData[1], pCtx->pPreviousDecodedPictureInDpb->pData[1], pRef->iLinesize[1] * pRef->iHeightInPixel / 2);
+ memcpy (pRef->pData[2], pCtx->pPreviousDecodedPictureInDpb->pData[2], pRef->iLinesize[2] * pRef->iHeightInPixel / 2);
+ } else {
+ memset (pRef->pData[0], 128, pRef->iLinesize[0] * pRef->iHeightInPixel);
+ memset (pRef->pData[1], 128, pRef->iLinesize[1] * pRef->iHeightInPixel / 2);
+ memset (pRef->pData[2], 128, pRef->iLinesize[2] * pRef->iHeightInPixel / 2);
+ }
pRef->iFrameNum = 0;
pRef->iFramePoc = 0;
pRef->uiTemporalId = pRef->uiQualityId = 0;
--- a/codec/decoder/plus/src/welsDecoderExt.cpp
+++ b/codec/decoder/plus/src/welsDecoderExt.cpp
@@ -275,7 +275,7 @@
return cmInitParaError;
iVal = * ((int*)pOption); // int value for error concealment idc
- iVal = WELS_CLIP3 (iVal, (int32_t) ERROR_CON_DISABLE, (int32_t) ERROR_CON_SLICE_COPY);
+ iVal = WELS_CLIP3 (iVal, (int32_t) ERROR_CON_DISABLE, (int32_t) ERROR_CON_SLICE_COPY_CROSS_IDR);
m_pDecContext->eErrorConMethod = (ERROR_CON_IDC) iVal;
InitErrorCon (m_pDecContext);
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
--- a/test/decoder/DecUT_ErrorConcealment.cpp
+++ b/test/decoder/DecUT_ErrorConcealment.cpp
@@ -121,6 +121,9 @@
int32_t iMbHeight = (int32_t) pECCtx->iMbHeight;
PPicture pDstPic = &pECCtx->sAncPic;
PPicture pSrcPic = pECCtx->pCtx->pPreviousDecodedPictureInDpb;
+ if ((pECCtx->pCtx->eErrorConMethod == ERROR_CON_SLICE_COPY)
+ && (pECCtx->pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.bIdrFlag))
+ pSrcPic = NULL;
//uint8_t *pDstData[3], *pSrcData[3];
bool* pMbCorrectlyDecodedFlag = pECCtx->pMbCorrectlyDecodedFlag;
@@ -231,27 +234,31 @@
return;
}
- pECCtx->pCtx->eErrorConMethod = ERROR_CON_FRAME_COPY;
- InitECCopyData (pECCtx);
- //case 1: no reference picture
- pECCtx->pCtx->pPreviousDecodedPictureInDpb = NULL;
- DoErrorConFrameCopy (pECCtx->pCtx);
+ for (int iEC = 0; iEC < 2; ++ iEC) { //ERROR_CON_FRAME_COPY, ERROR_CON_FRAME_COPY_CROSS_IDR
+ pECCtx->pCtx->eErrorConMethod = iEC > 0 ? ERROR_CON_FRAME_COPY_CROSS_IDR : ERROR_CON_FRAME_COPY;
+ InitECCopyData (pECCtx);
+ int32_t iLumaSize = pECCtx->iMbWidth * pECCtx->iMbHeight * 256;
- int32_t iLumaSize = pECCtx->iMbWidth * pECCtx->iMbHeight * 256;
- memset (pECCtx->sAncPic.pData[0], 128, iLumaSize * 3 / 2); //should be the same as known EC method, here all 128
- bOK = ComparePictureDataI420 (pECCtx->sAncPic.pData[0], pECCtx->sWelsPic.pData[0], pECCtx->iLinesize[0],
- pECCtx->iMbHeight * 16);
- EXPECT_EQ (bOK, true);
+ for (int iRef = 0; iRef < 2; ++ iRef) { //no ref, with ref
+ pECCtx->pCtx->pPreviousDecodedPictureInDpb = iRef ? &pECCtx->sSrcPic : NULL;
+ for (int iIDR = 0; iIDR < 2; ++ iIDR) { //non IDR, IDR
+ pECCtx->pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.bIdrFlag = (iIDR > 0);
+ //Do reference code method
+ DoErrorConFrameCopy (pECCtx->pCtx);
+ //Do anchor method
+ if (iRef && ! ((pECCtx->pCtx->eErrorConMethod == ERROR_CON_FRAME_COPY)
+ && (pECCtx->pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.bIdrFlag)))
+ memcpy (pECCtx->sAncPic.pData[0], pECCtx->sSrcPic.pData[0], iLumaSize * 3 / 2);
+ else
+ memset (pECCtx->sAncPic.pData[0], 128, iLumaSize * 3 / 2); //should be the same as known EC method, here all 128
+ //Compare results
+ bOK = ComparePictureDataI420 (pECCtx->sAncPic.pData[0], pECCtx->sWelsPic.pData[0], pECCtx->iLinesize[0],
+ pECCtx->iMbHeight * 16);
+ EXPECT_EQ (bOK, true);
+ } //non IDR, IDR
+ } // no ref, with ref
+ } //FRAME_COPY methods
- //case 2: with reference picture
- pECCtx->pCtx->pPreviousDecodedPictureInDpb = &pECCtx->sSrcPic;
- DoErrorConFrameCopy (pECCtx->pCtx);
-
- memcpy (pECCtx->sAncPic.pData[0], pECCtx->sSrcPic.pData[0], iLumaSize * 3 / 2);
- bOK = ComparePictureDataI420 (pECCtx->sAncPic.pData[0], pECCtx->sWelsPic.pData[0], pECCtx->iLinesize[0],
- pECCtx->iMbHeight * 16);
- EXPECT_EQ (bOK, true);
-
FreeInputData (pECCtx);
}
@@ -263,25 +270,25 @@
FreeInputData (pECCtx);
return;
}
- pECCtx->pCtx->eErrorConMethod = ERROR_CON_SLICE_COPY;
- InitECCopyData (pECCtx);
- //case 1: no reference picture
- pECCtx->pCtx->pPreviousDecodedPictureInDpb = NULL;
- DoAncErrorConSliceCopy (pECCtx);
- DoErrorConSliceCopy (pECCtx->pCtx);
- bOK = ComparePictureDataI420 (pECCtx->sAncPic.pData[0], pECCtx->sWelsPic.pData[0], pECCtx->iLinesize[0],
- pECCtx->iMbHeight * 16);
- EXPECT_EQ (bOK, true);
-
- //case 2: with reference picture
- pECCtx->pCtx->pPreviousDecodedPictureInDpb = &pECCtx->sSrcPic;
- DoAncErrorConSliceCopy (pECCtx);
- DoErrorConSliceCopy (pECCtx->pCtx);
-
- bOK = ComparePictureDataI420 (pECCtx->sAncPic.pData[0], pECCtx->sWelsPic.pData[0], pECCtx->iLinesize[0],
- pECCtx->iMbHeight * 16);
- EXPECT_EQ (bOK, true);
+ for (int iEC = 0; iEC < 2; ++ iEC) { //ERROR_CON_SLICE_COPY, ERROR_CON_SLICE_COPY_CROSS_IDR
+ pECCtx->pCtx->eErrorConMethod = iEC > 0 ? ERROR_CON_SLICE_COPY_CROSS_IDR : ERROR_CON_SLICE_COPY;
+ InitECCopyData (pECCtx);
+ for (int iRef = 0; iRef < 2; ++ iRef) { //no ref, with ref
+ pECCtx->pCtx->pPreviousDecodedPictureInDpb = iRef ? &pECCtx->sSrcPic : NULL;
+ for (int iIDR = 0; iIDR < 2; ++ iIDR) { //non IDR, IDR
+ pECCtx->pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.bIdrFlag = (iIDR > 0);
+ //Do reference code method
+ DoErrorConSliceCopy (pECCtx->pCtx);
+ //Do anchor method
+ DoAncErrorConSliceCopy (pECCtx);
+ //Compare results
+ bOK = ComparePictureDataI420 (pECCtx->sAncPic.pData[0], pECCtx->sWelsPic.pData[0], pECCtx->iLinesize[0],
+ pECCtx->iMbHeight * 16);
+ EXPECT_EQ (bOK, true);
+ } //non IDR, IDR
+ } // no ref, with ref
+ } //FRAME_COPY methods
FreeInputData (pECCtx);
}