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_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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user