enable cross IDR EC method

This commit is contained in:
huili2
2014-11-03 18:17:32 -08:00
parent c5029ef275
commit 103fa5bbed
6 changed files with 75 additions and 48 deletions

View File

@@ -133,7 +133,9 @@ typedef enum {
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

View File

@@ -160,7 +160,7 @@ void WelsDecoderDefaults (PWelsDecoderContext pCtx, SLogContext* pLogCtx) {
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 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
} 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 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
//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);

View File

@@ -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 @@ void DoErrorConFrameCopy (PWelsDecoderContext pCtx) {
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 @@ void DoErrorConSliceCopy (PWelsDecoderContext pCtx) {
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
//uint8_t *pDstData[3], *pSrcData[3];
bool* pMbCorrectlyDecodedFlag = pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag;
@@ -183,9 +187,11 @@ void ImplementErrorCon (PWelsDecoderContext pCtx) {
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;

View File

@@ -119,9 +119,19 @@ int32_t WelsInitRefList (PWelsDecoderContext pCtx, int32_t iPoc) {
// IDR lost, set new
pRef->bIsComplete = false; // Set complete flag to false for lost IDR ref picture
pCtx->iErrorCode |= dsDataErrorConcealed;
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;

View File

@@ -274,7 +274,7 @@ long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) {
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,

View File

@@ -121,6 +121,9 @@ void DoAncErrorConSliceCopy (PECInputCtx pECCtx) {
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,26 +234,30 @@ TEST (ErrorConTest, DoErrorConFrameCopy) {
return;
}
pECCtx->pCtx->eErrorConMethod = ERROR_CON_FRAME_COPY;
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);
//case 1: no reference picture
pECCtx->pCtx->pPreviousDecodedPictureInDpb = NULL;
DoErrorConFrameCopy (pECCtx->pCtx);
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);
//case 2: with reference picture
pECCtx->pCtx->pPreviousDecodedPictureInDpb = &pECCtx->sSrcPic;
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
FreeInputData (pECCtx);
}
@@ -263,25 +270,25 @@ TEST (ErrorConTest, DoErrorConSliceCopy) {
FreeInputData (pECCtx);
return;
}
pECCtx->pCtx->eErrorConMethod = ERROR_CON_SLICE_COPY;
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);
//case 1: no reference picture
pECCtx->pCtx->pPreviousDecodedPictureInDpb = NULL;
DoAncErrorConSliceCopy (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);
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);
//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);
}