add EC method to freeze sequence when resolution changed and decoding IDR error
This commit is contained in:
@@ -135,7 +135,8 @@ typedef enum {
|
|||||||
ERROR_CON_FRAME_COPY,
|
ERROR_CON_FRAME_COPY,
|
||||||
ERROR_CON_SLICE_COPY,
|
ERROR_CON_SLICE_COPY,
|
||||||
ERROR_CON_FRAME_COPY_CROSS_IDR,
|
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;
|
} ERROR_CON_IDC;
|
||||||
|
|
||||||
typedef enum { //feedback that whether or not have VCL NAL in current AU
|
typedef enum { //feedback that whether or not have VCL NAL in current AU
|
||||||
|
|||||||
@@ -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 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 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
|
// Derived common elements
|
||||||
SNalUnitHeader sCurNalHead;
|
SNalUnitHeader sCurNalHead;
|
||||||
|
|||||||
@@ -145,6 +145,9 @@ void WelsDecoderDefaults (PWelsDecoderContext pCtx, SLogContext* pLogCtx) {
|
|||||||
|
|
||||||
pCtx->iImgWidthInPixel = 0;
|
pCtx->iImgWidthInPixel = 0;
|
||||||
pCtx->iImgHeightInPixel = 0; // alloc picture data when picture size is available
|
pCtx->iImgHeightInPixel = 0; // alloc picture data when picture size is available
|
||||||
|
pCtx->iLastImgWidthInPixel = 0;
|
||||||
|
pCtx->iLastImgHeightInPixel = 0;
|
||||||
|
pCtx->bFreezeOutput = false;
|
||||||
|
|
||||||
pCtx->iFrameNum = -1;
|
pCtx->iFrameNum = -1;
|
||||||
pCtx->iPrevFrameNum = -1;
|
pCtx->iPrevFrameNum = -1;
|
||||||
@@ -160,7 +163,7 @@ void WelsDecoderDefaults (PWelsDecoderContext pCtx, SLogContext* pLogCtx) {
|
|||||||
pCtx->pPicBuff[LIST_1] = NULL;
|
pCtx->pPicBuff[LIST_1] = NULL;
|
||||||
|
|
||||||
pCtx->bAvcBasedFlag = true;
|
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;
|
pCtx->pPreviousDecodedPictureInDpb = NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -270,6 +273,9 @@ void WelsFreeMem (PWelsDecoderContext pCtx) {
|
|||||||
// added for safe memory
|
// added for safe memory
|
||||||
pCtx->iImgWidthInPixel = 0;
|
pCtx->iImgWidthInPixel = 0;
|
||||||
pCtx->iImgHeightInPixel = 0;
|
pCtx->iImgHeightInPixel = 0;
|
||||||
|
pCtx->iLastImgWidthInPixel = 0;
|
||||||
|
pCtx->iLastImgHeightInPixel = 0;
|
||||||
|
pCtx->bFreezeOutput = false;
|
||||||
pCtx->bHaveGotMemory = false;
|
pCtx->bHaveGotMemory = false;
|
||||||
WelsFree (pCtx->pCabacDecEngine, "pCtx->pCabacDecEngine");
|
WelsFree (pCtx->pCabacDecEngine, "pCtx->pCabacDecEngine");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
|
|||||||
} else if (pCurDq->sLayerInfo.sNalHeaderExt.bIdrFlag
|
} else if (pCurDq->sLayerInfo.sNalHeaderExt.bIdrFlag
|
||||||
&& (pCtx->iErrorCode == dsErrorFree)) { //complete non-ECed IDR frame done
|
&& (pCtx->iErrorCode == dsErrorFree)) { //complete non-ECed IDR frame done
|
||||||
pCtx->pDec->bIsComplete = true;
|
pCtx->pDec->bIsComplete = true;
|
||||||
|
pCtx->bFreezeOutput = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pCtx->iTotalNumMbRec = 0;
|
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;
|
ppDst[2] = ppDst[2] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset;
|
||||||
pDstInfo->iBufferStatus = 1;
|
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
|
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) //no buffer output if EC is disabled and frame incomplete
|
||||||
pDstInfo->iBufferStatus = (int32_t) (bFrameCompleteFlag
|
pDstInfo->iBufferStatus = (int32_t) (bFrameCompleteFlag
|
||||||
&& pPic->bIsComplete); // When EC disable, ECed picture not output
|
&& 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)) {
|
if ((pDstInfo->iBufferStatus == 1) && (pCurDq->sLayerInfo.sNalHeaderExt.bIdrFlag)) {
|
||||||
@@ -120,6 +127,8 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
|
|||||||
pCtx->iErrorCode |= dsBitstreamError;
|
pCtx->iErrorCode |= dsBitstreamError;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (pCtx->bFreezeOutput)
|
||||||
|
pDstInfo->iBufferStatus = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -394,6 +403,9 @@ int32_t WelsInitMemory (PWelsDecoderContext pCtx) {
|
|||||||
pCtx->bEndOfStreamFlag = false;
|
pCtx->bEndOfStreamFlag = false;
|
||||||
pCtx->iImgWidthInPixel = 0;
|
pCtx->iImgWidthInPixel = 0;
|
||||||
pCtx->iImgHeightInPixel = 0;
|
pCtx->iImgHeightInPixel = 0;
|
||||||
|
pCtx->iLastImgWidthInPixel = 0;
|
||||||
|
pCtx->iLastImgHeightInPixel = 0;
|
||||||
|
pCtx->bFreezeOutput = false;
|
||||||
|
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,8 @@
|
|||||||
namespace WelsDec {
|
namespace WelsDec {
|
||||||
//Init
|
//Init
|
||||||
void InitErrorCon (PWelsDecoderContext pCtx) {
|
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.pCopyLumaFunc = WelsCopy16x16_c;
|
||||||
pCtx->sCopyFunc.pCopyChromaFunc = WelsCopy8x8_c;
|
pCtx->sCopyFunc.pCopyChromaFunc = WelsCopy8x8_c;
|
||||||
|
|
||||||
@@ -196,7 +197,8 @@ void ImplementErrorCon (PWelsDecoderContext pCtx) {
|
|||||||
|| (ERROR_CON_FRAME_COPY_CROSS_IDR == pCtx->eErrorConMethod)) {
|
|| (ERROR_CON_FRAME_COPY_CROSS_IDR == pCtx->eErrorConMethod)) {
|
||||||
DoErrorConFrameCopy (pCtx);
|
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)) {
|
|| (ERROR_CON_SLICE_COPY_CROSS_IDR == pCtx->eErrorConMethod)
|
||||||
|
|| (ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->eErrorConMethod)) {
|
||||||
DoErrorConSliceCopy (pCtx);
|
DoErrorConSliceCopy (pCtx);
|
||||||
} //TODO add other EC methods here in the future
|
} //TODO add other EC methods here in the future
|
||||||
pCtx->iErrorCode |= dsDataErrorConcealed;
|
pCtx->iErrorCode |= dsDataErrorConcealed;
|
||||||
|
|||||||
@@ -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
|
pRef->bIsComplete = false; // Set complete flag to false for lost IDR ref picture
|
||||||
pCtx->iErrorCode |= dsDataErrorConcealed;
|
pCtx->iErrorCode |= dsDataErrorConcealed;
|
||||||
bool bCopyPrevious = ((ERROR_CON_FRAME_COPY_CROSS_IDR == pCtx->eErrorConMethod)
|
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)
|
bCopyPrevious = bCopyPrevious && (pRef->iWidthInPixel == pCtx->pPreviousDecodedPictureInDpb->iWidthInPixel)
|
||||||
&& (pRef->iHeightInPixel == pCtx->pPreviousDecodedPictureInDpb->iHeightInPixel);
|
&& (pRef->iHeightInPixel == pCtx->pPreviousDecodedPictureInDpb->iHeightInPixel);
|
||||||
if (bCopyPrevious) {
|
if (bCopyPrevious) {
|
||||||
|
|||||||
@@ -275,7 +275,7 @@ long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) {
|
|||||||
return cmInitParaError;
|
return cmInitParaError;
|
||||||
|
|
||||||
iVal = * ((int*)pOption); // int value for error concealment idc
|
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;
|
m_pDecContext->eErrorConMethod = (ERROR_CON_IDC) iVal;
|
||||||
InitErrorCon (m_pDecContext);
|
InitErrorCon (m_pDecContext);
|
||||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
|
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
|
||||||
|
|||||||
Reference in New Issue
Block a user