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))