Commit 6ea4bb0b72 for ffmpeg

commit 6ea4bb0b72376871a92b55bc8064ae737afe9e14
Author: Rainbaby <r@bgr.jp>
Date:   Fri Aug 28 16:18:07 2026 +0900

    avcodec/cavsdec: set coded dimensions from macroblock grid

    The decoder writes whole macroblocks, so give ff_set_dimensions() the
    macroblock aligned size and restore the display size after, as
    h264_slice.c does. A non-progressive sequence uses the interlaced
    MbHeight of clause 7.2.2; the parser now reports the same height.

    Signed-off-by: Rainbaby <r@bgr.jp>

diff --git a/libavcodec/cavs_parser.c b/libavcodec/cavs_parser.c
index 8dccc0923a..b3f67d6aef 100644
--- a/libavcodec/cavs_parser.c
+++ b/libavcodec/cavs_parser.c
@@ -81,11 +81,11 @@ static int parse_seq_header(AVCodecParserContext *s, AVCodecContext *avctx,
 {
     int frame_rate_code;
     int width, height;
-    int mb_width, mb_height;
+    int mb_width, mb_height, progressive;

     skip_bits(gb, 8); // profile
     skip_bits(gb, 8); // level
-    skip_bits1(gb);   // progressive sequence
+    progressive = get_bits1(gb);

     width  = get_bits(gb, 14);
     height = get_bits(gb, 14);
@@ -94,7 +94,8 @@ static int parse_seq_header(AVCodecParserContext *s, AVCodecContext *avctx,
         return AVERROR_INVALIDDATA;
     }
     mb_width  = (width  + 15) >> 4;
-    mb_height = (height + 15) >> 4;
+    /* an interlaced sequence has an even MbHeight (clause 7.2.2) */
+    mb_height = progressive ? (height + 15) >> 4 : ((height + 31) >> 5) * 2;

     skip_bits(gb, 2); // chroma format
     skip_bits(gb, 3); // sample_precision
diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c
index 1ec50af121..67002049f0 100644
--- a/libavcodec/cavsdec.c
+++ b/libavcodec/cavsdec.c
@@ -1231,17 +1231,20 @@ static int decode_pic(AVSContext *h)
 static int decode_seq_header(AVSContext *h)
 {
     int frame_rate_code;
+    int profile, level, aspect_ratio;
     int width, height;
+    int mb_width, mb_height;
+    int progressive_seq, low_delay;
     int ret;

-    h->profile = get_bits(&h->gb, 8);
-    if (h->profile != 0x20) {
+    profile = get_bits(&h->gb, 8);
+    if (profile != 0x20) {
         avpriv_report_missing_feature(h->avctx,
                                       "only support JiZhun profile");
         return AVERROR_PATCHWELCOME;
     }
-    h->level   = get_bits(&h->gb, 8);
-    skip_bits1(&h->gb); //progressive sequence
+    level = get_bits(&h->gb, 8);
+    progressive_seq = get_bits1(&h->gb);

     width  = get_bits(&h->gb, 14);
     height = get_bits(&h->gb, 14);
@@ -1256,7 +1259,7 @@ static int decode_seq_header(AVSContext *h)
     }
     skip_bits(&h->gb, 2); //chroma format
     skip_bits(&h->gb, 3); //sample_precision
-    h->aspect_ratio = get_bits(&h->gb, 4);
+    aspect_ratio = get_bits(&h->gb, 4);
     frame_rate_code = get_bits(&h->gb, 4);
     if (frame_rate_code == 0 || frame_rate_code > 13) {
         av_log(h->avctx, AV_LOG_WARNING,
@@ -1267,16 +1270,34 @@ static int decode_seq_header(AVSContext *h)
     skip_bits(&h->gb, 18); //bit_rate_lower
     skip_bits1(&h->gb);    //marker_bit
     skip_bits(&h->gb, 12); //bit_rate_upper
-    h->low_delay =  get_bits1(&h->gb);
+    low_delay = get_bits1(&h->gb);
+
+    mb_width  = (width  + 15) >> 4;
+    /* interlaced: an even number of MB rows (clause 7.2.2) */
+    mb_height = progressive_seq ? (height + 15) >> 4
+                                : ((height + 31) >> 5) * 2;
+    /* the grid sizes the arrays of ff_cavs_init_top_lines(), allocated once */
+    if (h->top_qp && (mb_width != h->mb_width || mb_height != h->mb_height)) {
+        avpriv_report_missing_feature(h->avctx, "Macroblock grid changing");
+        return AVERROR_PATCHWELCOME;
+    }

-    ret = ff_set_dimensions(h->avctx, width, height);
+    /* horizontal_size and vertical_size are only the displayed part */
+    ret = ff_set_dimensions(h->avctx, mb_width * 16, mb_height * 16);
     if (ret < 0)
         return ret;
-
-    h->width  = width;
-    h->height = height;
-    h->mb_width  = (h->width  + 15) >> 4;
-    h->mb_height = (h->height + 15) >> 4;
+    h->avctx->width  = width;
+    h->avctx->height = height;
+
+    /* commit last: a rejected header must leave the decoder as it was */
+    h->profile         = profile;
+    h->level           = level;
+    h->aspect_ratio    = aspect_ratio;
+    h->width           = width;
+    h->height          = height;
+    h->mb_width        = mb_width;
+    h->mb_height       = mb_height;
+    h->low_delay       = low_delay;
     h->avctx->framerate = ff_mpeg12_frame_rate_tab[frame_rate_code];
     if (!h->top_qp)
         return ff_cavs_init_top_lines(h);