Commit 3f86623c27 for ffmpeg
commit 3f86623c2782e7add879ec3a3e9404f9b5c280f5
Author: Rainbaby <r@bgr.jp>
Date: Fri Aug 28 16:18:07 2026 +0900
avcodec/cavsdec: propagate inter residual errors
decode_mb_i() has acted on a failed residual block since c1cee05656.
The inter path discarded that and the illegal cbp error too, carrying
on with a desynchronized reader and, in the cbp case, the previous
macroblock's coded block pattern.
Signed-off-by: Rainbaby <r@bgr.jp>
diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c
index 9b236f519d..82422bccb0 100644
--- a/libavcodec/cavsdec.c
+++ b/libavcodec/cavsdec.c
@@ -616,7 +616,7 @@ static inline int decode_residual_chroma(AVSContext *h)
static inline int decode_residual_inter(AVSContext *h)
{
- int block;
+ int block, ret;
/* get coded block pattern */
int cbp = get_ue_golomb(&h->gb);
@@ -630,12 +630,15 @@ static inline int decode_residual_inter(AVSContext *h)
if (h->cbp && !h->qp_fixed)
h->qp = (h->qp + (unsigned)get_se_golomb(&h->gb)) & 63;
for (block = 0; block < 4; block++)
- if (h->cbp & (1 << block))
- decode_residual_block(h, &h->gb, inter_dec, 0, h->qp,
- h->cy + h->luma_scan[block], h->l_stride);
- decode_residual_chroma(h);
+ if (h->cbp & (1 << block)) {
+ ret = decode_residual_block(h, &h->gb, inter_dec, 0, h->qp,
+ h->cy + h->luma_scan[block],
+ h->l_stride);
+ if (ret < 0)
+ return ret;
+ }
- return 0;
+ return decode_residual_chroma(h);
}
/*****************************************************************************
@@ -739,10 +742,11 @@ static inline void set_intra_mode_default(AVSContext *h)
}
}
-static void decode_mb_p(AVSContext *h, enum cavs_mb mb_type)
+static int decode_mb_p(AVSContext *h, enum cavs_mb mb_type)
{
GetBitContext *gb = &h->gb;
int ref[4];
+ int ret;
ff_cavs_init_mb(h);
switch (mb_type) {
@@ -778,10 +782,15 @@ static void decode_mb_p(AVSContext *h, enum cavs_mb mb_type)
ff_cavs_inter(h, mb_type);
set_intra_mode_default(h);
store_mvs(h);
- if (mb_type != P_SKIP)
- decode_residual_inter(h);
+ if (mb_type != P_SKIP) {
+ ret = decode_residual_inter(h);
+ if (ret < 0)
+ return ret;
+ }
ff_cavs_filter(h, mb_type);
h->col_type_base[h->mbidx] = mb_type;
+
+ return 0;
}
static int decode_mb_b(AVSContext *h, enum cavs_mb mb_type)
@@ -789,6 +798,7 @@ static int decode_mb_b(AVSContext *h, enum cavs_mb mb_type)
int block;
enum cavs_sub_mb sub_type[4];
int flags;
+ int ret;
ff_cavs_init_mb(h);
@@ -914,8 +924,11 @@ static int decode_mb_b(AVSContext *h, enum cavs_mb mb_type)
}
ff_cavs_inter(h, mb_type);
set_intra_mode_default(h);
- if (mb_type != B_SKIP)
- decode_residual_inter(h);
+ if (mb_type != B_SKIP) {
+ ret = decode_residual_inter(h);
+ if (ret < 0)
+ return ret;
+ }
ff_cavs_filter(h, mb_type);
return 0;
@@ -1143,7 +1156,7 @@ static int decode_pic(AVSContext *h)
skip_count = get_ue_golomb(&h->gb);
}
if (h->skip_mode_flag && skip_count--) {
- decode_mb_p(h, P_SKIP);
+ ret = decode_mb_p(h, P_SKIP);
} else {
if (get_bits_left(&h->gb) < 1) {
ret = AVERROR_INVALIDDATA;
@@ -1153,7 +1166,7 @@ static int decode_pic(AVSContext *h)
if (mb_type > P_8X8)
ret = decode_mb_i(h, mb_type - P_8X8 - 1);
else
- decode_mb_p(h, mb_type);
+ ret = decode_mb_p(h, mb_type);
}
if (ret < 0)
break;