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;