diff --git a/codec/decoder/core/src/manage_dec_ref.cpp b/codec/decoder/core/src/manage_dec_ref.cpp index 90f79409e8..13c83eb584 100644 --- a/codec/decoder/core/src/manage_dec_ref.cpp +++ b/codec/decoder/core/src/manage_dec_ref.cpp @@ -557,7 +557,7 @@ int32_t WelsReorderRefList2 (PWelsDecoderContext pCtx) { iPredFrameNum = pRefPicListReorderSyn->sReorderingSyn[listIdx][i].uiLongTermPicNum; for (j = 0; j < iLongRefCount; j++) { if (ppLongRefList[j] != NULL) { - if (ppLongRefList[j]->uiLongTermPicNum == (uint32_t)iPredFrameNum) { + if (ppLongRefList[j]->iLongTermFrameIdx == iPredFrameNum) { ppRefList[iCount++] = ppLongRefList[j]; break; } @@ -566,7 +566,7 @@ int32_t WelsReorderRefList2 (PWelsDecoderContext pCtx) { k = iCount; for (j = k; j <= iRefCount; j++) { if (ppRefList[j] != NULL) { - if (!ppRefList[j]->bIsLongRef || ppRefList[j]->uiLongTermPicNum != (uint32_t)iPredFrameNum) + if (!ppRefList[j]->bIsLongRef || ppRefList[j]->iLongTermFrameIdx != iPredFrameNum) ppRefList[k++] = ppRefList[j]; } } diff --git a/res/ltr_reorder_high_cabac.264 b/res/ltr_reorder_high_cabac.264 new file mode 100644 index 0000000000..67a57aa8a2 Binary files /dev/null and b/res/ltr_reorder_high_cabac.264 differ diff --git a/test/api/decoder_test.cpp b/test/api/decoder_test.cpp index 988e18f81c..0b19216cf7 100644 --- a/test/api/decoder_test.cpp +++ b/test/api/decoder_test.cpp @@ -139,6 +139,7 @@ static const FileParam kFileParamArray[] = { {"res/VID_1280x544_cavlc_temporal_direct.264", "33bfa44b4a3c87fe28354cace1d4b99a03d2967d"}, {"res/VID_1280x720_cavlc_temporal_direct.264", "4face6b5d73a378b6e564a831b49311c230158e4"}, {"res/VID_1920x1080_cavlc_temporal_direct.264", "b35dc99604ea2a1fda5b84d1b9098cb7565dec8f"}, + {"res/ltr_reorder_high_cabac.264", "f496a84291950422de2620e6e022a4ac47b099f1"}, }; INSTANTIATE_TEST_CASE_P (DecodeFile, DecoderOutputTest, diff --git a/test/build/win32/codec_ut/codec_unittest.vcproj b/test/build/win32/codec_ut/codec_unittest.vcproj index 6b9dc42c37..1c09126a74 100644 --- a/test/build/win32/codec_ut/codec_unittest.vcproj +++ b/test/build/win32/codec_ut/codec_unittest.vcproj @@ -726,6 +726,42 @@ /> + + + + + + + + + + + + + + +#include +#include "decoder_context.h" +#include "manage_dec_ref.h" + +using namespace WelsDec; + +namespace { + +const int kLongRefCount = 3; +const int kTargetFrameIdx = 2; // request the long-term reference with iLongTermFrameIdx == 2 + +class RefListReorderTest : public ::testing::Test { + protected: + virtual void SetUp() { + m_pCtx = new SWelsDecoderContext; + m_pDqLayer = new SDqLayer; + m_pReorder = new SRefPicListReorderSyn; + m_pSps = new SSps; + memset (m_pCtx, 0, sizeof (SWelsDecoderContext)); + memset (m_pDqLayer, 0, sizeof (SDqLayer)); + memset (m_pReorder, 0, sizeof (SRefPicListReorderSyn)); + memset (m_pSps, 0, sizeof (SSps)); + memset (m_aPics, 0, sizeof (m_aPics)); + + // Three long-term references with distinct frame indices but, as MMCO-6 marking produces, + // an identical (zero) uiLongTermPicNum. + for (int i = 0; i < kLongRefCount; ++i) { + m_aPics[i].bIsLongRef = true; + m_aPics[i].iLongTermFrameIdx = i; + m_aPics[i].uiLongTermPicNum = 0; + } + + // Reference list starts in default frame-index order [idx0, idx1, idx2]. + SRefPic& sRefPic = m_pCtx->sRefPic; + for (int i = 0; i < kLongRefCount; ++i) { + sRefPic.pLongRefList[LIST_0][i] = &m_aPics[i]; + sRefPic.pRefList[LIST_0][i] = &m_aPics[i]; + } + sRefPic.uiLongRefCount[LIST_0] = kLongRefCount; + sRefPic.uiShortRefCount[LIST_0] = 0; + sRefPic.uiRefCount[LIST_0] = 0; + + // A single long-term reorder command requesting long_term_pic_num == kTargetFrameIdx, + // terminated by idc == 3. + m_pReorder->bRefPicListReorderingFlag[LIST_0] = true; + m_pReorder->sReorderingSyn[LIST_0][0].uiReorderingOfPicNumsIdc = 2; + m_pReorder->sReorderingSyn[LIST_0][0].uiLongTermPicNum = kTargetFrameIdx; + m_pReorder->sReorderingSyn[LIST_0][1].uiReorderingOfPicNumsIdc = 3; + + m_pDqLayer->pRefPicListReordering = m_pReorder; + PSliceHeader pSliceHeader = &m_pDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader; + pSliceHeader->iFrameNum = 5; + pSliceHeader->uiRefCount[LIST_0] = kLongRefCount; + pSliceHeader->pSps = m_pSps; + m_pSps->uiLog2MaxFrameNum = 4; + + m_pCtx->pCurDqLayer = m_pDqLayer; + m_pCtx->eSliceType = P_SLICE; + m_pCtx->iPicQueueNumber = MAX_REF_PIC_COUNT; + } + + virtual void TearDown() { + delete m_pSps; + delete m_pReorder; + delete m_pDqLayer; + delete m_pCtx; + } + + PWelsDecoderContext m_pCtx; + PDqLayer m_pDqLayer; + PRefPicListReorderSyn m_pReorder; + PSps m_pSps; + SPicture m_aPics[kLongRefCount]; +}; + +// The long-term reorder command asks for the reference with LongTermFrameIdx == 2 to be placed +// first. +TEST_F (RefListReorderTest, LongTermReorderMatchesByFrameIdx) { + int32_t iRet = WelsReorderRefList2 (m_pCtx); + ASSERT_EQ (iRet, ERR_NONE); + + PPicture pFirst = m_pCtx->sRefPic.pRefList[LIST_0][0]; + ASSERT_TRUE (pFirst != NULL); + EXPECT_TRUE (pFirst->bIsLongRef); + EXPECT_EQ (pFirst->iLongTermFrameIdx, kTargetFrameIdx); +} + +} // anonymous namespace diff --git a/test/decoder/meson.build b/test/decoder/meson.build index bf83360b14..088a9020c1 100644 --- a/test/decoder/meson.build +++ b/test/decoder/meson.build @@ -7,6 +7,7 @@ test_sources = [ 'DecUT_IntraPrediction.cpp', 'DecUT_ParseSyntax.cpp', 'DecUT_PredMv.cpp', + 'DecUT_RefListReorder.cpp', ] e = executable('test_decoder', test_sources, diff --git a/test/decoder/targets.mk b/test/decoder/targets.mk index 47df6777d5..6ddad11a58 100644 --- a/test/decoder/targets.mk +++ b/test/decoder/targets.mk @@ -11,6 +11,7 @@ DECODER_UNITTEST_CPP_SRCS=\ $(DECODER_UNITTEST_SRCDIR)/DecUT_IntraPrediction.cpp\ $(DECODER_UNITTEST_SRCDIR)/DecUT_ParseSyntax.cpp\ $(DECODER_UNITTEST_SRCDIR)/DecUT_PredMv.cpp\ + $(DECODER_UNITTEST_SRCDIR)/DecUT_RefListReorder.cpp\ DECODER_UNITTEST_OBJS += $(DECODER_UNITTEST_CPP_SRCS:.cpp=.$(OBJ))