add EC method to freeze sequence when resolution changed and decoding IDR error

This commit is contained in:
huili2
2014-11-13 19:26:10 -08:00
parent aed7b2316c
commit 0d16fd61b2
7 changed files with 33 additions and 6 deletions

View File

@@ -135,7 +135,8 @@ typedef enum {
ERROR_CON_FRAME_COPY,
ERROR_CON_SLICE_COPY,
ERROR_CON_FRAME_COPY_CROSS_IDR,
ERROR_CON_SLICE_COPY_CROSS_IDR
ERROR_CON_SLICE_COPY_CROSS_IDR,
ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE
} ERROR_CON_IDC;
typedef enum { //feedback that whether or not have VCL NAL in current AU

View File

@@ -221,6 +221,10 @@ bool bHaveGotMemory; // global memory for decoder context related ever reques
int32_t iImgWidthInPixel; // width of image in pixel reconstruction picture to be output
int32_t iImgHeightInPixel;// height of image in pixel reconstruction picture to be output
int32_t iLastImgWidthInPixel; // width of image in last successful pixel reconstruction picture to be output
int32_t iLastImgHeightInPixel;// height of image in last successful pixel reconstruction picture to be output
bool bFreezeOutput;
// Derived common elements
SNalUnitHeader sCurNalHead;

View File

@@ -145,6 +145,9 @@ void WelsDecoderDefaults (PWelsDecoderContext pCtx, SLogContext* pLogCtx) {
pCtx->iImgWidthInPixel = 0;
pCtx->iImgHeightInPixel = 0; // alloc picture data when picture size is available
pCtx->iLastImgWidthInPixel = 0;
pCtx->iLastImgHeightInPixel = 0;
pCtx->bFreezeOutput = false;
pCtx->iFrameNum = -1;
pCtx->iPrevFrameNum = -1;
@@ -160,7 +163,7 @@ void WelsDecoderDefaults (PWelsDecoderContext pCtx, SLogContext* pLogCtx) {
pCtx->pPicBuff[LIST_1] = NULL;
pCtx->bAvcBasedFlag = true;
pCtx->eErrorConMethod = ERROR_CON_SLICE_COPY_CROSS_IDR;
pCtx->eErrorConMethod = ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE;
pCtx->pPreviousDecodedPictureInDpb = NULL;
}
@@ -270,6 +273,9 @@ void WelsFreeMem (PWelsDecoderContext pCtx) {
// added for safe memory
pCtx->iImgWidthInPixel = 0;
pCtx->iImgHeightInPixel = 0;
pCtx->iLastImgWidthInPixel = 0;
pCtx->iLastImgHeightInPixel = 0;
pCtx->bFreezeOutput = false;
pCtx->bHaveGotMemory = false;
WelsFree (pCtx->pCabacDecEngine, "pCtx->pCabacDecEngine");
}

View File

@@ -83,6 +83,7 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
} else if (pCurDq->sLayerInfo.sNalHeaderExt.bIdrFlag
&& (pCtx->iErrorCode == dsErrorFree)) { //complete non-ECed IDR frame done
pCtx->pDec->bIsComplete = true;
pCtx->bFreezeOutput = false;
}
pCtx->iTotalNumMbRec = 0;
@@ -103,9 +104,15 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
ppDst[2] = ppDst[2] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset;
pDstInfo->iBufferStatus = 1;
bool bOutResChange = (pCtx->iLastImgWidthInPixel != pDstInfo->UsrData.sSystemBuffer.iWidth)
|| (pCtx->iLastImgHeightInPixel != pDstInfo->UsrData.sSystemBuffer.iHeight);
pCtx->iLastImgWidthInPixel = pDstInfo->UsrData.sSystemBuffer.iWidth;
pCtx->iLastImgHeightInPixel = pDstInfo->UsrData.sSystemBuffer.iHeight;
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) //no buffer output if EC is disabled and frame incomplete
pDstInfo->iBufferStatus = (int32_t) (bFrameCompleteFlag
&& pPic->bIsComplete); // When EC disable, ECed picture not output
else if (pCtx->eErrorConMethod == ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE && pCtx->iErrorCode && bOutResChange)
pCtx->bFreezeOutput = true;
if ((pDstInfo->iBufferStatus == 1) && (pCurDq->sLayerInfo.sNalHeaderExt.bIdrFlag)) {
@@ -120,6 +127,8 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
pCtx->iErrorCode |= dsBitstreamError;
return -1;
}
if (pCtx->bFreezeOutput)
pDstInfo->iBufferStatus = 0;
return 0;
}
@@ -394,6 +403,9 @@ int32_t WelsInitMemory (PWelsDecoderContext pCtx) {
pCtx->bEndOfStreamFlag = false;
pCtx->iImgWidthInPixel = 0;
pCtx->iImgHeightInPixel = 0;
pCtx->iLastImgWidthInPixel = 0;
pCtx->iLastImgHeightInPixel = 0;
pCtx->bFreezeOutput = false;
return ERR_NONE;
}

View File

@@ -41,7 +41,8 @@
namespace WelsDec {
//Init
void InitErrorCon (PWelsDecoderContext pCtx) {
if ((pCtx->eErrorConMethod == ERROR_CON_SLICE_COPY) || (pCtx->eErrorConMethod == ERROR_CON_SLICE_COPY_CROSS_IDR)) {
if ((pCtx->eErrorConMethod == ERROR_CON_SLICE_COPY) || (pCtx->eErrorConMethod == ERROR_CON_SLICE_COPY_CROSS_IDR)
|| (pCtx->eErrorConMethod == ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE)) {
pCtx->sCopyFunc.pCopyLumaFunc = WelsCopy16x16_c;
pCtx->sCopyFunc.pCopyChromaFunc = WelsCopy8x8_c;
@@ -196,7 +197,8 @@ void ImplementErrorCon (PWelsDecoderContext pCtx) {
|| (ERROR_CON_FRAME_COPY_CROSS_IDR == pCtx->eErrorConMethod)) {
DoErrorConFrameCopy (pCtx);
} else if ((ERROR_CON_SLICE_COPY == pCtx->eErrorConMethod)
|| (ERROR_CON_SLICE_COPY_CROSS_IDR == pCtx->eErrorConMethod)) {
|| (ERROR_CON_SLICE_COPY_CROSS_IDR == pCtx->eErrorConMethod)
|| (ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->eErrorConMethod)) {
DoErrorConSliceCopy (pCtx);
} //TODO add other EC methods here in the future
pCtx->iErrorCode |= dsDataErrorConcealed;

View File

@@ -120,7 +120,9 @@ int32_t WelsInitRefList (PWelsDecoderContext pCtx, int32_t iPoc) {
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);
|| (ERROR_CON_SLICE_COPY_CROSS_IDR == pCtx->eErrorConMethod)
|| (ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->eErrorConMethod))
&& (NULL != pCtx->pPreviousDecodedPictureInDpb);
bCopyPrevious = bCopyPrevious && (pRef->iWidthInPixel == pCtx->pPreviousDecodedPictureInDpb->iWidthInPixel)
&& (pRef->iHeightInPixel == pCtx->pPreviousDecodedPictureInDpb->iHeightInPixel);
if (bCopyPrevious) {

View File

@@ -275,7 +275,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_CROSS_IDR);
iVal = WELS_CLIP3 (iVal, (int32_t) ERROR_CON_DISABLE, (int32_t) ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE);
m_pDecContext->eErrorConMethod = (ERROR_CON_IDC) iVal;
InitErrorCon (m_pDecContext);
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,