Commit 98bc7cbb for openh264
commit 98bc7cbbeb7381c94ef8f9a5d158327abbf6b8b9
Author: BenzhengZhang <140143892+BenzhengZhang@users.noreply.github.com>
Date: Mon Aug 10 18:01:46 2026 +0800
decoder: guard GetColocatedMb null colocPic before wait (#3978)
Co-authored-by: benzzhan <benzzhan@cisco.com>
diff --git a/codec/decoder/core/src/mv_pred.cpp b/codec/decoder/core/src/mv_pred.cpp
index 28b4feb9..b2d122d0 100644
--- a/codec/decoder/core/src/mv_pred.cpp
+++ b/codec/decoder/core/src/mv_pred.cpp
@@ -315,6 +315,12 @@ int32_t GetColocatedMb (PWelsDecoderContext pCtx, MbType& mbType, SubMbType& sub
mbType = GetMbType (pCurDqLayer)[iMbXy];
PPicture colocPic = pCtx->sRefPic.pRefList[LIST_1][0];
+ if (colocPic == NULL) {
+ SLogContext* pLogCtx = & (pCtx->sLogCtx);
+ WelsLog (pLogCtx, WELS_LOG_ERROR, "Colocated Ref Picture for B-Slice is lost, B-Slice decoding cannot be continued!");
+ return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_DATA, ERR_INFO_REFERENCE_PIC_LOST);
+ }
+
if (GetThreadCount (pCtx) > 1) {
if (16 * pCurDqLayer->iMbY > pCtx->lastReadyHeightOffset[1][0]) {
if (colocPic->pReadyEvent[pCurDqLayer->iMbY].isSignaled != 1) {
@@ -324,12 +330,6 @@ int32_t GetColocatedMb (PWelsDecoderContext pCtx, MbType& mbType, SubMbType& sub
}
}
- if (colocPic == NULL) {
- SLogContext* pLogCtx = & (pCtx->sLogCtx);
- WelsLog (pLogCtx, WELS_LOG_ERROR, "Colocated Ref Picture for B-Slice is lost, B-Slice decoding cannot be continued!");
- return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_DATA, ERR_INFO_REFERENCE_PIC_LOST);
- }
-
MbType coloc_mbType = colocPic->pMbType[iMbXy];
if (coloc_mbType == MB_TYPE_SKIP) {
//This indicates the colocated MB is P SKIP MB
diff --git a/test/decoder/DecUT_PredMv.cpp b/test/decoder/DecUT_PredMv.cpp
index 4a7d6a86..aca9e001 100644
--- a/test/decoder/DecUT_PredMv.cpp
+++ b/test/decoder/DecUT_PredMv.cpp
@@ -7,6 +7,13 @@
using namespace WelsDec;
+static void DummyDecoderLog (void* pCtx, const int32_t iLevel, const char* kpFmt, va_list argv) {
+ (void)pCtx;
+ (void)iLevel;
+ (void)kpFmt;
+ (void)argv;
+}
+
//Anchor functions
#define REF_NOT_AVAIL -2
#define REF_NOT_IN_LIST -1 //intra
@@ -668,3 +675,30 @@ TEST (PredMvTest, PredSkipMvFromNeighbor) {
FreeLayerData (&sDqLayer);
}
+
+TEST (PredMvTest, GetColocatedMbNullRefPicReturnsErrorBeforeWait) {
+ SWelsDecoderContext sCtx;
+ SDqLayer sDqLayer;
+ SWelsDecoderThreadCTX sThreadCtx;
+ uint32_t uiMbType = MB_TYPE_16x16;
+ MbType mbType = MB_TYPE_16x16;
+ SubMbType subMbType = SUB_MB_TYPE_8x8;
+
+ memset (&sCtx, 0, sizeof (sCtx));
+ memset (&sDqLayer, 0, sizeof (sDqLayer));
+ memset (&sThreadCtx, 0, sizeof (sThreadCtx));
+
+ sDqLayer.iMbXyIndex = 0;
+ sDqLayer.iMbY = 1;
+ sDqLayer.pMbType = &uiMbType;
+ sCtx.pCurDqLayer = &sDqLayer;
+
+ sThreadCtx.sThreadInfo.uiThrMaxNum = 2;
+ sCtx.pThreadCtx = &sThreadCtx;
+ sCtx.sLogCtx.pfLog = DummyDecoderLog;
+ sCtx.lastReadyHeightOffset[1][0] = 0;
+ sCtx.sRefPic.pRefList[LIST_1][0] = NULL;
+
+ const int32_t iRet = GetColocatedMb (&sCtx, mbType, subMbType);
+ EXPECT_EQ (GENERATE_ERROR_NO (ERR_LEVEL_SLICE_DATA, ERR_INFO_REFERENCE_PIC_LOST), iRet);
+}