Add picture bIsComplete flag to reflect the status of decoder

Modify the output error status and add some some judgement
This commit is contained in:
Haibo Zhu 2014-10-12 23:20:16 -07:00
parent 614e898b67
commit 9d182ee515
9 changed files with 113 additions and 59 deletions

View File

@ -316,7 +316,6 @@ int32_t iFeedbackVclNalInAu;
int32_t iFeedbackTidInAu;
bool bAuReadyFlag; // true: one au is ready for decoding; false: default value
bool bDecErrorConedFlag; //true: current decoder is error coned
bool bPrintFrameErrorTraceFlag; //true: can print info for upper layer
int32_t iIgnoredErrorInfoPacketCount; //store the packet number with error decoding info

View File

@ -157,6 +157,7 @@ void WelsDecodeAccessUnitEnd (PWelsDecoderContext pCtx);
void ForceResetCurrentAccessUnit (PAccessUnit pAu);
void ForceClearCurrentNal (PAccessUnit pAu);
bool bCheckRefPicturesComplete (PWelsDecoderContext pCtx); // Check whether all ref pictures are complete
} // namespace WelsDec
#endif//WELS_DECODER_CORE_H__

View File

@ -63,6 +63,7 @@ bool bIsLongRef; // long term reference frame flag //for ref pic management
uint8_t uiRefCount;
bool bAvailableFlag; // indicate whether it is available in this picture memory block.
bool bIsComplete; // indicate whether current picture is complete, not from EC
/*******************************for future use****************************/
uint8_t uiTemporalId;
uint8_t uiSpatialId;

View File

@ -297,7 +297,6 @@ int32_t WelsOpenDecoder (PWelsDecoderContext pCtx) {
pCtx->bReferenceLostAtT0Flag = true; // should be true to waiting IDR at incoming AU bits following, 6/4/2010
#endif //LONG_TERM_REF
pCtx->bNewSeqBegin = true;
pCtx->bDecErrorConedFlag = false; //default: decoder normal status
pCtx->bPrintFrameErrorTraceFlag = true;
pCtx->iIgnoredErrorInfoPacketCount = 0;
return iRet;

View File

@ -82,7 +82,7 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
return -1;
} else if (pCurDq->sLayerInfo.sNalHeaderExt.bIdrFlag
&& (pCtx->iErrorCode == dsErrorFree)) { //complete non-ECed IDR frame done
pCtx->bDecErrorConedFlag = false;
pCtx->pDec->bIsComplete = true;
}
pCtx->iTotalNumMbRec = 0;
@ -104,10 +104,12 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
pDstInfo->iBufferStatus = 1;
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
if (!bFrameCompleteFlag) {
pCtx->iErrorCode |= dsBitstreamError;
if (pDstInfo->iBufferStatus == 0) {
if (!bFrameCompleteFlag)
pCtx->iErrorCode |= dsBitstreamError;
return -1;
}
@ -1780,6 +1782,8 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
int32_t iPpsId = 0;
int32_t iRet = ERR_NONE;
bool bAllRefComplete = true; // Assume default all ref picutres are complete
const uint8_t kuiTargetLayerDqId = GetTargetDqId (pCtx->uiTargetDqId, pCtx->pParam);
const uint8_t kuiDependencyIdMax = (kuiTargetLayerDqId & 0x7F) >> 4;
int16_t iLastIdD = -1, iLastIdQ = -1;
@ -1889,6 +1893,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
"referencing pictures lost due frame gaps exist, prev_frame_num: %d, curr_frame_num: %d", pCtx->iPrevFrameNum,
pSh->iFrameNum);
bAllRefComplete = false;
pCtx->iErrorCode |= dsRefLost;
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) {
#ifdef LONG_TERM_REF
@ -1905,6 +1910,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
if (iCurrIdD == kuiDependencyIdMax && iCurrIdQ == BASE_QUALITY_ID) {
iRet = InitRefPicList (pCtx, uiNalRefIdc, pSh->iPicOrderCntLsb);
if (iRet) {
bAllRefComplete = false; // RPLR error, set ref pictures complete flag false
HandleReferenceLost (pCtx, pNalCur);
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
"reference picture introduced by this frame is lost during transmission! uiTId: %d",
@ -1922,6 +1928,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
"DecodeCurrentAccessUnit() failed (%d) in frame: %d uiDId: %d uiQId: %d",
iRet, pSh->iFrameNum, iCurrIdD, iCurrIdQ);
bAllRefComplete = false;
HandleReferenceLostL0 (pCtx, pNalCur);
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) {
return iRet;
@ -1929,9 +1936,13 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
}
if (bReconstructSlice) {
if (WelsDecodeConstructSlice (pCtx, pNalCur)) {
pCtx->pDec->bIsComplete = false; // reconstruction error, directly set the flag false
return -1;
}
}
if (bAllRefComplete && (pCtx->sRefPic.uiRefCount[LIST_0] > 0 || pCtx->eSliceType != I_SLICE)) {
bAllRefComplete &= bCheckRefPicturesComplete (pCtx);
}
}
#if defined (_DEBUG) && !defined (CODEC_FOR_TESTBED)
fprintf (stderr, "cur_frame : %d iCurrIdD : %d\n ",
@ -1954,6 +1965,12 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
break;
}
// Set the current dec picture complete flag. The flag will be reset when current picture need do ErrorCon.
pCtx->pDec->bIsComplete = bAllRefComplete;
if (!pCtx->pDec->bIsComplete) { // Ref pictures ECed, result in ECed
pCtx->iErrorCode |= dsDataErrorConcealed;
}
// A dq layer decoded here
#if defined (_DEBUG) && !defined (CODEC_FOR_TESTBED)
#undef fprintf
@ -2031,4 +2048,42 @@ bool CheckAndFinishLastPic (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferIn
}
return ERR_NONE;
}
bool bCheckRefPicturesComplete (PWelsDecoderContext pCtx) {
// Multi Reference, RefIdx may differ
bool bAllRefComplete = true;
int32_t iRealMbIdx;
for (int32_t iMbIdx = 0; bAllRefComplete
&& iMbIdx < pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.iTotalMbInCurSlice; iMbIdx++) {
iRealMbIdx = pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iFirstMbInSlice + iMbIdx;
switch (pCtx->pCurDqLayer->pMbType[iRealMbIdx]) {
case MB_TYPE_SKIP:
case MB_TYPE_16x16:
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
break;
case MB_TYPE_16x8:
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][8] ]->bIsComplete;
break;
case MB_TYPE_8x16:
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][2] ]->bIsComplete;
break;
case MB_TYPE_8x8:
case MB_TYPE_8x8_REF0:
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][2] ]->bIsComplete;
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][8] ]->bIsComplete;
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][10] ]->bIsComplete;
break;
default:
break;
}
}
return bAllRefComplete;
}
} // namespace WelsDec

View File

@ -189,7 +189,7 @@ void ImplementErrorCon (PWelsDecoderContext pCtx) {
DoErrorConSliceCopy (pCtx);
} //TODO add other EC methods here in the future
pCtx->iErrorCode |= dsDataErrorConcealed;
pCtx->bDecErrorConedFlag = true;
pCtx->pDec->bIsComplete = false; // Set complete flag to false after do EC.
}
} // namespace WelsDec

View File

@ -73,6 +73,7 @@ static void SetUnRef (PPicture pRef) {
pRef->uiTemporalId = -1;
pRef->uiSpatialId = -1;
pRef->iSpsId = -1;
pRef->bIsComplete = false;
}
}
@ -115,6 +116,9 @@ int32_t WelsInitRefList (PWelsDecoderContext pCtx, int32_t iPoc) {
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) { //IDR lost!, recover it for future decoding with data all set to 0
PPicture pRef = PrefetchPic (pCtx->pPicBuff[0]);
if (pRef != NULL) {
// 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);

View File

@ -438,17 +438,11 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
}
if ((m_pDecContext->eErrorConMethod != ERROR_CON_DISABLE) && (pDstInfo->iBufferStatus == 1)) {
//TODO after dec status updated
m_pDecContext->bDecErrorConedFlag = true;
m_pDecContext->iErrorCode |= dsDataErrorConcealed;
}
return (DECODING_STATE) m_pDecContext->iErrorCode;
} else { //decoding correct, but may have ECed status
if (m_pDecContext->bDecErrorConedFlag) { //TODO after dec status updated
if (m_pDecContext->eErrorConMethod != ERROR_CON_DISABLE) //EC is on
m_pDecContext->iErrorCode |= dsDataErrorConcealed;
return (DECODING_STATE) m_pDecContext->iErrorCode;
}
}
// else Error free, the current codec works well
return dsErrorFree;
}
@ -457,7 +451,7 @@ DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc,
const int kiSrcLen,
SParserBsInfo* pDstInfo) {
//TODO, add function here
return (DECODING_STATE) m_pDecContext->iErrorCode;
return (DECODING_STATE) m_pDecContext->iErrorCode;
}
DECODING_STATE CWelsDecoder::DecodeFrame (const unsigned char* kpSrc,

View File

@ -102,6 +102,8 @@ class EncodeDecodeTestBase : public ::testing::TestWithParam<EncodeDecodeFilePar
};
class EncodeDecodeTestAPI : public EncodeDecodeTestBase {
public:
uint8_t iRandValue;
public:
void SetUp() {
EncodeDecodeTestBase::SetUp();
@ -115,17 +117,17 @@ class EncodeDecodeTestAPI : public EncodeDecodeTestBase {
EncodeDecodeTestBase::prepareParam (width, height, framerate);
}
void prepareEncDecParam(const EncodeDecodeFileParamBase EncDecFileParam);
void prepareEncDecParam (const EncodeDecodeFileParamBase EncDecFileParam);
void EncodeOneFrame() {
int frameSize = EncPic.iPicWidth * EncPic.iPicHeight * 3 / 2;
memset (buf_.data(), rand() % 256, frameSize);
memset (buf_.data(), iRandValue, (frameSize >> 2));
memset (buf_.data() + (frameSize >> 2), rand() % 256, (frameSize - (frameSize >> 2)));
int rv = encoder_->EncodeFrame (&EncPic, &info);
ASSERT_TRUE (rv == cmResultSuccess || rv == cmUnkonwReason);
}
};
void EncodeDecodeTestAPI::prepareEncDecParam(const EncodeDecodeFileParamBase EncDecFileParam)
{
void EncodeDecodeTestAPI::prepareEncDecParam (const EncodeDecodeFileParamBase EncDecFileParam) {
// for encoder
// I420: 1(Y) + 1/4(U) + 1/4(V)
int frameSize = EncDecFileParam.width * EncDecFileParam.height * 3 / 2;
@ -145,6 +147,9 @@ void EncodeDecodeTestAPI::prepareEncDecParam(const EncodeDecodeFileParamBase Enc
//for decoder
memset (&info, 0, sizeof (SFrameBSInfo));
//set a fixed random value
iRandValue = rand() % 256;
}
@ -165,7 +170,7 @@ TEST_P (EncodeDecodeTestAPI, DecoderVclNal) {
encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
prepareEncDecParam(p);
prepareEncDecParam (p);
int iIdx = 0;
while (iIdx <= p.numframes) {
@ -201,7 +206,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionFramenum) {
encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
prepareEncDecParam(p);
prepareEncDecParam (p);
int32_t iEncFrameNum = -1;
int32_t iDecFrameNum;
@ -240,7 +245,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionIDR) {
encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
prepareEncDecParam(p);
prepareEncDecParam (p);
int32_t iEncCurIdrPicId = 0;
int32_t iDecCurIdrPicId;
@ -479,7 +484,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionLTR_ALLIDR) {
int rv = encoder_->InitializeExt (&param_);
ASSERT_TRUE (rv == cmResultSuccess);
prepareEncDecParam(p);
prepareEncDecParam (p);
int32_t iTraceLevel = WELS_LOG_QUIET;
encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
@ -574,7 +579,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionLTR_Engine) {
ASSERT_TRUE (rv == cmResultSuccess);
m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
prepareEncDecParam(p);
prepareEncDecParam (p);
int32_t iTraceLevel = WELS_LOG_QUIET;
encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
@ -593,7 +598,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionLTR_Engine) {
int iLossIdx = 0;
bool bVCLLoss = false;
while (iIdx <= p.numframes) {
EncodeOneFrame();
EncodeOneFrame();
if (m_LTR_Recover_Request.uiFeedbackType == IDR_RECOVERY_REQUEST) {
ASSERT_TRUE (info.eFrameType == videoFrameTypeIDR);
}
@ -639,7 +644,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECFlag_ERROR_CON_DISABLE) {
ASSERT_EQ (0, rv);
m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
prepareEncDecParam(p);
prepareEncDecParam (p);
int32_t iTraceLevel = WELS_LOG_QUIET;
encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
@ -695,7 +700,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECFlag_ERROR_CON_SLICE_COPY) {
ASSERT_TRUE (rv == cmResultSuccess);
m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
prepareEncDecParam(p);
prepareEncDecParam (p);
int32_t iTraceLevel = WELS_LOG_QUIET;
encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
@ -752,7 +757,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionTid_AVC_NOPREFIX) {
int rv = encoder_->InitializeExt (&param_);
ASSERT_TRUE (rv == cmResultSuccess);
m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
prepareEncDecParam(p);
prepareEncDecParam (p);
int32_t iTraceLevel = WELS_LOG_QUIET;
encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
@ -825,7 +830,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionTid_AVC_WITH_PREFIX_NOLOSS) {
ASSERT_TRUE (rv == cmResultSuccess);
m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
prepareEncDecParam(p);
prepareEncDecParam (p);
int32_t iTraceLevel = WELS_LOG_QUIET;
encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
@ -887,7 +892,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionTid_SVC_L1_NOLOSS) {
ASSERT_TRUE (rv == cmResultSuccess);
m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
prepareEncDecParam(p);
prepareEncDecParam (p);
int32_t iTraceLevel = WELS_LOG_QUIET;
encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
@ -944,7 +949,7 @@ TEST_P (EncodeDecodeTestAPI, SetOption_Trace) {
ASSERT_TRUE (rv == cmResultSuccess);
m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
prepareEncDecParam(p);
prepareEncDecParam (p);
int32_t iTraceLevel = WELS_LOG_QUIET;
pFunc = TestOutPutTrace;
pTraceInfo = &sTrace;
@ -1009,7 +1014,7 @@ TEST_P (EncodeDecodeTestAPI, SetOption_Trace_NULL) {
ASSERT_TRUE (rv == cmResultSuccess);
m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
prepareEncDecParam(p);
prepareEncDecParam (p);
int32_t iTraceLevel = WELS_LOG_QUIET;
pFunc = NULL;
@ -1082,7 +1087,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECIDC_GeneralSliceChange) {
//Start for enc/dec
prepareEncDecParam(p);
prepareEncDecParam (p);
int32_t iTraceLevel = WELS_LOG_QUIET;
encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
@ -1113,7 +1118,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECIDC_GeneralSliceChange) {
rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf + iTotalSliceSize,
info.sLayerInfo[0].pNalLengthInByte[iPacketNum], pData, &dstBufInfo_);
if (uiEcIdc == ERROR_CON_DISABLE)
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
}
//EC_IDC should not change till now
decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
@ -1170,7 +1175,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificFrameChange) {
int len = 0;
unsigned char* pData[3] = { NULL };
prepareEncDecParam(p);
prepareEncDecParam (p);
//Frame 0: IDR, EC_IDC=DISABLE, loss = 0
EncodeOneFrame();
encToDecData (info, len);
@ -1241,10 +1246,9 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificFrameChange) {
EXPECT_EQ (rv, 0); //parse correct
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //no output
rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
if (rv == 0) //TODO: should depend on if ref-frame is OK.
EXPECT_EQ (dstBufInfo_.iBufferStatus, 1);
else
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
//Ref picture is ECed, so current status is ECed, when EC disable, NO output
EXPECT_TRUE (rv & 32);
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
iIdx++;
//Frame 5: P, EC_IDC=DISABLE, loss = 1
@ -1269,7 +1273,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificFrameChange) {
pData[0] = pData[1] = pData[2] = 0;
memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
EXPECT_TRUE (rv != 0); //parse correct, but previous decoding error, ECed
EXPECT_TRUE (rv == 0); // Now the parse process is Error_None, and the reconstruction will has error return
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //no output
rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
EXPECT_TRUE (rv != 0); //not sure if previous data drop would be detected in construction
@ -1306,7 +1310,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRLoss) {
unsigned char* pData[3] = { NULL };
int iTotalSliceSize = 0;
prepareEncDecParam(p);
prepareEncDecParam (p);
//Frame 0: IDR, EC_IDC=2, loss = 2
EncodeOneFrame();
@ -1325,7 +1329,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRLoss) {
rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, iTotalSliceSize, pData, &dstBufInfo_);
EXPECT_EQ (rv, 0); //parse correct
rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
EXPECT_EQ (rv, 0); //parse correct
EXPECT_EQ (rv, 0); // Reconstruct first slice OK
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //slice incomplete, no output
iIdx++;
@ -1361,10 +1365,9 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRLoss) {
rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
EXPECT_EQ (rv, 0); //parse correct
rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
if (rv == 0) //TODO: should depend on if ref-frame is OK.
EXPECT_EQ (dstBufInfo_.iBufferStatus, 1);
else
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
// Ref picture is ECed, so reconstructed picture is ECed
EXPECT_TRUE (rv & 32);
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
iIdx++;
//set EC=SLICE_COPY
@ -1381,7 +1384,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRLoss) {
decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_FRAME_COPY);
rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf + iTotalSliceSize, len, pData, &dstBufInfo_);
EXPECT_TRUE (rv & 32);
EXPECT_EQ (rv, 0); //parse correct
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
EXPECT_TRUE (rv & 32);
@ -1402,10 +1405,10 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRLoss) {
EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_DISABLE);
rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
EXPECT_TRUE (rv != 0);
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //output previous pic
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); // EC_IDC=0, previous picture slice lost, no output
rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
EXPECT_TRUE (rv != 0);
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //output previous pic
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); // No ref picture, no output
iIdx++;
}
@ -1440,7 +1443,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRNoLoss) {
unsigned char* pData[3] = { NULL };
int iTotalSliceSize = 0;
prepareEncDecParam(p);
prepareEncDecParam (p);
//set EC=DISABLE
uiEcIdc = (uint32_t) (ERROR_CON_DISABLE);
@ -1509,7 +1512,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRNoLoss) {
decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_SLICE_COPY);
rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
EXPECT_TRUE (rv & 32); //ECed
EXPECT_TRUE (rv & 32); //parse OK but frame 2 ECed
EXPECT_EQ (dstBufInfo_.iBufferStatus, 1); //slice loss but ECed output Frame 2
rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
EXPECT_TRUE (rv & 32);
@ -1533,11 +1536,9 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRNoLoss) {
EXPECT_TRUE (rv != 0); //previous slice not outputted, will return error due to incomplete frame
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //output previous pic
rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction,
//not sure if current frame can be correctly decoded
if (rv == 0)
EXPECT_EQ (dstBufInfo_.iBufferStatus, 1); //output previous pic
else
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //output previous pic
// previous frame NOT output, no ref
EXPECT_TRUE (rv != 0);
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //output previous pic
iIdx++;
//Frame 5: IDR, EC_IDC=2->0, loss = 0
@ -1560,10 +1561,10 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRNoLoss) {
pData[0] = pData[1] = pData[2] = 0;
memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, iTotalSliceSize, pData, &dstBufInfo_);
EXPECT_TRUE (rv != 0); //TODO: should be correct, now ECed status will return error
EXPECT_TRUE (rv == 0); // IDR status return error_free
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //frame incomplete
rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction,
EXPECT_TRUE (rv != 0); //TODO: as above
EXPECT_TRUE (rv == 0);
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //output previous pic
//set EC=DISABLE for slice 2
encToDecSliceData (1, 1, info, len); //slice 1
@ -1577,7 +1578,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRNoLoss) {
EXPECT_EQ (rv, 0); //Parse correct under no EC
EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //frame incomplete
rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction,
EXPECT_EQ (rv, 0); //Parse correct under no EC
EXPECT_EQ (rv, 0);
EXPECT_EQ (dstBufInfo_.iBufferStatus, 1); //output previous pic
iIdx++;