Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] Misc mpegvideo patches
@ 2025-03-04 13:42 Andreas Rheinhardt
  2025-03-04 16:30 ` Ramiro Polla
  0 siblings, 1 reply; 6+ messages in thread
From: Andreas Rheinhardt @ 2025-03-04 13:42 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

[-- Attachment #1: Type: text/plain, Size: 113 bytes --]

(Mostly trivial) patches attached. A branch is at
https://github.com/mkver/FFmpeg/tree/mpegvideo_misc

- Andreas

[-- Attachment #2: 0001-avcodec-rv34-Make-ff_rv34_get_start_offset-honor-its.patch --]
[-- Type: text/x-patch, Size: 2551 bytes --]

From 7bf6f6d334fd0cb60ecd7253ea75089e95e5e3f2 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 26 Feb 2025 11:13:15 +0100
Subject: [PATCH 01/40] avcodec/rv34: Make ff_rv34_get_start_offset() honor its
 name

Up until now, it only returned the number of bits for the
start offset, but not the start offset; the GetBitContext
passed to it was unused.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/rv30.c | 4 +---
 libavcodec/rv34.c | 2 +-
 libavcodec/rv40.c | 4 +---
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c
index 5e1dd01aa1..351276995b 100644
--- a/libavcodec/rv30.c
+++ b/libavcodec/rv30.c
@@ -38,7 +38,6 @@
 static int rv30_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si)
 {
     AVCodecContext *avctx = r->s.avctx;
-    int mb_bits;
     int w = r->s.width, h = r->s.height;
     int mb_size;
     int rpr;
@@ -76,8 +75,7 @@ static int rv30_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceIn
     si->width  = w;
     si->height = h;
     mb_size = ((w + 15) >> 4) * ((h + 15) >> 4);
-    mb_bits = ff_rv34_get_start_offset(gb, mb_size);
-    si->start = get_bits(gb, mb_bits);
+    si->start = ff_rv34_get_start_offset(gb, mb_size);
     skip_bits1(gb);
     return 0;
 }
diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c
index d8d307f969..ddc95c3a78 100644
--- a/libavcodec/rv34.c
+++ b/libavcodec/rv34.c
@@ -342,7 +342,7 @@ int ff_rv34_get_start_offset(GetBitContext *gb, int mb_size)
     for(i = 0; i < 5; i++)
         if(rv34_mb_max_sizes[i] >= mb_size - 1)
             break;
-    return rv34_mb_bits_sizes[i];
+    return get_bits(gb, rv34_mb_bits_sizes[i]);
 }
 
 /**
diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c
index 0a5136d129..d28e02c2d1 100644
--- a/libavcodec/rv40.c
+++ b/libavcodec/rv40.c
@@ -131,7 +131,6 @@ static void rv40_parse_picture_size(GetBitContext *gb, int *w, int *h)
 
 static int rv40_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si)
 {
-    int mb_bits;
     int w = r->s.width, h = r->s.height;
     int mb_size;
     int ret;
@@ -154,8 +153,7 @@ static int rv40_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceIn
     si->width  = w;
     si->height = h;
     mb_size = ((w + 15) >> 4) * ((h + 15) >> 4);
-    mb_bits = ff_rv34_get_start_offset(gb, mb_size);
-    si->start = get_bits(gb, mb_bits);
+    si->start = ff_rv34_get_start_offset(gb, mb_size);
 
     return 0;
 }
-- 
2.45.2


[-- Attachment #3: 0002-avcodec-vc1_block-vc1dec-Don-t-use-c_dc_scale-_table.patch --]
[-- Type: text/x-patch, Size: 6538 bytes --]

From af15d9d28e90598e8be00f78cf9925887898d329 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 27 Feb 2025 14:15:10 +0100
Subject: [PATCH 02/40] avcodec/vc1_block, vc1dec: Don't use
 c_dc_scale(_table)?

It coincides with the luma values.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/vc1_block.c | 43 +++++++++++-------------------------------
 libavcodec/vc1dec.c    |  1 -
 2 files changed, 11 insertions(+), 33 deletions(-)

diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c
index 1c422d902f..5dd2083385 100644
--- a/libavcodec/vc1_block.c
+++ b/libavcodec/vc1_block.c
@@ -354,8 +354,7 @@ static inline int vc1_i_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
     };
 
     /* find prediction - wmv3_dc_scale always used here in fact */
-    if (n < 4) scale = s->y_dc_scale;
-    else       scale = s->c_dc_scale;
+    scale = s->y_dc_scale;
 
     wrap   = s->block_wrap[n];
     dc_val = s->dc_val[0] + s->block_index[n];
@@ -611,11 +610,7 @@ static int vc1_decode_i_block(VC1Context *v, int16_t block[64], int n,
     *dc_val = dcdiff;
 
     /* Store the quantized DC coeff, used for prediction */
-    if (n < 4)
-        scale = s->y_dc_scale;
-    else
-        scale = s->c_dc_scale;
-    block[0] = dcdiff * scale;
+    block[0] = dcdiff * s->y_dc_scale;
 
     ac_val  = s->ac_val[0][s->block_index[n]];
     ac_val2 = ac_val;
@@ -752,11 +747,7 @@ static int vc1_decode_i_block_adv(VC1Context *v, int16_t block[64], int n,
     *dc_val = dcdiff;
 
     /* Store the quantized DC coeff, used for prediction */
-    if (n < 4)
-        scale = s->y_dc_scale;
-    else
-        scale = s->c_dc_scale;
-    block[0] = dcdiff * scale;
+    block[0] = dcdiff * s->y_dc_scale;
 
     /* check if AC is needed at all */
     if (!a_avail && !c_avail)
@@ -925,9 +916,8 @@ static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n,
     /* XXX: Guard against dumb values of mquant */
     quant = av_clip_uintp2(quant, 5);
 
-    /* Set DC scale - y and c use the same */
+    /* Set DC scale - y and c use the same so we only set y */
     s->y_dc_scale = s->y_dc_scale_table[quant];
-    s->c_dc_scale = s->c_dc_scale_table[quant];
 
     /* Get DC differential */
     dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_vlc[s->dc_table_index][n >= 4],
@@ -949,12 +939,7 @@ static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n,
     *dc_val = dcdiff;
 
     /* Store the quantized DC coeff, used for prediction */
-
-    if (n < 4) {
-        block[0] = dcdiff * s->y_dc_scale;
-    } else {
-        block[0] = dcdiff * s->c_dc_scale;
-    }
+    block[0] = dcdiff * s->y_dc_scale;
 
     //AC Decoding
     i = 1;
@@ -1593,9 +1578,8 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
             v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
             GET_MQUANT();
             s->cur_pic.qscale_table[mb_pos] = mquant;
-            /* Set DC scale - y and c use the same (not sure if necessary here) */
+            /* Set DC scale - y and c use the same so we only set y */
             s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
-            s->c_dc_scale = s->c_dc_scale_table[FFABS(mquant)];
             dst_idx = 0;
             for (i = 0; i < 6; i++) {
                 v->a_avail = v->c_avail          = 0;
@@ -1756,9 +1740,8 @@ static int vc1_decode_p_mb_intfi(VC1Context *v)
         s->cur_pic.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
         GET_MQUANT();
         s->cur_pic.qscale_table[mb_pos] = mquant;
-        /* Set DC scale - y and c use the same (not sure if necessary here) */
+        /* Set DC scale - y and c use the same so we only set y */
         s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
-        s->c_dc_scale = s->c_dc_scale_table[FFABS(mquant)];
         v->s.ac_pred  = v->acpred_plane[mb_pos] = get_bits1(gb);
         mb_has_coeffs = idx_mbmode & 1;
         if (mb_has_coeffs)
@@ -2044,9 +2027,8 @@ static int vc1_decode_b_mb_intfi(VC1Context *v)
         s->cur_pic.mb_type[mb_pos + v->mb_off]         = MB_TYPE_INTRA;
         GET_MQUANT();
         s->cur_pic.qscale_table[mb_pos] = mquant;
-        /* Set DC scale - y and c use the same (not sure if necessary here) */
+        /* Set DC scale - y and c use the same so we only set y */
         s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
-        s->c_dc_scale = s->c_dc_scale_table[FFABS(mquant)];
         v->s.ac_pred  = v->acpred_plane[mb_pos] = get_bits1(gb);
         mb_has_coeffs = idx_mbmode & 1;
         if (mb_has_coeffs)
@@ -2245,9 +2227,8 @@ static int vc1_decode_b_mb_intfr(VC1Context *v)
         v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
         GET_MQUANT();
         s->cur_pic.qscale_table[mb_pos] = mquant;
-        /* Set DC scale - y and c use the same (not sure if necessary here) */
+        /* Set DC scale - y and c use the same so we only set y */
         s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
-        s->c_dc_scale = s->c_dc_scale_table[FFABS(mquant)];
         dst_idx = 0;
         for (i = 0; i < 6; i++) {
             v->a_avail = v->c_avail          = 0;
@@ -2568,9 +2549,8 @@ static void vc1_decode_i_blocks(VC1Context *v)
         break;
     }
 
-    /* Set DC scale - y and c use the same */
+    /* Set DC scale - y and c use the same so we only set y */
     s->y_dc_scale = s->y_dc_scale_table[v->pq];
-    s->c_dc_scale = s->c_dc_scale_table[v->pq];
 
     //do frame decode
     s->mb_x = s->mb_y = 0;
@@ -2738,9 +2718,8 @@ static int vc1_decode_i_blocks_adv(VC1Context *v)
             GET_MQUANT();
 
             s->cur_pic.qscale_table[mb_pos] = mquant;
-            /* Set DC scale - y and c use the same */
+            /* Set DC scale - y and c use the same so we only set y */
             s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
-            s->c_dc_scale = s->c_dc_scale_table[FFABS(mquant)];
 
             for (k = 0; k < 6; k++) {
                 v->mb_type[0][s->block_index[k]] = 1;
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index cfd97c4ca6..bd6f090c55 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -472,7 +472,6 @@ av_cold int ff_vc1_decode_init(AVCodecContext *avctx)
         return ret;
 
     s->y_dc_scale_table = ff_wmv3_dc_scale_table;
-    s->c_dc_scale_table = ff_wmv3_dc_scale_table;
 
     ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable,
                       ff_wmv1_scantable[1]);
-- 
2.45.2


[-- Attachment #4: 0003-avcodec-vc1_block-Inline-y_dc_scale_table.patch --]
[-- Type: text/x-patch, Size: 5796 bytes --]

From 7b4f8fd62259a81fc9bdc0e4d813a64d767526f3 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 27 Feb 2025 14:58:43 +0100
Subject: [PATCH 03/40] avcodec/vc1_block: Inline y_dc_scale_table

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/vc1_block.c | 22 +++++++++++-----------
 libavcodec/vc1dec.c    |  2 --
 2 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c
index 5dd2083385..8babbde38c 100644
--- a/libavcodec/vc1_block.c
+++ b/libavcodec/vc1_block.c
@@ -417,7 +417,7 @@ static inline int ff_vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
 
     /* scale predictors if needed */
     q1 = FFABS(s->cur_pic.qscale_table[mb_pos]);
-    dqscale_index = s->y_dc_scale_table[q1] - 1;
+    dqscale_index = ff_wmv3_dc_scale_table[q1] - 1;
     if (dqscale_index < 0)
         return 0;
 
@@ -434,12 +434,12 @@ static inline int ff_vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
     if (c_avail && (n != 1 && n != 3)) {
         q2 = FFABS(s->cur_pic.qscale_table[mb_pos - 1]);
         if (q2 && q2 != q1)
-            c = (int)((unsigned)c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
+            c = (int)((unsigned)c * ff_wmv3_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
     }
     if (a_avail && (n != 2 && n != 3)) {
         q2 = FFABS(s->cur_pic.qscale_table[mb_pos - s->mb_stride]);
         if (q2 && q2 != q1)
-            a = (int)((unsigned)a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
+            a = (int)((unsigned)a * ff_wmv3_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
     }
     if (a_avail && c_avail && (n != 3)) {
         int off = mb_pos;
@@ -449,7 +449,7 @@ static inline int ff_vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
             off -= s->mb_stride;
         q2 = FFABS(s->cur_pic.qscale_table[off]);
         if (q2 && q2 != q1)
-            b = (int)((unsigned)b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
+            b = (int)((unsigned)b * ff_wmv3_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
     }
 
     if (c_avail && (!a_avail || abs(a - b) <= abs(b - c))) {
@@ -917,7 +917,7 @@ static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n,
     quant = av_clip_uintp2(quant, 5);
 
     /* Set DC scale - y and c use the same so we only set y */
-    s->y_dc_scale = s->y_dc_scale_table[quant];
+    s->y_dc_scale = ff_wmv3_dc_scale_table[quant];
 
     /* Get DC differential */
     dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_vlc[s->dc_table_index][n >= 4],
@@ -1579,7 +1579,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
             GET_MQUANT();
             s->cur_pic.qscale_table[mb_pos] = mquant;
             /* Set DC scale - y and c use the same so we only set y */
-            s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
+            s->y_dc_scale = ff_wmv3_dc_scale_table[FFABS(mquant)];
             dst_idx = 0;
             for (i = 0; i < 6; i++) {
                 v->a_avail = v->c_avail          = 0;
@@ -1741,7 +1741,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v)
         GET_MQUANT();
         s->cur_pic.qscale_table[mb_pos] = mquant;
         /* Set DC scale - y and c use the same so we only set y */
-        s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
+        s->y_dc_scale = ff_wmv3_dc_scale_table[FFABS(mquant)];
         v->s.ac_pred  = v->acpred_plane[mb_pos] = get_bits1(gb);
         mb_has_coeffs = idx_mbmode & 1;
         if (mb_has_coeffs)
@@ -2028,7 +2028,7 @@ static int vc1_decode_b_mb_intfi(VC1Context *v)
         GET_MQUANT();
         s->cur_pic.qscale_table[mb_pos] = mquant;
         /* Set DC scale - y and c use the same so we only set y */
-        s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
+        s->y_dc_scale = ff_wmv3_dc_scale_table[FFABS(mquant)];
         v->s.ac_pred  = v->acpred_plane[mb_pos] = get_bits1(gb);
         mb_has_coeffs = idx_mbmode & 1;
         if (mb_has_coeffs)
@@ -2228,7 +2228,7 @@ static int vc1_decode_b_mb_intfr(VC1Context *v)
         GET_MQUANT();
         s->cur_pic.qscale_table[mb_pos] = mquant;
         /* Set DC scale - y and c use the same so we only set y */
-        s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
+        s->y_dc_scale = ff_wmv3_dc_scale_table[FFABS(mquant)];
         dst_idx = 0;
         for (i = 0; i < 6; i++) {
             v->a_avail = v->c_avail          = 0;
@@ -2550,7 +2550,7 @@ static void vc1_decode_i_blocks(VC1Context *v)
     }
 
     /* Set DC scale - y and c use the same so we only set y */
-    s->y_dc_scale = s->y_dc_scale_table[v->pq];
+    s->y_dc_scale = ff_wmv3_dc_scale_table[v->pq];
 
     //do frame decode
     s->mb_x = s->mb_y = 0;
@@ -2719,7 +2719,7 @@ static int vc1_decode_i_blocks_adv(VC1Context *v)
 
             s->cur_pic.qscale_table[mb_pos] = mquant;
             /* Set DC scale - y and c use the same so we only set y */
-            s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
+            s->y_dc_scale = ff_wmv3_dc_scale_table[FFABS(mquant)];
 
             for (k = 0; k < 6; k++) {
                 v->mb_type[0][s->block_index[k]] = 1;
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index bd6f090c55..7256ad9557 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -471,8 +471,6 @@ av_cold int ff_vc1_decode_init(AVCodecContext *avctx)
     if (ret < 0)
         return ret;
 
-    s->y_dc_scale_table = ff_wmv3_dc_scale_table;
-
     ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable,
                       ff_wmv1_scantable[1]);
 
-- 
2.45.2


[-- Attachment #5: 0004-avcodec-vc1dec-Don-t-initialize-unused-parts-of-Scan.patch --]
[-- Type: text/x-patch, Size: 1088 bytes --]

From 4ce1bdfb79cd192035eded62e5564247a86ce80d Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 03:36:57 +0100
Subject: [PATCH 04/40] avcodec/vc1dec: Don't initialize unused parts of
 ScanTable

The VC-1 decoders don't need ScanTable.raster_end as
they don't call any of the unquantize functions.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/vc1dec.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 7256ad9557..d92a7da8ab 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -471,8 +471,8 @@ av_cold int ff_vc1_decode_init(AVCodecContext *avctx)
     if (ret < 0)
         return ret;
 
-    ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable,
-                      ff_wmv1_scantable[1]);
+    ff_permute_scantable(s->intra_scantable.permutated, ff_wmv1_scantable[1],
+                         s->idsp.idct_permutation);
 
     ret = vc1_decode_init_alloc_tables(v);
     if (ret < 0) {
-- 
2.45.2


[-- Attachment #6: 0005-avcodec-Remove-leftover-alpha-declarations.patch --]
[-- Type: text/x-patch, Size: 4178 bytes --]

From a3734572694ec6e618e5e66305b1dda1a52ee00e Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 2 Mar 2025 05:18:43 +0100
Subject: [PATCH 05/40] avcodec: Remove leftover alpha declarations

Forgotten in cdd139d760688b14849d02ee1907f68fe692c24e.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/blockdsp.h    | 1 -
 libavcodec/hpeldsp.h     | 1 -
 libavcodec/idctdsp.h     | 2 --
 libavcodec/me_cmp.h      | 1 -
 libavcodec/mpegvideo.h   | 1 -
 libavcodec/pixblockdsp.h | 2 --
 6 files changed, 8 deletions(-)

diff --git a/libavcodec/blockdsp.h b/libavcodec/blockdsp.h
index 6d751d797b..f83068ce53 100644
--- a/libavcodec/blockdsp.h
+++ b/libavcodec/blockdsp.h
@@ -38,7 +38,6 @@ typedef struct BlockDSPContext {
 
 void ff_blockdsp_init(BlockDSPContext *c);
 
-void ff_blockdsp_init_alpha(BlockDSPContext *c);
 void ff_blockdsp_init_arm(BlockDSPContext *c);
 void ff_blockdsp_init_ppc(BlockDSPContext *c);
 void ff_blockdsp_init_riscv(BlockDSPContext *c);
diff --git a/libavcodec/hpeldsp.h b/libavcodec/hpeldsp.h
index 45e81b10a5..41a46f0760 100644
--- a/libavcodec/hpeldsp.h
+++ b/libavcodec/hpeldsp.h
@@ -97,7 +97,6 @@ typedef struct HpelDSPContext {
 void ff_hpeldsp_init(HpelDSPContext *c, int flags);
 
 void ff_hpeldsp_init_aarch64(HpelDSPContext *c, int flags);
-void ff_hpeldsp_init_alpha(HpelDSPContext *c, int flags);
 void ff_hpeldsp_init_arm(HpelDSPContext *c, int flags);
 void ff_hpeldsp_init_ppc(HpelDSPContext *c, int flags);
 void ff_hpeldsp_init_x86(HpelDSPContext *c, int flags);
diff --git a/libavcodec/idctdsp.h b/libavcodec/idctdsp.h
index c08242881c..7783d7098a 100644
--- a/libavcodec/idctdsp.h
+++ b/libavcodec/idctdsp.h
@@ -98,8 +98,6 @@ void ff_idctdsp_init(IDCTDSPContext *c, struct AVCodecContext *avctx);
 
 void ff_idctdsp_init_aarch64(IDCTDSPContext *c, struct AVCodecContext *avctx,
                              unsigned high_bit_depth);
-void ff_idctdsp_init_alpha(IDCTDSPContext *c, struct AVCodecContext *avctx,
-                           unsigned high_bit_depth);
 void ff_idctdsp_init_arm(IDCTDSPContext *c, struct AVCodecContext *avctx,
                          unsigned high_bit_depth);
 void ff_idctdsp_init_ppc(IDCTDSPContext *c, struct AVCodecContext *avctx,
diff --git a/libavcodec/me_cmp.h b/libavcodec/me_cmp.h
index 9053327c4c..4aefcf1622 100644
--- a/libavcodec/me_cmp.h
+++ b/libavcodec/me_cmp.h
@@ -76,7 +76,6 @@ typedef struct MECmpContext {
 
 void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx);
 void ff_me_cmp_init_aarch64(MECmpContext *c, AVCodecContext *avctx);
-void ff_me_cmp_init_alpha(MECmpContext *c, AVCodecContext *avctx);
 void ff_me_cmp_init_arm(MECmpContext *c, AVCodecContext *avctx);
 void ff_me_cmp_init_ppc(MECmpContext *c, AVCodecContext *avctx);
 void ff_me_cmp_init_riscv(MECmpContext *c, AVCodecContext *avctx);
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 48fc1d418e..ac38d112f9 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -561,7 +561,6 @@ void ff_mpv_common_defaults(MpegEncContext *s);
 
 int ff_mpv_common_init(MpegEncContext *s);
 void ff_mpv_common_init_arm(MpegEncContext *s);
-void ff_mpv_common_init_axp(MpegEncContext *s);
 void ff_mpv_common_init_neon(MpegEncContext *s);
 void ff_mpv_common_init_ppc(MpegEncContext *s);
 void ff_mpv_common_init_x86(MpegEncContext *s);
diff --git a/libavcodec/pixblockdsp.h b/libavcodec/pixblockdsp.h
index cac5f3d4a2..215b0905d7 100644
--- a/libavcodec/pixblockdsp.h
+++ b/libavcodec/pixblockdsp.h
@@ -44,8 +44,6 @@ typedef struct PixblockDSPContext {
 void ff_pixblockdsp_init(PixblockDSPContext *c, AVCodecContext *avctx);
 void ff_pixblockdsp_init_aarch64(PixblockDSPContext *c, AVCodecContext *avctx,
                                  unsigned high_bit_depth);
-void ff_pixblockdsp_init_alpha(PixblockDSPContext *c, AVCodecContext *avctx,
-                               unsigned high_bit_depth);
 void ff_pixblockdsp_init_arm(PixblockDSPContext *c, AVCodecContext *avctx,
                              unsigned high_bit_depth);
 void ff_pixblockdsp_init_ppc(PixblockDSPContext *c, AVCodecContext *avctx,
-- 
2.45.2


[-- Attachment #7: 0006-avcodec-mpeg12dec-Don-t-count-errors-from-first-thre.patch --]
[-- Type: text/x-patch, Size: 3395 bytes --]

From da85ffccf686798287223720ab0a630a349b3c59 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 1 Mar 2025 22:36:35 +0100
Subject: [PATCH 06/40] avcodec/mpeg12dec: Don't count errors from first thread
 twice

Compilers can not perform this optimization on their own
given that they don't know that the different thread_context
pointers don't alias.
Also avoid using sequentially consistent operations with
atomics when only a single thread accesses them.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12dec.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index 843640edbf..6bbb8e7afd 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -29,6 +29,7 @@
 
 #define UNCHECKED_BITSTREAM_READER 1
 #include <inttypes.h>
+#include <stdatomic.h>
 
 #include "libavutil/attributes.h"
 #include "libavutil/emms.h"
@@ -46,7 +47,6 @@
 #include "hwaccel_internal.h"
 #include "hwconfig.h"
 #include "idctdsp.h"
-#include "internal.h"
 #include "mpeg_er.h"
 #include "mpeg12.h"
 #include "mpeg12codecs.h"
@@ -2252,6 +2252,7 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture,
                 if (HAVE_THREADS &&
                     (avctx->active_thread_type & FF_THREAD_SLICE) &&
                     !avctx->hwaccel) {
+                    int error_count = 0;
                     int i;
                     av_assert0(avctx->thread_count > 1);
 
@@ -2259,7 +2260,10 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture,
                                    &s2->thread_context[0], NULL,
                                    s->slice_count, sizeof(void *));
                     for (i = 0; i < s->slice_count; i++)
-                        s2->er.error_count += s2->thread_context[i]->er.error_count;
+                        error_count += atomic_load_explicit(&s2->thread_context[i]->er.error_count,
+                                                            memory_order_relaxed);
+                    atomic_store_explicit(&s2->er.error_count, error_count,
+                                          memory_order_relaxed);
                 }
 
                 ret = slice_end(avctx, picture, got_output);
@@ -2321,13 +2325,17 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture,
             }
             if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) &&
                 !avctx->hwaccel && s->slice_count) {
+                int error_count = 0;
                 int i;
 
                 avctx->execute(avctx, slice_decode_thread,
                                s2->thread_context, NULL,
                                s->slice_count, sizeof(void *));
                 for (i = 0; i < s->slice_count; i++)
-                    s2->er.error_count += s2->thread_context[i]->er.error_count;
+                    error_count += atomic_load_explicit(&s2->thread_context[i]->er.error_count,
+                                                        memory_order_relaxed);
+                atomic_store_explicit(&s2->er.error_count, error_count,
+                                      memory_order_relaxed);
                 s->slice_count = 0;
             }
             if (last_code == 0 || last_code == SLICE_MIN_START_CODE) {
-- 
2.45.2


[-- Attachment #8: 0007-avcodec-mpeg12dec-Mark-flush-as-cold.patch --]
[-- Type: text/x-patch, Size: 797 bytes --]

From 1c771c17b7e8e74d62215e938e5e48282759298b Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 03:30:40 +0100
Subject: [PATCH 07/40] avcodec/mpeg12dec: Mark flush as cold

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12dec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index 6bbb8e7afd..ba40c1f06f 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -2641,7 +2641,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, AVFrame *picture,
     return ret;
 }
 
-static void flush(AVCodecContext *avctx)
+static av_cold void flush(AVCodecContext *avctx)
 {
     Mpeg1Context *s = avctx->priv_data;
 
-- 
2.45.2


[-- Attachment #9: 0008-avcodec-h261dec-Don-t-call-ff_set_qscale.patch --]
[-- Type: text/x-patch, Size: 1544 bytes --]

From 76406cfcd9adf55fcf5a17e2e5992e29bacf79fd Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 1 Mar 2025 21:32:51 +0100
Subject: [PATCH 08/40] avcodec/h261dec: Don't call ff_set_qscale()

Most of what it does is unneeded for H.261.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/h261dec.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c
index 8a2c4d35b4..c32ddd2ddf 100644
--- a/libavcodec/h261dec.c
+++ b/libavcodec/h261dec.c
@@ -155,6 +155,7 @@ static int h261_decode_gob_header(H261DecContext *h)
         av_log(s->avctx, AV_LOG_ERROR, "qscale has forbidden 0 value\n");
         if (s->avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_COMPLIANT))
             return -1;
+        s->qscale = 1;
     }
 
     /* For the first transmitted macroblock in a GOB, MBA is the absolute
@@ -380,8 +381,11 @@ static int h261_decode_mb(H261DecContext *h)
     }
 
     // Read mquant
-    if (IS_QUANT(com->mtype))
-        ff_set_qscale(s, get_bits(&s->gb, 5));
+    if (IS_QUANT(com->mtype)) {
+        s->qscale = get_bits(&s->gb, 5);
+        if (!s->qscale)
+            s->qscale = 1;
+    }
 
     s->mb_intra = IS_INTRA4x4(com->mtype);
 
@@ -511,8 +515,6 @@ static int h261_decode_gob(H261DecContext *h)
 {
     MpegEncContext *const s = &h->s;
 
-    ff_set_qscale(s, s->qscale);
-
     /* decode mb's */
     while (h->current_mba <= MBA_STUFFING) {
         int ret;
-- 
2.45.2


[-- Attachment #10: 0009-avcodec-h261-Use-forward-declaration-for-MpegEncCont.patch --]
[-- Type: text/x-patch, Size: 1036 bytes --]

From 71e8b0ab8f04a6cbb8975156e38ee3fef45c8d91 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 28 Feb 2025 18:13:59 +0100
Subject: [PATCH 09/40] avcodec/h261: Use forward-declaration for
 MpegEncContext

Avoids an indirect inclusion of mpegvideo.h in h261data.c.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/h261.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/h261.h b/libavcodec/h261.h
index 4279a12677..fb5fc6f940 100644
--- a/libavcodec/h261.h
+++ b/libavcodec/h261.h
@@ -29,7 +29,6 @@
 #define AVCODEC_H261_H
 
 #include "mpegutils.h"
-#include "mpegvideo.h"
 #include "rl.h"
 
 /**
@@ -54,6 +53,7 @@ extern const uint16_t ff_h261_tcoeff_vlc[65][2];
 extern const int8_t ff_h261_tcoeff_level[64];
 extern const int8_t ff_h261_tcoeff_run[64];
 
-void ff_h261_loop_filter(MpegEncContext *s);
+struct MpegEncContext;
+void ff_h261_loop_filter(struct MpegEncContext *s);
 
 #endif /* AVCODEC_H261_H */
-- 
2.45.2


[-- Attachment #11: 0010-avcodec-mpegvideo_enc-Move-default_mv_penalty-to-h26.patch --]
[-- Type: text/x-patch, Size: 2368 bytes --]

From daa01271141c2acb54d11f92dae67344e72e9d5a Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 20:53:33 +0100
Subject: [PATCH 10/40] avcodec/mpegvideo_enc: Move default_mv_penalty to
 h261enc.c

MPEG-1/2 and the H.263-based encoders overwrite the default later
and SpeedHQ and MJPEG-based encoders are intra-only and don't
need a mv_penalty table at all. So only H.261 uses this table.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/h261enc.c       | 3 +++
 libavcodec/mpegvideo_enc.c | 2 --
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index dabab9d80a..e33bf35a8a 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -46,6 +46,7 @@ static struct VLCLUT {
     uint16_t code;
 } vlc_lut[H261_MAX_RUN + 1][32 /* 0..2 * H261_MAX_LEN are used */];
 
+static uint8_t mv_penalty[MAX_FCODE + 1][MAX_DMV * 2 + 1];
 static uint8_t uni_h261_rl_len     [64 * 128];
 static uint8_t uni_h261_rl_len_last[64 * 128];
 static uint8_t h261_mv_codes[64][2];
@@ -370,6 +371,8 @@ av_cold int ff_h261_encode_init(MpegEncContext *s)
     s->max_qcoeff       = 127;
     s->ac_esc_length    = H261_ESC_LEN;
 
+    s->me.mv_penalty = mv_penalty;
+
     s->intra_ac_vlc_length      = s->inter_ac_vlc_length      = uni_h261_rl_len;
     s->intra_ac_vlc_last_length = s->inter_ac_vlc_last_length = uni_h261_rl_len_last;
     ff_thread_once(&init_static_once, h261_encode_init_static);
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 8c22dbb5f5..1fe69f89a6 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -93,7 +93,6 @@ static int dct_quantize_c(MpegEncContext *s,
                           int qscale, int *overflow);
 static int dct_quantize_trellis_c(MpegEncContext *s, int16_t *block, int n, int qscale, int *overflow);
 
-static uint8_t default_mv_penalty[MAX_FCODE + 1][MAX_DMV * 2 + 1];
 static uint8_t default_fcode_tab[MAX_MV * 2 + 1];
 
 static const AVOption mpv_generic_options[] = {
@@ -287,7 +286,6 @@ static void mpv_encode_defaults(MpegEncContext *s)
 
     ff_thread_once(&init_static_once, mpv_encode_init_static);
 
-    s->me.mv_penalty = default_mv_penalty;
     s->fcode_tab     = default_fcode_tab;
 
     s->input_picture_number  = 0;
-- 
2.45.2


[-- Attachment #12: 0011-avcodec-mpegutils-Move-MAX_FCODE-to-mpegvideoenc.h.patch --]
[-- Type: text/x-patch, Size: 1138 bytes --]

From 70843bd9027a24c0bcbcfcf4efd9aba7550d3992 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 21:01:31 +0100
Subject: [PATCH 11/40] avcodec/mpegutils: Move MAX_FCODE to mpegvideoenc.h

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegutils.h    | 1 -
 libavcodec/mpegvideoenc.h | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/mpegutils.h b/libavcodec/mpegutils.h
index e4ce26d299..9967762a79 100644
--- a/libavcodec/mpegutils.h
+++ b/libavcodec/mpegutils.h
@@ -33,7 +33,6 @@
 #define PICT_FRAME         3
 
 #define MAX_MB_BYTES    (30 * 16 * 16 * 3 / 8 + 120)
-#define MAX_FCODE        7
 
 /* MB types */
 #define MB_TYPE_INTRA4x4   (1 <<  0)
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index f5044a0309..2d7f76c57a 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -33,6 +33,7 @@
 #include "libavutil/opt.h"
 #include "mpegvideo.h"
 
+#define MAX_FCODE        7
 #define UNI_AC_ENC_INDEX(run,level) ((run)*128 + (level))
 #define INPLACE_OFFSET 16
 
-- 
2.45.2


[-- Attachment #13: 0012-avcodec-ituh263enc-Move-MPEG-4-fcode_tab-to-mpeg4vid.patch --]
[-- Type: text/x-patch, Size: 2959 bytes --]

From 5075398a320885d1597b143362535685a5310a63 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 21:04:49 +0100
Subject: [PATCH 12/40] avcodec/ituh263enc: Move MPEG-4 fcode_tab to
 mpeg4videoenc.c

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/ituh263enc.c    | 12 ------------
 libavcodec/mpeg4videoenc.c | 11 +++++++++++
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 1ef4a8f88e..2152046b43 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -52,11 +52,6 @@
  */
 static uint8_t mv_penalty[MAX_FCODE+1][MAX_DMV*2+1];
 
-/**
- * Minimal fcode that a motion vector component would need.
- */
-static uint8_t fcode_tab[MAX_MV*2+1];
-
 /**
  * Minimal fcode that a motion vector component would need in umv.
  * All entries in this table are 1.
@@ -762,12 +757,6 @@ static av_cold void init_mv_penalty_and_fcode(void)
         }
     }
 
-    for(f_code=MAX_FCODE; f_code>0; f_code--){
-        for(mv=-(16<<f_code); mv<(16<<f_code); mv++){
-            fcode_tab[mv+MAX_MV]= f_code;
-        }
-    }
-
     for(mv=0; mv<MAX_MV*2+1; mv++){
         umv_fcode_tab[mv]= 1;
     }
@@ -844,7 +833,6 @@ av_cold void ff_h263_encode_init(MpegEncContext *s)
     // use fcodes >1 only for MPEG-4 & H.263 & H.263+ FIXME
     switch(s->codec_id){
     case AV_CODEC_ID_MPEG4:
-        s->fcode_tab= fcode_tab;
         break;
     case AV_CODEC_ID_H263P:
         if(s->umvplus)
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 0b31576dc5..64fb96a0cf 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -37,6 +37,11 @@
 #include "profiles.h"
 #include "version.h"
 
+/**
+ * Minimal fcode that a motion vector component would need.
+ */
+static uint8_t fcode_tab[MAX_MV*2+1];
+
 /* The uni_DCtab_* tables below contain unified bits+length tables to encode DC
  * differences in MPEG-4. Unified in the sense that the specification specifies
  * this encoding in several steps. */
@@ -1255,6 +1260,11 @@ static av_cold void mpeg4_encode_init_static(void)
 
     init_uni_mpeg4_rl_tab(&ff_mpeg4_rl_intra, uni_mpeg4_intra_rl_bits, uni_mpeg4_intra_rl_len);
     init_uni_mpeg4_rl_tab(&ff_h263_rl_inter,  uni_mpeg4_inter_rl_bits, uni_mpeg4_inter_rl_len);
+
+    for (int f_code = MAX_FCODE; f_code > 0; f_code--) {
+        for (int mv = -(16 << f_code); mv < (16 << f_code); mv++)
+            fcode_tab[mv + MAX_MV] = f_code;
+    }
 }
 
 static av_cold int encode_init(AVCodecContext *avctx)
@@ -1274,6 +1284,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
 
     ff_thread_once(&init_static_once, mpeg4_encode_init_static);
 
+    s->fcode_tab                = fcode_tab;
     s->min_qcoeff               = -2048;
     s->max_qcoeff               = 2047;
     s->intra_ac_vlc_length      = uni_mpeg4_intra_rl_len;
-- 
2.45.2


[-- Attachment #14: 0013-avcodec-ituh263enc-Remove-redundant-setting-of-dc_sc.patch --]
[-- Type: text/x-patch, Size: 1170 bytes --]

From 37ecd7a44e14bc9afd960bd41af17eb95171ebbd Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 20:32:59 +0100
Subject: [PATCH 13/40] avcodec/ituh263enc: Remove redundant setting of
 dc_scale_tables

ff_mpeg1_dc_scale_table is already the default dc_scale table
for both y and c.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/ituh263enc.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 2152046b43..ba2a373571 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -36,7 +36,6 @@
 #include "avcodec.h"
 #include "codec_internal.h"
 #include "mpegvideo.h"
-#include "mpegvideodata.h"
 #include "flvenc.h"
 #include "mpegvideoenc.h"
 #include "h263.h"
@@ -862,9 +861,6 @@ av_cold void ff_h263_encode_init(MpegEncContext *s)
     if(s->h263_aic){
          s->y_dc_scale_table=
          s->c_dc_scale_table= ff_aic_dc_scale_table;
-    }else{
-        s->y_dc_scale_table=
-        s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
     }
 
 #if CONFIG_H263_ENCODER // Snow and SVQ1 call this
-- 
2.45.2


[-- Attachment #15: 0014-avcodec-ituh263enc-Combine-branches.patch --]
[-- Type: text/x-patch, Size: 1260 bytes --]

From 019955adcf81134c029165da3b754a528fbc5330 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 21:15:30 +0100
Subject: [PATCH 14/40] avcodec/ituh263enc: Combine branches

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/ituh263enc.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index ba2a373571..02da090ba4 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -826,6 +826,9 @@ av_cold void ff_h263_encode_init(MpegEncContext *s)
     if(s->h263_aic){
         s->intra_ac_vlc_length     = uni_h263_intra_aic_rl_len;
         s->intra_ac_vlc_last_length= uni_h263_intra_aic_rl_len + 128*64;
+
+        s->y_dc_scale_table =
+        s->c_dc_scale_table = ff_aic_dc_scale_table;
     }
     s->ac_esc_length= 7+1+6+8;
 
@@ -858,10 +861,6 @@ av_cold void ff_h263_encode_init(MpegEncContext *s)
         s->min_qcoeff= -127;
         s->max_qcoeff=  127;
     }
-    if(s->h263_aic){
-         s->y_dc_scale_table=
-         s->c_dc_scale_table= ff_aic_dc_scale_table;
-    }
 
 #if CONFIG_H263_ENCODER // Snow and SVQ1 call this
     ff_h263dsp_init(&s->h263dsp);
-- 
2.45.2


[-- Attachment #16: 0015-avcodec-ituh263enc-Make-SVQ1-Snowenc-stop-calling-ff.patch --]
[-- Type: text/x-patch, Size: 10809 bytes --]

From 60be1a8e2138e86641643486f3781896c3412922 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 22:32:40 +0100
Subject: [PATCH 15/40] avcodec/ituh263enc: Make SVQ1+Snowenc stop calling
 ff_h263_encode_init()

They only do it for the mv_penalty table. Factor initializating
the static tables out into a function of its own; also move
everything not needed by SVQ1 or Snow behind #if CONFIG_H263_ENCODER
(this involved moving ff_h263_encode_motion() which is used
by svq1enc).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/h263enc.h    |   2 +
 libavcodec/ituh263enc.c | 247 ++++++++++++++++++++--------------------
 libavcodec/snowenc.c    |   2 +-
 libavcodec/svq1enc.c    |   2 +-
 4 files changed, 127 insertions(+), 126 deletions(-)

diff --git a/libavcodec/h263enc.h b/libavcodec/h263enc.h
index 784500ca7a..71e30931aa 100644
--- a/libavcodec/h263enc.h
+++ b/libavcodec/h263enc.h
@@ -24,6 +24,8 @@
 #include "h263data.h"
 #include "mpegvideoenc.h"
 
+const uint8_t (*ff_h263_get_mv_penalty(void))[MAX_DMV*2+1];
+
 void ff_h263_encode_init(MpegEncContext *s);
 void ff_h263_encode_picture_header(MpegEncContext *s);
 void ff_h263_encode_gob_header(MpegEncContext * s, int mb_line);
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 02da090ba4..8313b2c2c1 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -65,6 +65,127 @@ static uint8_t  uni_h263_inter_rl_len [64*64*2*2];
 //#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run) + (level)*64)
 #define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run)*128 + (level))
 
+static av_cold void init_mv_penalty_and_fcode(void)
+{
+    for (int f_code = 1; f_code <= MAX_FCODE; f_code++) {
+        for (int mv = -MAX_DMV; mv <= MAX_DMV; mv++) {
+            int len;
+
+            if (mv == 0) len = 1; // ff_mvtab[0][1]
+            else {
+                int val, bit_size, code;
+
+                bit_size = f_code - 1;
+
+                val = mv;
+                if (val < 0)
+                    val = -val;
+                val--;
+                code = (val >> bit_size) + 1;
+                if (code < 33) {
+                    len = ff_mvtab[code][1] + 1 + bit_size;
+                } else {
+                    len = 12 /* ff_mvtab[32][1] */ + av_log2(code>>5) + 2 + bit_size;
+                }
+            }
+
+            mv_penalty[f_code][mv + MAX_DMV] = len;
+        }
+    }
+
+    for (int mv = 0; mv < MAX_MV * 2 + 1; mv++)
+        umv_fcode_tab[mv]= 1;
+}
+
+static av_cold void init_uni_h263_rl_tab(const RLTable *rl, uint8_t *len_tab)
+{
+    av_assert0(MAX_LEVEL >= 64);
+    av_assert0(MAX_RUN   >= 63);
+
+    for (int slevel = -64; slevel < 64; slevel++) {
+        if (slevel == 0) continue;
+        for (int run = 0; run < 64; run++) {
+            for (int last = 0; last <= 1; last++) {
+                const int index = UNI_MPEG4_ENC_INDEX(last, run, slevel + 64);
+                int level = slevel < 0 ? -slevel : slevel;
+                int sign  = slevel < 0 ? 1 : 0;
+                int bits, len, code;
+
+                len_tab[index] = 100;
+
+                /* ESC0 */
+                code = get_rl_index(rl, last, run, level);
+                bits = rl->table_vlc[code][0];
+                len  = rl->table_vlc[code][1];
+                bits = bits * 2 + sign;
+                len++;
+
+                if (code != rl->n && len < len_tab[index])
+                    len_tab[index] = len;
+
+                /* ESC */
+                bits = rl->table_vlc[rl->n][0];
+                len  = rl->table_vlc[rl->n][1];
+                bits = bits *   2 + last; len++;
+                bits = bits *  64 + run;  len += 6;
+                bits = bits * 256 + (level & 0xff); len += 8;
+
+                if (len < len_tab[index])
+                    len_tab[index] = len;
+            }
+        }
+    }
+}
+
+static av_cold void h263_encode_init_static(void)
+{
+    static uint8_t rl_intra_table[2][2 * MAX_RUN + MAX_LEVEL + 3];
+
+    ff_rl_init(&ff_rl_intra_aic, rl_intra_table);
+    ff_h263_init_rl_inter();
+
+    init_uni_h263_rl_tab(&ff_rl_intra_aic,  uni_h263_intra_aic_rl_len);
+    init_uni_h263_rl_tab(&ff_h263_rl_inter, uni_h263_inter_rl_len);
+
+    init_mv_penalty_and_fcode();
+}
+
+av_cold const uint8_t (*ff_h263_get_mv_penalty(void))[MAX_DMV*2+1]
+{
+    static AVOnce init_static_once = AV_ONCE_INIT;
+
+    ff_thread_once(&init_static_once, h263_encode_init_static);
+
+    return mv_penalty;
+}
+
+void ff_h263_encode_motion(PutBitContext *pb, int val, int f_code)
+{
+    if (val == 0) {
+        /* zero vector -- corresponds to ff_mvtab[0] */
+        put_bits(pb, 1, 1);
+    } else {
+        int sign, code, bits;
+        int bit_size = f_code - 1;
+        int range = 1 << bit_size;
+        /* modulo encoding */
+        val = sign_extend(val, 6 + bit_size);
+        sign = val>>31;
+        val= (val^sign)-sign;
+        sign&=1;
+
+        val--;
+        code = (val >> bit_size) + 1;
+        bits = val & (range - 1);
+
+        put_bits(pb, ff_mvtab[code][1] + 1, (ff_mvtab[code][0] << 1) | sign);
+        if (bit_size > 0) {
+            put_bits(pb, bit_size, bits);
+        }
+    }
+}
+
+#if CONFIG_H263_ENCODER // Snow and SVQ1 need the above
 static const uint8_t wrong_run[102] = {
  1,  2,  3,  5,  4, 10,  9,  8,
 11, 15, 17, 16, 23, 22, 21, 20,
@@ -698,128 +819,9 @@ void ff_h263_update_mb(MpegEncContext *s)
     ff_h263_update_motion_val(s);
 }
 
-void ff_h263_encode_motion(PutBitContext *pb, int val, int f_code)
-{
-    int range, bit_size, sign, code, bits;
-
-    if (val == 0) {
-        /* zero vector -- corresponds to ff_mvtab[0] */
-        put_bits(pb, 1, 1);
-    } else {
-        bit_size = f_code - 1;
-        range = 1 << bit_size;
-        /* modulo encoding */
-        val = sign_extend(val, 6 + bit_size);
-        sign = val>>31;
-        val= (val^sign)-sign;
-        sign&=1;
-
-        val--;
-        code = (val >> bit_size) + 1;
-        bits = val & (range - 1);
-
-        put_bits(pb, ff_mvtab[code][1] + 1, (ff_mvtab[code][0] << 1) | sign);
-        if (bit_size > 0) {
-            put_bits(pb, bit_size, bits);
-        }
-    }
-}
-
-static av_cold void init_mv_penalty_and_fcode(void)
-{
-    int f_code;
-    int mv;
-
-    for(f_code=1; f_code<=MAX_FCODE; f_code++){
-        for(mv=-MAX_DMV; mv<=MAX_DMV; mv++){
-            int len;
-
-            if (mv==0) len = 1; // ff_mvtab[0][1]
-            else{
-                int val, bit_size, code;
-
-                bit_size = f_code - 1;
-
-                val=mv;
-                if (val < 0)
-                    val = -val;
-                val--;
-                code = (val >> bit_size) + 1;
-                if(code<33){
-                    len= ff_mvtab[code][1] + 1 + bit_size;
-                }else{
-                    len = 12 /* ff_mvtab[32][1] */ + av_log2(code>>5) + 2 + bit_size;
-                }
-            }
-
-            mv_penalty[f_code][mv+MAX_DMV]= len;
-        }
-    }
-
-    for(mv=0; mv<MAX_MV*2+1; mv++){
-        umv_fcode_tab[mv]= 1;
-    }
-}
-
-static av_cold void init_uni_h263_rl_tab(const RLTable *rl, uint8_t *len_tab)
-{
-    int slevel, run, last;
-
-    av_assert0(MAX_LEVEL >= 64);
-    av_assert0(MAX_RUN   >= 63);
-
-    for(slevel=-64; slevel<64; slevel++){
-        if(slevel==0) continue;
-        for(run=0; run<64; run++){
-            for(last=0; last<=1; last++){
-                const int index= UNI_MPEG4_ENC_INDEX(last, run, slevel+64);
-                int level= slevel < 0 ? -slevel : slevel;
-                int sign= slevel < 0 ? 1 : 0;
-                int bits, len, code;
-
-                len_tab[index]= 100;
-
-                /* ESC0 */
-                code= get_rl_index(rl, last, run, level);
-                bits= rl->table_vlc[code][0];
-                len=  rl->table_vlc[code][1];
-                bits=bits*2+sign; len++;
-
-                if (code != rl->n && len < len_tab[index])
-                    len_tab [index]= len;
-
-                /* ESC */
-                bits= rl->table_vlc[rl->n][0];
-                len = rl->table_vlc[rl->n][1];
-                bits=bits*2+last; len++;
-                bits=bits*64+run; len+=6;
-                bits=bits*256+(level&0xff); len+=8;
-
-                if (len < len_tab[index])
-                    len_tab [index]= len;
-            }
-        }
-    }
-}
-
-static av_cold void h263_encode_init_static(void)
-{
-    static uint8_t rl_intra_table[2][2 * MAX_RUN + MAX_LEVEL + 3];
-
-    ff_rl_init(&ff_rl_intra_aic, rl_intra_table);
-    ff_h263_init_rl_inter();
-
-    init_uni_h263_rl_tab(&ff_rl_intra_aic,  uni_h263_intra_aic_rl_len);
-    init_uni_h263_rl_tab(&ff_h263_rl_inter, uni_h263_inter_rl_len);
-
-    init_mv_penalty_and_fcode();
-}
-
 av_cold void ff_h263_encode_init(MpegEncContext *s)
 {
-    static AVOnce init_static_once = AV_ONCE_INIT;
-
-    s->me.mv_penalty= mv_penalty; // FIXME exact table for MSMPEG4 & H.263+
+    s->me.mv_penalty = ff_h263_get_mv_penalty(); // FIXME exact table for MSMPEG4 & H.263+
 
     s->intra_ac_vlc_length     =s->inter_ac_vlc_length     = uni_h263_inter_rl_len;
     s->intra_ac_vlc_last_length=s->inter_ac_vlc_last_length= uni_h263_inter_rl_len + 128*64;
@@ -862,11 +864,7 @@ av_cold void ff_h263_encode_init(MpegEncContext *s)
         s->max_qcoeff=  127;
     }
 
-#if CONFIG_H263_ENCODER // Snow and SVQ1 call this
     ff_h263dsp_init(&s->h263dsp);
-#endif
-
-    ff_thread_once(&init_static_once, h263_encode_init_static);
 }
 
 void ff_h263_encode_mba(MpegEncContext *s)
@@ -945,3 +943,4 @@ const FFCodec ff_h263p_encoder = {
     FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
 };
+#endif
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index 0623c9d196..5f539a57df 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -240,7 +240,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
         return AVERROR(ENOMEM);
     mpv->me.score_map = mpv->me.map + ME_MAP_SIZE;
 
-    ff_h263_encode_init(mpv); //mv_penalty
+    mpv->me.mv_penalty = ff_h263_get_mv_penalty();
 
     s->max_ref_frames = av_clip(avctx->refs, 1, MAX_REF_FRAMES);
 
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index d969be25c1..0d27a73500 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -631,7 +631,7 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx)
 
     ff_svq1enc_init(&s->svq1encdsp);
 
-    ff_h263_encode_init(&s->m); // mv_penalty
+    s->m.me.mv_penalty = ff_h263_get_mv_penalty();
 
     return write_ident(avctx, s->avctx->flags & AV_CODEC_FLAG_BITEXACT ? "Lavc" : LIBAVCODEC_IDENT);
 }
-- 
2.45.2


[-- Attachment #17: 0016-avcodec-ituh263enc-Use-memset-where-appropriate.patch --]
[-- Type: text/x-patch, Size: 1035 bytes --]

From 73c4dcdccd958d1ccdb7a64e42f52c270f500ab5 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 22:45:57 +0100
Subject: [PATCH 16/40] avcodec/ituh263enc: Use memset where appropriate

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/ituh263enc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 8313b2c2c1..2d750439d1 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -30,6 +30,7 @@
 #include "config_components.h"
 
 #include <limits.h>
+#include <string.h>
 
 #include "libavutil/attributes.h"
 #include "libavutil/thread.h"
@@ -93,8 +94,7 @@ static av_cold void init_mv_penalty_and_fcode(void)
         }
     }
 
-    for (int mv = 0; mv < MAX_MV * 2 + 1; mv++)
-        umv_fcode_tab[mv]= 1;
+    memset(umv_fcode_tab, 1, sizeof(umv_fcode_tab));
 }
 
 static av_cold void init_uni_h263_rl_tab(const RLTable *rl, uint8_t *len_tab)
-- 
2.45.2


[-- Attachment #18: 0017-avcodec-flvenc-Remove-redundant-setting-of-dc_scale_.patch --]
[-- Type: text/x-patch, Size: 1474 bytes --]

From c4444def5a2fcce439f2c819ca5fe39b1331c926 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 20:09:58 +0100
Subject: [PATCH 17/40] avcodec/flvenc: Remove redundant setting of
 dc_scale_tables

h263_aic is always zero for FLV and ff_mpeg1_dc_scale_table
is already the default dc_scale table for both y and c.
h263_aic is also always zero for the FLV decoder.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/flvenc.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/libavcodec/flvenc.c b/libavcodec/flvenc.c
index cbe3b7f056..192c2a929f 100644
--- a/libavcodec/flvenc.c
+++ b/libavcodec/flvenc.c
@@ -20,9 +20,7 @@
 
 #include "codec_internal.h"
 #include "flvenc.h"
-#include "h263data.h"
 #include "mpegvideo.h"
-#include "mpegvideodata.h"
 #include "mpegvideoenc.h"
 
 void ff_flv_encode_picture_header(MpegEncContext *s)
@@ -63,14 +61,6 @@ void ff_flv_encode_picture_header(MpegEncContext *s)
     put_bits(&s->pb, 1, 1);   /* DeblockingFlag: on */
     put_bits(&s->pb, 5, s->qscale);   /* Quantizer */
     put_bits(&s->pb, 1, 0);   /* ExtraInformation */
-
-    if (s->h263_aic) {
-        s->y_dc_scale_table =
-        s->c_dc_scale_table = ff_aic_dc_scale_table;
-    } else {
-        s->y_dc_scale_table =
-        s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
-    }
 }
 
 void ff_flv2_encode_ac_esc(PutBitContext *pb, int slevel, int level,
-- 
2.45.2


[-- Attachment #19: 0018-avcodec-ituh263dec-Reorder-branches.patch --]
[-- Type: text/x-patch, Size: 1310 bytes --]

From d1d16bc306b0d90d1a1ed399433ab38c50d3e9fc Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 2 Mar 2025 23:02:26 +0100
Subject: [PATCH 18/40] avcodec/ituh263dec: Reorder branches

(To perform this optimization a compiler would have to look
at both ff_rv_decode_dc() and av_log(). The latter seems very
unlikely.)

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/ituh263dec.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c
index e0f3034e57..93349a3b0e 100644
--- a/libavcodec/ituh263dec.c
+++ b/libavcodec/ituh263dec.c
@@ -543,6 +543,8 @@ static int h263_decode_block(MpegEncContext * s, int16_t * block,
     if (s->h263_aic && s->mb_intra) {
         rl = &ff_rl_intra_aic;
         i = 0;
+        if (!coded)
+            goto not_coded;
         if (s->ac_pred) {
             if (s->h263_aic_dir)
                 scan_table = s->permutated_intra_v_scantable; /* left */
@@ -587,8 +589,6 @@ static int h263_decode_block(MpegEncContext * s, int16_t * block,
         i = 0;
     }
     if (!coded) {
-        if (s->mb_intra && s->h263_aic)
-            goto not_coded;
         s->block_last_index[n] = i - 1;
         return 0;
     }
-- 
2.45.2


[-- Attachment #20: 0019-avcodec-mpeg4videodec-Bail-out-earlier-when-parsing.patch --]
[-- Type: text/x-patch, Size: 1907 bytes --]

From a7230e880bc34fb85dfca22db1e5d28380a12cec Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 2 Mar 2025 23:09:39 +0100
Subject: [PATCH 19/40] avcodec/mpeg4videodec: Bail out earlier when parsing

The scantables are unused for the parser (and in fact
the IDCT permutation used has not been initialized at all).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg4videodec.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index eace43b4cb..2a340ea682 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -3250,6 +3250,12 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb,
         } else
             s->alternate_scan = 0;
     }
+    /* Skip at this point when only parsing since the remaining
+     * data is not useful for a parser and requires the
+     * sprite_trajectory VLC to be initialized. */
+    if (parse_only)
+        goto end;
+
     if (s->alternate_scan) {
         ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable,   ff_alternate_vertical_scan);
         ff_permute_scantable(s->permutated_intra_h_scantable, ff_alternate_vertical_scan,
@@ -3262,12 +3268,6 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb,
     ff_permute_scantable(s->permutated_intra_v_scantable, ff_alternate_vertical_scan,
                          s->idsp.idct_permutation);
 
-    /* Skip at this point when only parsing since the remaining
-     * data is not useful for a parser and requires the
-     * sprite_trajectory VLC to be initialized. */
-    if (parse_only)
-        goto end;
-
     if (s->pict_type == AV_PICTURE_TYPE_S) {
         if((ctx->vol_sprite_usage == STATIC_SPRITE ||
             ctx->vol_sprite_usage == GMC_SPRITE)) {
-- 
2.45.2


[-- Attachment #21: 0020-avcodec-mpeg4video-Split-ff_mpeg4_pred_dc.patch --]
[-- Type: text/x-patch, Size: 7713 bytes --]

From 932aa92fcb592a1aee1310c27aad934376f3340d Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 00:21:04 +0100
Subject: [PATCH 20/40] avcodec/mpeg4video: Split ff_mpeg4_pred_dc()

It currently does two things: a) Get a prediction for the dc
and the dc direction and b) process said prediction. Processing
the prediction differs for encoding (getting a diff) and decoding
(getting the level via diff+prediction). So having a common function
performing b) makes no sense.

Even worse, there is a decoding mode where the dc coefficient (diff)
is not coded specially and therefore unavailable before entering
the block decoding loop, so that one can only perform a). Before
this commit, the decoder simply called ff_mpeg4_pred_dc() twice;
the results of the b) part of the call before the loop were ignored
(but the compiler could not elide them because they involved error
messages) and a) was also performed twice.

This commit changes this by splitting b) out of ff_mpeg4_pred_dc()
and moving this code to decoder and encoder.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg4video.h    | 47 ++++---------------------------------
 libavcodec/mpeg4videodec.c | 48 ++++++++++++++++++++++++++++++++++----
 libavcodec/mpeg4videoenc.c | 10 ++++++--
 3 files changed, 55 insertions(+), 50 deletions(-)

diff --git a/libavcodec/mpeg4video.h b/libavcodec/mpeg4video.h
index 29b11eb92e..9ac18943a2 100644
--- a/libavcodec/mpeg4video.h
+++ b/libavcodec/mpeg4video.h
@@ -44,24 +44,15 @@ int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my);
 
 /**
  * Predict the dc.
- * encoding quantized level -> quantized diff
- * decoding quantized diff -> quantized level
  * @param n block index (0-3 are luma, 4-5 are chroma)
  * @param dir_ptr pointer to an integer where the prediction direction will be stored
  */
-static inline int ff_mpeg4_pred_dc(MpegEncContext *s, int n, int level,
-                                   int *dir_ptr, int encoding)
+static inline int ff_mpeg4_pred_dc(MpegEncContext *s, int n, int *dir_ptr)
 {
-    int a, b, c, wrap, pred, scale, ret;
-    int16_t *dc_val;
+    int a, b, c, wrap, pred;
+    const int16_t *dc_val;
 
     /* find prediction */
-    if (n < 4)
-        scale = s->y_dc_scale;
-    else
-        scale = s->c_dc_scale;
-    if (IS_3IV1)
-        scale = 8;
 
     wrap   = s->block_wrap[n];
     dc_val = s->dc_val[0] + s->block_index[n];
@@ -93,37 +84,7 @@ static inline int ff_mpeg4_pred_dc(MpegEncContext *s, int n, int level,
         pred     = a;
         *dir_ptr = 0; /* left */
     }
-    /* we assume pred is positive */
-    pred = FASTDIV((pred + (scale >> 1)), scale);
-
-    if (encoding) {
-        ret = level - pred;
-    } else {
-        level += pred;
-        ret    = level;
-    }
-    level *= scale;
-    if (level & (~2047)) {
-        if (!s->encoding && (s->avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_AGGRESSIVE))) {
-            if (level < 0) {
-                av_log(s->avctx, AV_LOG_ERROR,
-                       "dc<0 at %dx%d\n", s->mb_x, s->mb_y);
-                return AVERROR_INVALIDDATA;
-            }
-            if (level > 2048 + scale) {
-                av_log(s->avctx, AV_LOG_ERROR,
-                       "dc overflow at %dx%d\n", s->mb_x, s->mb_y);
-                return AVERROR_INVALIDDATA;
-            }
-        }
-        if (level < 0)
-            level = 0;
-        else if (!(s->workaround_bugs & FF_BUG_DC_CLIP))
-            level = 2047;
-    }
-    dc_val[0] = level;
-
-    return ret;
+    return pred;
 }
 
 #endif /* AVCODEC_MPEG4VIDEO_H */
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 2a340ea682..31d00dd0b9 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -880,6 +880,43 @@ static inline int get_amv(Mpeg4DecContext *ctx, int n)
     return sum;
 }
 
+static inline int mpeg4_get_level_dc(MpegEncContext *s, int n, int pred, int level)
+{
+    int scale = n < 4 ? s->y_dc_scale : s->c_dc_scale;
+    int ret;
+
+    if (IS_3IV1)
+        scale = 8;
+
+    /* we assume pred is positive */
+    pred = FASTDIV((pred + (scale >> 1)), scale);
+
+    level += pred;
+    ret    = level;
+    level *= scale;
+    if (level & (~2047)) {
+        if (s->avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_AGGRESSIVE)) {
+            if (level < 0) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "dc<0 at %dx%d\n", s->mb_x, s->mb_y);
+                return AVERROR_INVALIDDATA;
+            }
+            if (level > 2048 + scale) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "dc overflow at %dx%d\n", s->mb_x, s->mb_y);
+                return AVERROR_INVALIDDATA;
+            }
+        }
+        if (level < 0)
+            level = 0;
+        else if (!(s->workaround_bugs & FF_BUG_DC_CLIP))
+            level = 2047;
+    }
+    s->dc_val[0][s->block_index[n]] = level;
+
+    return ret;
+}
+
 /**
  * Decode the dc value.
  * @param n block index (0-3 are luma, 4-5 are chroma)
@@ -888,7 +925,7 @@ static inline int get_amv(Mpeg4DecContext *ctx, int n)
  */
 static inline int mpeg4_decode_dc(MpegEncContext *s, int n, int *dir_ptr)
 {
-    int level, code;
+    int level, code, pred;
 
     if (n < 4)
         code = get_vlc2(&s->gb, dc_lum, DC_VLC_BITS, 1);
@@ -926,7 +963,8 @@ static inline int mpeg4_decode_dc(MpegEncContext *s, int n, int *dir_ptr)
         }
     }
 
-    return ff_mpeg4_pred_dc(s, n, level, dir_ptr, 0);
+    pred = ff_mpeg4_pred_dc(s, n, dir_ptr);
+    return mpeg4_get_level_dc(s, n, pred, level);
 }
 
 /**
@@ -1290,7 +1328,7 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block,
                                      int use_intra_dc_vlc, int rvlc)
 {
     MpegEncContext *s = &ctx->m;
-    int level, i, last, run, qmul, qadd;
+    int level, i, last, run, qmul, qadd, pred;
     int av_uninit(dc_pred_dir);
     const RLTable *rl;
     const RL_VLC_ELEM *rl_vlc;
@@ -1317,7 +1355,7 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block,
             i        = 0;
         } else {
             i = -1;
-            ff_mpeg4_pred_dc(s, n, 0, &dc_pred_dir, 0);
+            pred = ff_mpeg4_pred_dc(s, n, &dc_pred_dir);
         }
         if (!coded)
             goto not_coded;
@@ -1540,7 +1578,7 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block,
 not_coded:
     if (intra) {
         if (!use_intra_dc_vlc) {
-            block[0] = ff_mpeg4_pred_dc(s, n, block[0], &dc_pred_dir, 0);
+            block[0] = mpeg4_get_level_dc(s, n, pred, block[0]);
 
             i -= i >> 31;  // if (i == -1) i = 0;
         }
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 64fb96a0cf..26f9b40ff7 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -806,8 +806,14 @@ void ff_mpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64],
         const uint8_t *scan_table[6];
         int i;
 
-        for (i = 0; i < 6; i++)
-            dc_diff[i] = ff_mpeg4_pred_dc(s, i, block[i][0], &dir[i], 1);
+        for (int i = 0; i < 6; i++) {
+            int pred  = ff_mpeg4_pred_dc(s, i, &dir[i]);
+            int scale = i < 4 ? s->y_dc_scale : s->c_dc_scale;
+
+            pred = FASTDIV((pred + (scale >> 1)), scale);
+            dc_diff[i] = block[i][0] - pred;
+            s->dc_val[0][s->block_index[i]] = av_clip_uintp2(block[i][0] * scale, 11);
+        }
 
         if (s->avctx->flags & AV_CODEC_FLAG_AC_PRED) {
             s->ac_pred = decide_ac_pred(s, block, dir, scan_table, zigzag_last_index);
-- 
2.45.2


[-- Attachment #22: 0021-avcodec-mpeg4video-Move-IS_3IV1-macro-to-mpeg4videod.patch --]
[-- Type: text/x-patch, Size: 1604 bytes --]

From 0f22de2d0117026b009e55a81ed95e17784ebb08 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 01:12:02 +0100
Subject: [PATCH 21/40] avcodec/mpeg4video: Move IS_3IV1 macro to
 mpeg4videodec.c

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg4video.h    | 6 ------
 libavcodec/mpeg4videodec.c | 6 ++++++
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/libavcodec/mpeg4video.h b/libavcodec/mpeg4video.h
index 9ac18943a2..cfc6dcb684 100644
--- a/libavcodec/mpeg4video.h
+++ b/libavcodec/mpeg4video.h
@@ -36,12 +36,6 @@ void ff_mpeg4_init_direct_mv(MpegEncContext *s);
  */
 int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my);
 
-#if 0 //3IV1 is quite rare and it slows things down a tiny bit
-#define IS_3IV1 s->codec_tag == AV_RL32("3IV1")
-#else
-#define IS_3IV1 0
-#endif
-
 /**
  * Predict the dc.
  * @param n block index (0-3 are luma, 4-5 are chroma)
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 31d00dd0b9..f4cfb8a18f 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -49,6 +49,12 @@
 #include "xvididct.h"
 #include "unary.h"
 
+#if 0 //3IV1 is quite rare and it slows things down a tiny bit
+#define IS_3IV1 s->codec_tag == AV_RL32("3IV1")
+#else
+#define IS_3IV1 0
+#endif
+
 /* The defines below define the number of bits that are read at once for
  * reading vlc values. Changing these may improve speed and data cache needs
  * be aware though that decreasing them may need the number of stages that is
-- 
2.45.2


[-- Attachment #23: 0022-avcodec-mpegvideo_enc-Only-allocate-chroma-intra-mat.patch --]
[-- Type: text/x-patch, Size: 3113 bytes --]

From ce3604d8244abf3278e2ba74876cb4ff2e9fe11d Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 27 Feb 2025 19:01:03 +0100
Subject: [PATCH 22/40] avcodec/mpegvideo_enc: Only allocate chroma intra
 matrices when needed

Also start factoring the matrix-init code out into a function
of its own to declutter ff_mpv_encode_init().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 27 ++++++++++++++++++---------
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 1fe69f89a6..79d6bfc056 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -348,6 +348,20 @@ static av_cold int me_cmp_init(MpegEncContext *s, AVCodecContext *avctx)
     return 0;
 }
 
+static av_cold int init_matrices(MpegEncContext *s, AVCodecContext *avctx)
+{
+    if (s->out_format == FMT_MJPEG) {
+        if (!FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix,   32) ||
+            !FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix16, 32))
+            return AVERROR(ENOMEM);
+    } else {
+        s->q_chroma_intra_matrix   = s->q_intra_matrix;
+        s->q_chroma_intra_matrix16 = s->q_intra_matrix16;
+    }
+
+    return 0;
+}
+
 /* init video encoder */
 av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 {
@@ -866,10 +880,8 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 
     if (!(avctx->stats_out = av_mallocz(256))               ||
         !FF_ALLOCZ_TYPED_ARRAY(s->q_intra_matrix,          32) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix,   32) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->q_inter_matrix,          32) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->q_intra_matrix16,        32) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix16, 32) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->q_inter_matrix16,        32) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->input_picture,           MAX_B_FRAMES + 1) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->reordered_input_picture, MAX_B_FRAMES + 1) ||
@@ -877,6 +889,10 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         !(s->picture_pool = ff_mpv_alloc_pic_pool(0)))
         return AVERROR(ENOMEM);
 
+    ret = init_matrices(s, avctx);
+    if (ret < 0)
+        return ret;
+
     /* Allocate MV tables; the MV and MB tables will be copied
      * to slice contexts by ff_update_duplicate_context().  */
     mv_table_size = (s->mb_height + 2) * s->mb_stride + 1;
@@ -3700,13 +3716,6 @@ static int encode_picture(MpegEncContext *s, const AVPacket *pkt)
         update_qscale(s);
     }
 
-    if (s->out_format != FMT_MJPEG) {
-        if(s->q_chroma_intra_matrix   != s->q_intra_matrix  ) av_freep(&s->q_chroma_intra_matrix);
-        if(s->q_chroma_intra_matrix16 != s->q_intra_matrix16) av_freep(&s->q_chroma_intra_matrix16);
-        s->q_chroma_intra_matrix   = s->q_intra_matrix;
-        s->q_chroma_intra_matrix16 = s->q_intra_matrix16;
-    }
-
     ff_me_init_pic(s);
 
     s->mb_intra=0; //for the rate distortion & bit compare functions
-- 
2.45.2


[-- Attachment #24: 0023-avcodec-mpegvideo_enc-Set-chroma_intra_matrix-for-Sp.patch --]
[-- Type: text/x-patch, Size: 1426 bytes --]

From fae7e3cd58f161d495c52f0a93b09a3284bf079a Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 27 Feb 2025 21:13:03 +0100
Subject: [PATCH 23/40] avcodec/mpegvideo_enc: Set chroma_intra_matrix for
 SpeedHQ

Used with trellis; notice that inter_matrix is unused for
(intra-only) SpeedHQ, so it is irrelevant that its value changes.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 79d6bfc056..11ebbe6a30 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -992,11 +992,8 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) {
             s->intra_matrix[j] =
             s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i];
-        } else if (CONFIG_SPEEDHQ_ENCODER && s->codec_id == AV_CODEC_ID_SPEEDHQ) {
-            s->intra_matrix[j] =
-            s->inter_matrix[j] = ff_mpeg1_default_intra_matrix[i];
         } else {
-            /* MPEG-1/2 */
+            /* MPEG-1/2, SpeedHQ */
             s->chroma_intra_matrix[j] =
             s->intra_matrix[j] = ff_mpeg1_default_intra_matrix[i];
             s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i];
-- 
2.45.2


[-- Attachment #25: 0024-avcodec-mpegvideo_enc-Factor-checks-out-of-loop.patch --]
[-- Type: text/x-patch, Size: 3364 bytes --]

From 538e93e26dce8639910a1f84f931d45247f2f938 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 27 Feb 2025 22:01:12 +0100
Subject: [PATCH 24/40] avcodec/mpegvideo_enc: Factor checks out of loop

Also move this code to handle_matrices().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 49 +++++++++++++++++++++-----------------
 1 file changed, 27 insertions(+), 22 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 11ebbe6a30..aab82248e0 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -350,6 +350,8 @@ static av_cold int me_cmp_init(MpegEncContext *s, AVCodecContext *avctx)
 
 static av_cold int init_matrices(MpegEncContext *s, AVCodecContext *avctx)
 {
+    const uint16_t *intra_matrix, *inter_matrix;
+
     if (s->out_format == FMT_MJPEG) {
         if (!FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix,   32) ||
             !FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix16, 32))
@@ -359,6 +361,31 @@ static av_cold int init_matrices(MpegEncContext *s, AVCodecContext *avctx)
         s->q_chroma_intra_matrix16 = s->q_intra_matrix16;
     }
 
+    if (CONFIG_MPEG4_ENCODER && s->codec_id == AV_CODEC_ID_MPEG4 &&
+        s->mpeg_quant) {
+        intra_matrix = ff_mpeg4_default_intra_matrix;
+        inter_matrix = ff_mpeg4_default_non_intra_matrix;
+    } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) {
+        intra_matrix =
+        inter_matrix = ff_mpeg1_default_non_intra_matrix;
+    } else {
+        /* MPEG-1/2, SpeedHQ */
+        intra_matrix = ff_mpeg1_default_intra_matrix;
+        inter_matrix = ff_mpeg1_default_non_intra_matrix;
+    }
+    if (avctx->intra_matrix)
+        intra_matrix = avctx->intra_matrix;
+    if (avctx->inter_matrix)
+        inter_matrix = avctx->inter_matrix;
+
+    /* init q matrix */
+    for (int i = 0; i < 64; i++) {
+        int j = s->idsp.idct_permutation[i];
+
+        s->intra_matrix[j] = s->chroma_intra_matrix[j] = intra_matrix[i];
+        s->inter_matrix[j] = inter_matrix[i];
+    }
+
     return 0;
 }
 
@@ -982,28 +1009,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 #endif
     }
 
-    /* init q matrix */
-    for (i = 0; i < 64; i++) {
-        int j = s->idsp.idct_permutation[i];
-        if (CONFIG_MPEG4_ENCODER && s->codec_id == AV_CODEC_ID_MPEG4 &&
-            s->mpeg_quant) {
-            s->intra_matrix[j] = ff_mpeg4_default_intra_matrix[i];
-            s->inter_matrix[j] = ff_mpeg4_default_non_intra_matrix[i];
-        } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) {
-            s->intra_matrix[j] =
-            s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i];
-        } else {
-            /* MPEG-1/2, SpeedHQ */
-            s->chroma_intra_matrix[j] =
-            s->intra_matrix[j] = ff_mpeg1_default_intra_matrix[i];
-            s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i];
-        }
-        if (avctx->intra_matrix)
-            s->intra_matrix[j] = avctx->intra_matrix[i];
-        if (avctx->inter_matrix)
-            s->inter_matrix[j] = avctx->inter_matrix[i];
-    }
-
     /* precompute matrix */
     /* for mjpeg, we do include qscale in the matrix */
     if (s->out_format != FMT_MJPEG) {
-- 
2.45.2


[-- Attachment #26: 0025-avcodec-mpegvideo_enc-Only-allocate-inter-matrices-w.patch --]
[-- Type: text/x-patch, Size: 4132 bytes --]

From 519b858e9bcb066b4542573ab1928cc0599f402c Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 27 Feb 2025 22:29:58 +0100
Subject: [PATCH 25/40] avcodec/mpegvideo_enc: Only allocate inter matrices
 when needed

Also allocate them jointly with intra matrices when needed.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index aab82248e0..e4b89983ad 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -348,18 +348,27 @@ static av_cold int me_cmp_init(MpegEncContext *s, AVCodecContext *avctx)
     return 0;
 }
 
+#define ALLOCZ_ARRAYS(p, mult, numb) ((p) = av_calloc(numb, mult * sizeof(*(p))))
 static av_cold int init_matrices(MpegEncContext *s, AVCodecContext *avctx)
 {
+    const int nb_matrices = 1 + (s->out_format == FMT_MJPEG) + !s->intra_only;
     const uint16_t *intra_matrix, *inter_matrix;
 
+    if (!ALLOCZ_ARRAYS(s->q_intra_matrix,   32, nb_matrices) ||
+        !ALLOCZ_ARRAYS(s->q_intra_matrix16, 32, nb_matrices))
+        return AVERROR(ENOMEM);
+
     if (s->out_format == FMT_MJPEG) {
-        if (!FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix,   32) ||
-            !FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix16, 32))
-            return AVERROR(ENOMEM);
+        s->q_chroma_intra_matrix   = s->q_intra_matrix   + 32;
+        s->q_chroma_intra_matrix16 = s->q_intra_matrix16 + 32;
     } else {
         s->q_chroma_intra_matrix   = s->q_intra_matrix;
         s->q_chroma_intra_matrix16 = s->q_intra_matrix16;
     }
+    if (!s->intra_only) {
+        s->q_inter_matrix   = s->q_intra_matrix   + 32;
+        s->q_inter_matrix16 = s->q_intra_matrix16 + 32;
+    }
 
     if (CONFIG_MPEG4_ENCODER && s->codec_id == AV_CODEC_ID_MPEG4 &&
         s->mpeg_quant) {
@@ -906,10 +915,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         return ret;
 
     if (!(avctx->stats_out = av_mallocz(256))               ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->q_intra_matrix,          32) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->q_inter_matrix,          32) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->q_intra_matrix16,        32) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->q_inter_matrix16,        32) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->input_picture,           MAX_B_FRAMES + 1) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->reordered_input_picture, MAX_B_FRAMES + 1) ||
         !(s->new_pic = av_frame_alloc()) ||
@@ -948,7 +953,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         !(s->mb_mean = av_mallocz(mb_array_size)))
         return AVERROR(ENOMEM);
 
-#define ALLOCZ_ARRAYS(p, mult, numb) ((p) = av_calloc(numb, mult * sizeof(*(p))))
     if (s->codec_id == AV_CODEC_ID_MPEG4 ||
         (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
         int16_t (*tmp1)[2];
@@ -1019,6 +1023,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         ff_convert_matrix(s, s->q_intra_matrix, s->q_intra_matrix16,
                           s->intra_matrix, s->intra_quant_bias, avctx->qmin,
                           31, 1);
+        if (s->q_inter_matrix)
         ff_convert_matrix(s, s->q_inter_matrix, s->q_inter_matrix16,
                           s->inter_matrix, s->inter_quant_bias, avctx->qmin,
                           31, 0);
@@ -1093,14 +1098,8 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
     av_freep(&s->cplx_tab);
     av_freep(&s->bits_tab);
 
-    if(s->q_chroma_intra_matrix   != s->q_intra_matrix  ) av_freep(&s->q_chroma_intra_matrix);
-    if(s->q_chroma_intra_matrix16 != s->q_intra_matrix16) av_freep(&s->q_chroma_intra_matrix16);
-    s->q_chroma_intra_matrix=   NULL;
-    s->q_chroma_intra_matrix16= NULL;
     av_freep(&s->q_intra_matrix);
-    av_freep(&s->q_inter_matrix);
     av_freep(&s->q_intra_matrix16);
-    av_freep(&s->q_inter_matrix16);
     av_freep(&s->input_picture);
     av_freep(&s->reordered_input_picture);
     av_freep(&s->dct_offset);
-- 
2.45.2


[-- Attachment #27: 0026-avcodec-mpegvideo_enc-Don-t-init-matrices-unnecessar.patch --]
[-- Type: text/x-patch, Size: 1190 bytes --]

From 17160356eedd79dec4a3403b68d6f43e2bfacf49 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 27 Feb 2025 22:44:21 +0100
Subject: [PATCH 26/40] avcodec/mpegvideo_enc: Don't init matrices
 unnecessarily for MJPEG

The MJPEG initialization happens later.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index e4b89983ad..81e004d1a8 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -361,6 +361,10 @@ static av_cold int init_matrices(MpegEncContext *s, AVCodecContext *avctx)
     if (s->out_format == FMT_MJPEG) {
         s->q_chroma_intra_matrix   = s->q_intra_matrix   + 32;
         s->q_chroma_intra_matrix16 = s->q_intra_matrix16 + 32;
+        // No need to set q_inter_matrix
+        av_assert1(s->intra_only);
+        // intra_matrix, chroma_intra_matrix will be set later for MJPEG.
+        return 0;
     } else {
         s->q_chroma_intra_matrix   = s->q_intra_matrix;
         s->q_chroma_intra_matrix16 = s->q_intra_matrix16;
-- 
2.45.2


[-- Attachment #28: 0027-avcodec-mpegvideo_enc-Move-q_matrix-init-to-init_mat.patch --]
[-- Type: text/x-patch, Size: 2561 bytes --]

From ccae1f72b78e9f70f5794fb7caa61299f28eca9d Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 27 Feb 2025 22:56:59 +0100
Subject: [PATCH 27/40] avcodec/mpegvideo_enc: Move q_matrix init to
 init_matrices()

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 30 ++++++++++++++----------------
 1 file changed, 14 insertions(+), 16 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 81e004d1a8..5eea676dd4 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -353,6 +353,7 @@ static av_cold int init_matrices(MpegEncContext *s, AVCodecContext *avctx)
 {
     const int nb_matrices = 1 + (s->out_format == FMT_MJPEG) + !s->intra_only;
     const uint16_t *intra_matrix, *inter_matrix;
+    int ret;
 
     if (!ALLOCZ_ARRAYS(s->q_intra_matrix,   32, nb_matrices) ||
         !ALLOCZ_ARRAYS(s->q_intra_matrix16, 32, nb_matrices))
@@ -399,6 +400,19 @@ static av_cold int init_matrices(MpegEncContext *s, AVCodecContext *avctx)
         s->inter_matrix[j] = inter_matrix[i];
     }
 
+    /* precompute matrix */
+    ret = ff_check_codec_matrices(avctx, FF_MATRIX_TYPE_INTRA | FF_MATRIX_TYPE_INTER, 1, 255);
+    if (ret < 0)
+        return ret;
+
+    ff_convert_matrix(s, s->q_intra_matrix, s->q_intra_matrix16,
+                      s->intra_matrix, s->intra_quant_bias, avctx->qmin,
+                      31, 1);
+    if (s->q_inter_matrix)
+        ff_convert_matrix(s, s->q_inter_matrix, s->q_inter_matrix16,
+                          s->inter_matrix, s->inter_quant_bias, avctx->qmin,
+                          31, 0);
+
     return 0;
 }
 
@@ -1017,22 +1031,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 #endif
     }
 
-    /* precompute matrix */
-    /* for mjpeg, we do include qscale in the matrix */
-    if (s->out_format != FMT_MJPEG) {
-        ret = ff_check_codec_matrices(avctx, FF_MATRIX_TYPE_INTRA | FF_MATRIX_TYPE_INTER, 1, 255);
-        if (ret < 0)
-            return ret;
-
-        ff_convert_matrix(s, s->q_intra_matrix, s->q_intra_matrix16,
-                          s->intra_matrix, s->intra_quant_bias, avctx->qmin,
-                          31, 1);
-        if (s->q_inter_matrix)
-        ff_convert_matrix(s, s->q_inter_matrix, s->q_inter_matrix16,
-                          s->inter_matrix, s->inter_quant_bias, avctx->qmin,
-                          31, 0);
-    }
-
     if ((ret = ff_rate_control_init(s)) < 0)
         return ret;
 
-- 
2.45.2


[-- Attachment #29: 0028-avcodec-mpegvideo_enc-Move-q_scale_type-check-to-mpe.patch --]
[-- Type: text/x-patch, Size: 1914 bytes --]

From 42d9b10beb87570269ca1470682e6b688cba3208 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 28 Feb 2025 00:05:28 +0100
Subject: [PATCH 28/40] avcodec/mpegvideo_enc: Move q_scale_type check to
 mpeg12enc.c

The MPEG-2 encoder is the only encoder supporting q_scale_type.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12enc.c     | 8 ++++++++
 libavcodec/mpegvideo_enc.c | 8 --------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 52264ac6a0..90baf1ed95 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -201,6 +201,14 @@ static av_cold int encode_init(AVCodecContext *avctx)
         }
     }
 
+    if (mpeg12->mpeg.q_scale_type == 1) {
+        if (avctx->qmax > 28) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "non linear quant only supports qmax <= 28 currently\n");
+            return AVERROR_PATCHWELCOME;
+        }
+    }
+
     if (avctx->profile == AV_PROFILE_UNKNOWN) {
         if (avctx->level != AV_LEVEL_UNKNOWN) {
             av_log(avctx, AV_LOG_ERROR, "Set profile and level\n");
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 5eea676dd4..da9247ec25 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -705,14 +705,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         }
     }
 
-    if (s->q_scale_type == 1) {
-        if (avctx->qmax > 28) {
-            av_log(avctx, AV_LOG_ERROR,
-                   "non linear quant only supports qmax <= 28 currently\n");
-            return AVERROR_PATCHWELCOME;
-        }
-    }
-
     if (avctx->slices > 1 &&
         !(avctx->codec->capabilities & AV_CODEC_CAP_SLICE_THREADS)) {
         av_log(avctx, AV_LOG_ERROR, "Multiple slices are not supported by this codec\n");
-- 
2.45.2


[-- Attachment #30: 0029-avcodec-mpegvideo_enc-Move-vbv_delay-warning-to-mpeg.patch --]
[-- Type: text/x-patch, Size: 2283 bytes --]

From db4b09aad1b7094290d3c043549f7cb9144f0d18 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 28 Feb 2025 00:46:23 +0100
Subject: [PATCH 29/40] avcodec/mpegvideo_enc: Move vbv_delay warning to
 mpeg12enc.c

It is MPEG-1/2 only.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12enc.c     |  9 +++++++++
 libavcodec/mpegvideo_enc.c | 11 -----------
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 90baf1ed95..3f23045afc 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -255,6 +255,15 @@ static av_cold int encode_init(AVCodecContext *avctx)
         }
     }
 
+    if (avctx->rc_max_rate &&
+        avctx->rc_min_rate == avctx->rc_max_rate &&
+        90000LL * (avctx->rc_buffer_size - 1) >
+            avctx->rc_max_rate * 0xFFFFLL) {
+        av_log(avctx, AV_LOG_INFO,
+               "Warning vbv_delay will be set to 0xFFFF (=VBR) as the "
+               "specified vbv buffer is too large for the given bitrate!\n");
+    }
+
     if (mpeg12->drop_frame_timecode)
         mpeg12->tc.flags |= AV_TIMECODE_FLAG_DROPFRAME;
     if (mpeg12->drop_frame_timecode && mpeg12->frame_rate_index != 4) {
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index da9247ec25..cbfea534d9 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -588,17 +588,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
             avctx->bit_rate_tolerance = INT_MAX;
     }
 
-    if (avctx->rc_max_rate &&
-        avctx->rc_min_rate == avctx->rc_max_rate &&
-        (s->codec_id == AV_CODEC_ID_MPEG1VIDEO ||
-         s->codec_id == AV_CODEC_ID_MPEG2VIDEO) &&
-        90000LL * (avctx->rc_buffer_size - 1) >
-            avctx->rc_max_rate * 0xFFFFLL) {
-        av_log(avctx, AV_LOG_INFO,
-               "Warning vbv_delay will be set to 0xFFFF (=VBR) as the "
-               "specified vbv buffer is too large for the given bitrate!\n");
-    }
-
     if ((avctx->flags & AV_CODEC_FLAG_4MV) && s->codec_id != AV_CODEC_ID_MPEG4 &&
         s->codec_id != AV_CODEC_ID_H263 && s->codec_id != AV_CODEC_ID_H263P &&
         s->codec_id != AV_CODEC_ID_FLV1) {
-- 
2.45.2


[-- Attachment #31: 0030-avcodec-mpegvideo_enc-Move-H.263-specific-check-to-i.patch --]
[-- Type: text/x-patch, Size: 1472 bytes --]

From 59f3a14df332e67c077f388c25b9a67c699bf71a Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 1 Mar 2025 21:05:59 +0100
Subject: [PATCH 30/40] avcodec/mpegvideo_enc: Move H.263 specific check to
 ituh263enc.c

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/ituh263enc.c    | 3 +++
 libavcodec/mpegvideo_enc.c | 3 ---
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 2d750439d1..5beb857a6e 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -834,6 +834,9 @@ av_cold void ff_h263_encode_init(MpegEncContext *s)
     }
     s->ac_esc_length= 7+1+6+8;
 
+    if (s->modified_quant)
+        s->chroma_qscale_table = ff_h263_chroma_qscale_table;
+
     // use fcodes >1 only for MPEG-4 & H.263 & H.263+ FIXME
     switch(s->codec_id){
     case AV_CODEC_ID_MPEG4:
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index cbfea534d9..656d312d28 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -994,9 +994,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         s->dct_unquantize_inter = s->dct_unquantize_mpeg1_inter;
     }
 
-    if ((CONFIG_H263P_ENCODER || CONFIG_RV20_ENCODER) && s->modified_quant)
-        s->chroma_qscale_table = ff_h263_chroma_qscale_table;
-
     if (s->slice_context_count > 1) {
         s->rtp_mode = 1;
 
-- 
2.45.2


[-- Attachment #32: 0031-avcodec-mpegvideo-Move-ratecontrol-only-options-to-R.patch --]
[-- Type: text/x-patch, Size: 11179 bytes --]

From f303ecc412994c73ee4ef059cbedfba796b8006b Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 28 Feb 2025 23:47:52 +0100
Subject: [PATCH 31/40] avcodec/mpegvideo: Move ratecontrol-only options to
 RateControlContext

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.h    | 11 -----------
 libavcodec/mpegvideoenc.h | 13 +++++++------
 libavcodec/ratecontrol.c  | 25 +++++++++++++------------
 libavcodec/ratecontrol.h  | 11 +++++++++++
 libavcodec/snowenc.c      |  2 +-
 5 files changed, 32 insertions(+), 30 deletions(-)

diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index ac38d112f9..5fef008cc5 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -507,21 +507,10 @@ typedef struct MpegEncContext {
     me_cmp_func sse_cmp[2];
     int (*sum_abs_dctelem)(const int16_t *block);
 
-    /**
-     * ratecontrol qmin qmax limiting method
-     * 0-> clipping, 1-> use a nice continuous function to limit qscale within qmin/qmax.
-     */
-    float rc_qsquish;
-    float rc_qmod_amp;
-    int   rc_qmod_freq;
-    float rc_initial_cplx;
-    float rc_buffer_aggressivity;
     float border_masking;
     int lmin, lmax;
     int vbv_ignore_qmax;
 
-    char *rc_eq;
-
     /* temp buffers for rate control */
     float *cplx_tab, *bits_tab;
 
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 2d7f76c57a..f4e02593e8 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -81,6 +81,7 @@
 { "msad",   "Sum of absolute differences, median predicted", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_MEDIAN_SAD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, .unit = "cmp_func" }
 
 #define FF_MPV_OFFSET(x) offsetof(MpegEncContext, x)
+#define FF_RC_OFFSET(x) (offsetof(MpegEncContext, rc_context) + offsetof(RateControlContext, x))
 #define FF_MPV_OPT_FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
 #define FF_MPV_COMMON_OPTS \
 FF_MPV_OPT_CMP_FUNC, \
@@ -99,16 +100,16 @@ FF_MPV_OPT_CMP_FUNC, \
 { "error_rate", "Simulate errors in the bitstream to test error concealment.",                                                                                                  \
                                                                     FF_MPV_OFFSET(error_rate),              AV_OPT_TYPE_INT, { .i64 = 0 },       0, INT_MAX, FF_MPV_OPT_FLAGS },\
 {"qsquish", "how to keep quantizer between qmin and qmax (0 = clip, 1 = use differentiable function)",                                                                          \
-                                                                    FF_MPV_OFFSET(rc_qsquish), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, 0, 99, FF_MPV_OPT_FLAGS},                        \
-{"rc_qmod_amp", "experimental quantizer modulation",                FF_MPV_OFFSET(rc_qmod_amp), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS},           \
-{"rc_qmod_freq", "experimental quantizer modulation",               FF_MPV_OFFSET(rc_qmod_freq), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS},             \
+                                                                    FF_RC_OFFSET(qsquish), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, 0, 99, FF_MPV_OPT_FLAGS},                        \
+{"rc_qmod_amp", "experimental quantizer modulation",                FF_RC_OFFSET(qmod_amp), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS},           \
+{"rc_qmod_freq", "experimental quantizer modulation",               FF_RC_OFFSET(qmod_freq), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS},             \
 {"rc_eq", "Set rate control equation. When computing the expression, besides the standard functions "                                                                           \
           "defined in the section 'Expression Evaluation', the following functions are available: "                                                                             \
           "bits2qp(bits), qp2bits(qp). Also the following constants are available: iTex pTex tex mv "                                                                           \
           "fCode iCount mcVar var isI isP isB avgQP qComp avgIITex avgPITex avgPPTex avgBPTex avgTex.",                                                                         \
-                                                                    FF_MPV_OFFSET(rc_eq), AV_OPT_TYPE_STRING,                           .flags = FF_MPV_OPT_FLAGS },            \
-{"rc_init_cplx", "initial complexity for 1-pass encoding",          FF_MPV_OFFSET(rc_initial_cplx), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS},       \
-{"rc_buf_aggressivity", "currently useless",                        FF_MPV_OFFSET(rc_buffer_aggressivity), AV_OPT_TYPE_FLOAT, {.dbl = 1.0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \
+                                                                    FF_RC_OFFSET(rc_eq), AV_OPT_TYPE_STRING,                           .flags = FF_MPV_OPT_FLAGS },            \
+{"rc_init_cplx", "initial complexity for 1-pass encoding",          FF_RC_OFFSET(initial_cplx), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS},       \
+{"rc_buf_aggressivity", "currently useless",                        FF_RC_OFFSET(buffer_aggressivity), AV_OPT_TYPE_FLOAT, {.dbl = 1.0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \
 {"border_mask", "increase the quantizer for macroblocks close to borders", FF_MPV_OFFSET(border_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS},    \
 {"lmin", "minimum Lagrange factor (VBR)",                           FF_MPV_OFFSET(lmin), AV_OPT_TYPE_INT, {.i64 =  2*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS },            \
 {"lmax", "maximum Lagrange factor (VBR)",                           FF_MPV_OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 31*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS },            \
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index 86ec7a3443..f383c433c4 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -182,10 +182,10 @@ static double modify_qscale(MpegEncContext *s, const RateControlEntry *rce,
     get_qminmax(&qmin, &qmax, s, pict_type);
 
     /* modulation */
-    if (s->rc_qmod_freq &&
-        frame_num % s->rc_qmod_freq == 0 &&
+    if (rcc->qmod_freq &&
+        frame_num % rcc->qmod_freq == 0 &&
         pict_type == AV_PICTURE_TYPE_P)
-        q *= s->rc_qmod_amp;
+        q *= rcc->qmod_amp;
 
     /* buffer overflow/underflow protection */
     if (buffer_size) {
@@ -198,7 +198,7 @@ static double modify_qscale(MpegEncContext *s, const RateControlEntry *rce,
                 d = 1.0;
             else if (d < 0.0001)
                 d = 0.0001;
-            q *= pow(d, 1.0 / s->rc_buffer_aggressivity);
+            q *= pow(d, 1.0 / rcc->buffer_aggressivity);
 
             q_limit = bits2qp(rce,
                               FFMAX((min_rate - buffer_size + rcc->buffer_index) *
@@ -218,7 +218,7 @@ static double modify_qscale(MpegEncContext *s, const RateControlEntry *rce,
                 d = 1.0;
             else if (d < 0.0001)
                 d = 0.0001;
-            q /= pow(d, 1.0 / s->rc_buffer_aggressivity);
+            q /= pow(d, 1.0 / rcc->buffer_aggressivity);
 
             q_limit = bits2qp(rce,
                               FFMAX(rcc->buffer_index *
@@ -234,8 +234,8 @@ static double modify_qscale(MpegEncContext *s, const RateControlEntry *rce,
     }
     ff_dlog(s, "q:%f max:%f min:%f size:%f index:%f agr:%f\n",
             q, max_rate, min_rate, buffer_size, rcc->buffer_index,
-            s->rc_buffer_aggressivity);
-    if (s->rc_qsquish == 0.0 || qmin == qmax) {
+            rcc->buffer_aggressivity);
+    if (rcc->qsquish == 0.0 || qmin == qmax) {
         if (q < qmin)
             q = qmin;
         else if (q > qmax)
@@ -295,7 +295,7 @@ static double get_qscale(MpegEncContext *s, RateControlEntry *rce,
 
     bits = av_expr_eval(rcc->rc_eq_eval, const_values, rce);
     if (isnan(bits)) {
-        av_log(s->avctx, AV_LOG_ERROR, "Error evaluating rc_eq \"%s\"\n", s->rc_eq);
+        av_log(s->avctx, AV_LOG_ERROR, "Error evaluating rc_eq \"%s\"\n", rcc->rc_eq);
         return -1;
     }
 
@@ -541,11 +541,11 @@ av_cold int ff_rate_control_init(MpegEncContext *s)
     }
 
     res = av_expr_parse(&rcc->rc_eq_eval,
-                        s->rc_eq ? s->rc_eq : "tex^qComp",
+                        rcc->rc_eq ? rcc->rc_eq : "tex^qComp",
                         const_names, func1_names, func1,
                         NULL, NULL, 0, s->avctx);
     if (res < 0) {
-        av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", s->rc_eq);
+        av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", rcc->rc_eq);
         return res;
     }
 
@@ -649,9 +649,9 @@ av_cold int ff_rate_control_init(MpegEncContext *s)
             return -1;
         }
         /* init stuff with the user specified complexity */
-        if (s->rc_initial_cplx) {
+        if (rcc->initial_cplx) {
             for (i = 0; i < 60 * 30; i++) {
-                double bits = s->rc_initial_cplx * (i / 10000.0 + 1.0) * s->mb_num;
+                double bits = rcc->initial_cplx * (i / 10000.0 + 1.0) * s->mb_num;
                 RateControlEntry rce;
 
                 if (i % ((s->gop_size + 3) / 4) == 0)
@@ -701,6 +701,7 @@ av_cold void ff_rate_control_uninit(RateControlContext *rcc)
 {
     emms_c();
 
+    // rc_eq is always managed via an AVOption and therefore not freed here.
     av_expr_free(rcc->rc_eq_eval);
     rcc->rc_eq_eval = NULL;
     av_freep(&rcc->entry);
diff --git a/libavcodec/ratecontrol.h b/libavcodec/ratecontrol.h
index 4d71a181b5..edeccbc6cd 100644
--- a/libavcodec/ratecontrol.h
+++ b/libavcodec/ratecontrol.h
@@ -77,6 +77,17 @@ typedef struct RateControlContext{
     int frame_count[5];
     int last_non_b_pict_type;
 
+    /**
+     * ratecontrol qmin qmax limiting method
+     * 0-> clipping, 1-> use a nice continuous function to limit qscale within qmin/qmax.
+     */
+    float qsquish;
+    float qmod_amp;
+    int   qmod_freq;
+    float initial_cplx;
+    float buffer_aggressivity;
+
+    char *rc_eq;
     struct AVExpr *rc_eq_eval;
 }RateControlContext;
 
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index 5f539a57df..fe8ffdcdcd 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -2118,7 +2118,7 @@ static const AVOption options[] = {
      "defined in the section 'Expression Evaluation', the following functions are available: "
      "bits2qp(bits), qp2bits(qp). Also the following constants are available: iTex pTex tex mv "
      "fCode iCount mcVar var isI isP isB avgQP qComp avgIITex avgPITex avgPPTex avgBPTex avgTex.",
-                                                                                  OFFSET(m.rc_eq), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VE },
+                                                                                  OFFSET(m.rc_context.rc_eq), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VE },
     { NULL },
 };
 
-- 
2.45.2


[-- Attachment #33: 0032-avcodec-mpegvideo-Move-temp-ratecontrol-bufs-to-Rate.patch --]
[-- Type: text/x-patch, Size: 4675 bytes --]

From 8f25859b09385db6f924db8caf5ab4eddd70160a Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 1 Mar 2025 00:04:43 +0100
Subject: [PATCH 32/40] avcodec/mpegvideo: Move temp ratecontrol bufs to
 RateControlContext

Also only allocate them when they are needed (namely iff
adaptive quant is true) and allocate them jointly.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.h     |  3 ---
 libavcodec/mpegvideo_enc.c |  5 -----
 libavcodec/ratecontrol.c   | 19 +++++++++++++++----
 libavcodec/ratecontrol.h   |  2 ++
 4 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 5fef008cc5..43d4bbfbcb 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -511,9 +511,6 @@ typedef struct MpegEncContext {
     int lmin, lmax;
     int vbv_ignore_qmax;
 
-    /* temp buffers for rate control */
-    float *cplx_tab, *bits_tab;
-
     /* flag to indicate a reinitialization is required, e.g. after
      * a frame size change */
     int context_reinit;
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 656d312d28..4e4b4c1ba9 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -945,8 +945,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     mb_array_size = s->mb_stride * s->mb_height;
     if (!FF_ALLOCZ_TYPED_ARRAY(s->mb_type,      mb_array_size) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->lambda_table, mb_array_size) ||
-        !FF_ALLOC_TYPED_ARRAY (s->cplx_tab,     mb_array_size) ||
-        !FF_ALLOC_TYPED_ARRAY (s->bits_tab,     mb_array_size) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->mc_mb_var,    mb_array_size) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->mb_var, mb_array_size) ||
         !(s->mb_mean = av_mallocz(mb_array_size)))
@@ -1075,9 +1073,6 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
     av_freep(&s->mb_type);
     av_freep(&s->lambda_table);
 
-    av_freep(&s->cplx_tab);
-    av_freep(&s->bits_tab);
-
     av_freep(&s->q_intra_matrix);
     av_freep(&s->q_intra_matrix16);
     av_freep(&s->input_picture);
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index f383c433c4..86fdacd7b1 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -694,6 +694,15 @@ av_cold int ff_rate_control_init(MpegEncContext *s)
         }
     }
 
+    if (s->adaptive_quant) {
+        unsigned mb_array_size = s->mb_stride * s->mb_height;
+
+        rcc->cplx_tab = av_malloc_array(2 * sizeof(rcc->cplx_tab), mb_array_size);
+        if (!rcc->cplx_tab)
+            return AVERROR(ENOMEM);
+        rcc->bits_tab = rcc->cplx_tab + mb_array_size;
+    }
+
     return 0;
 }
 
@@ -705,6 +714,7 @@ av_cold void ff_rate_control_uninit(RateControlContext *rcc)
     av_expr_free(rcc->rc_eq_eval);
     rcc->rc_eq_eval = NULL;
     av_freep(&rcc->entry);
+    av_freep(&rcc->cplx_tab);
 }
 
 int ff_vbv_update(MpegEncContext *s, int frame_size)
@@ -766,7 +776,8 @@ static void update_predictor(Predictor *p, double q, double var, double size)
     p->coeff += new_coeff;
 }
 
-static void adaptive_quantization(MpegEncContext *s, double q)
+static void adaptive_quantization(RateControlContext *const rcc,
+                                  MpegEncContext *const s, double q)
 {
     int i;
     const float lumi_masking         = s->avctx->lumi_masking / (128.0 * 128.0);
@@ -777,8 +788,8 @@ static void adaptive_quantization(MpegEncContext *s, double q)
     const float border_masking       = s->border_masking;
     float bits_sum                   = 0.0;
     float cplx_sum                   = 0.0;
-    float *cplx_tab                  = s->cplx_tab;
-    float *bits_tab                  = s->bits_tab;
+    float *cplx_tab                  = rcc->cplx_tab;
+    float *bits_tab                  = rcc->bits_tab;
     const int qmin                   = s->avctx->mb_lmin;
     const int qmax                   = s->avctx->mb_lmax;
     const int mb_width               = s->mb_width;
@@ -1048,7 +1059,7 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
         q = qmax;
 
     if (s->adaptive_quant)
-        adaptive_quantization(s, q);
+        adaptive_quantization(rcc, s, q);
     else
         q = (int)(q + 0.5);
 
diff --git a/libavcodec/ratecontrol.h b/libavcodec/ratecontrol.h
index edeccbc6cd..b889491335 100644
--- a/libavcodec/ratecontrol.h
+++ b/libavcodec/ratecontrol.h
@@ -89,6 +89,8 @@ typedef struct RateControlContext{
 
     char *rc_eq;
     struct AVExpr *rc_eq_eval;
+
+    float *cplx_tab, *bits_tab;
 }RateControlContext;
 
 struct MpegEncContext;
-- 
2.45.2


[-- Attachment #34: 0033-avcodec-mpegvideo-Mark-ff_mpv_common_defaults-as-av_.patch --]
[-- Type: text/x-patch, Size: 956 bytes --]

From 9d0720bf19d026e7bef28c2aa3a38c4efa74ac0f Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 17:39:16 +0100
Subject: [PATCH 33/40] avcodec/mpegvideo: Mark ff_mpv_common_defaults() as
 av_cold

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 73c513acbd..f114dd8c0c 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -480,7 +480,7 @@ int ff_update_duplicate_context(MpegEncContext *dst, const MpegEncContext *src)
  * The changed fields will not depend upon the
  * prior state of the MpegEncContext.
  */
-void ff_mpv_common_defaults(MpegEncContext *s)
+av_cold void ff_mpv_common_defaults(MpegEncContext *s)
 {
     s->y_dc_scale_table      =
     s->c_dc_scale_table      = ff_mpeg1_dc_scale_table;
-- 
2.45.2


[-- Attachment #35: 0034-avcodec-speedhqenc-Don-t-log-to-the-private-context.patch --]
[-- Type: text/x-patch, Size: 1283 bytes --]

From 07292745b54ee9374a498825b956d50fbe3798e4 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 2 Mar 2025 00:12:05 +0100
Subject: [PATCH 34/40] avcodec/speedhqenc: Don't log to the private context

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/speedhqenc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/speedhqenc.c b/libavcodec/speedhqenc.c
index ac40fd6e75..dda5444434 100644
--- a/libavcodec/speedhqenc.c
+++ b/libavcodec/speedhqenc.c
@@ -100,13 +100,13 @@ av_cold int ff_speedhq_encode_init(MpegEncContext *s)
     static AVOnce init_static_once = AV_ONCE_INIT;
 
     if (s->width > 65500 || s->height > 65500) {
-        av_log(s, AV_LOG_ERROR, "SpeedHQ does not support resolutions above 65500x65500\n");
+        av_log(s->avctx, AV_LOG_ERROR, "SpeedHQ does not support resolutions above 65500x65500\n");
         return AVERROR(EINVAL);
     }
 
     // border is not implemented correctly at the moment, see ticket #10078
     if (s->width % 16) {
-        av_log(s, AV_LOG_ERROR, "width must be a multiple of 16\n");
+        av_log(s->avctx, AV_LOG_ERROR, "width must be a multiple of 16\n");
         return AVERROR_PATCHWELCOME;
     }
 
-- 
2.45.2


[-- Attachment #36: 0035-avcodec-speedhqenc-Inline-ff_speedhq_mb_y_order_to_m.patch --]
[-- Type: text/x-patch, Size: 2420 bytes --]

From e55ca840fe912f892174ec7449a98820bd85e1c4 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 16:27:44 +0100
Subject: [PATCH 35/40] avcodec/speedhqenc: Inline
 ff_speedhq_mb_y_order_to_mb()

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/speedhqenc.c | 16 ----------------
 libavcodec/speedhqenc.h | 16 +++++++++++++++-
 2 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/libavcodec/speedhqenc.c b/libavcodec/speedhqenc.c
index dda5444434..87497f5f85 100644
--- a/libavcodec/speedhqenc.c
+++ b/libavcodec/speedhqenc.c
@@ -272,22 +272,6 @@ void ff_speedhq_encode_mb(MpegEncContext *s, int16_t block[12][64])
     s->i_tex_bits += get_bits_diff(s);
 }
 
-static int ff_speedhq_mb_rows_in_slice(int slice_num, int mb_height)
-{
-    return mb_height / 4 + (slice_num < (mb_height % 4));
-}
-
-int ff_speedhq_mb_y_order_to_mb(int mb_y_order, int mb_height, int *first_in_slice)
-{
-    int slice_num = 0;
-    while (mb_y_order >= ff_speedhq_mb_rows_in_slice(slice_num, mb_height)) {
-         mb_y_order -= ff_speedhq_mb_rows_in_slice(slice_num, mb_height);
-         slice_num++;
-    }
-    *first_in_slice = (mb_y_order == 0);
-    return mb_y_order * 4 + slice_num;
-}
-
 const FFCodec ff_speedhq_encoder = {
     .p.name         = "speedhq",
     CODEC_LONG_NAME("NewTek SpeedHQ"),
diff --git a/libavcodec/speedhqenc.h b/libavcodec/speedhqenc.h
index 0c52e6a380..15be9764d7 100644
--- a/libavcodec/speedhqenc.h
+++ b/libavcodec/speedhqenc.h
@@ -40,6 +40,20 @@ void ff_speedhq_encode_mb(MpegEncContext *s, int16_t block[12][64]);
 void ff_speedhq_encode_picture_header(MpegEncContext *s);
 void ff_speedhq_end_slice(MpegEncContext *s);
 
-int ff_speedhq_mb_y_order_to_mb(int mb_y_order, int mb_height, int *first_in_slice);
+static inline int ff_speedhq_mb_rows_in_slice(int slice_num, int mb_height)
+{
+    return mb_height / 4 + (slice_num < (mb_height % 4));
+}
+
+static inline int ff_speedhq_mb_y_order_to_mb(int mb_y_order, int mb_height, int *first_in_slice)
+{
+    int slice_num = 0;
+    while (mb_y_order >= ff_speedhq_mb_rows_in_slice(slice_num, mb_height)) {
+         mb_y_order -= ff_speedhq_mb_rows_in_slice(slice_num, mb_height);
+         slice_num++;
+    }
+    *first_in_slice = (mb_y_order == 0);
+    return mb_y_order * 4 + slice_num;
+}
 
 #endif /* AVCODEC_SPEEDHQENC_H */
-- 
2.45.2


[-- Attachment #37: 0036-avcodec-mjpegenc-Remove-nonsensical-AMV-options.patch --]
[-- Type: text/x-patch, Size: 2234 bytes --]

From 8d5dbb1b8d75ae008c5075f6e26d4c6d57640c97 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 01:36:39 +0100
Subject: [PATCH 36/40] avcodec/mjpegenc: Remove nonsensical AMV options

Both these options are unsupported and silently ignored for AMV;
so it is better to not offer them at all.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mjpegenc.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index c2e8b93a34..22d2b4816f 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -301,7 +301,7 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s)
                  (s->avctx->active_thread_type & FF_THREAD_SLICE) &&
                  s->avctx->thread_count > 1;
 
-    if (s->codec_id == AV_CODEC_ID_AMV || use_slices)
+    if (use_slices)
         m->huffman = HUFFMAN_TABLE_DEFAULT;
 
     if (s->mpv_flags & FF_MPV_FLAG_QP_RD) {
@@ -624,11 +624,12 @@ static int amv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
 #define OFFSET(x) offsetof(MJPEGEncContext, mjpeg.x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-FF_MPV_COMMON_OPTS
+#define AMV_OPTIONS_OFFSET 4
 { "huffman", "Huffman table strategy", OFFSET(huffman), AV_OPT_TYPE_INT, { .i64 = HUFFMAN_TABLE_OPTIMAL }, 0, NB_HUFFMAN_TABLE_OPTION - 1, VE, .unit = "huffman" },
     { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = HUFFMAN_TABLE_DEFAULT }, INT_MIN, INT_MAX, VE, .unit = "huffman" },
     { "optimal", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = HUFFMAN_TABLE_OPTIMAL }, INT_MIN, INT_MAX, VE, .unit = "huffman" },
 { "force_duplicated_matrix", "Always write luma and chroma matrix for mjpeg, useful for rtp streaming.", OFFSET(force_duplicated_matrix), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, VE },
+FF_MPV_COMMON_OPTS
 { NULL},
 };
 
@@ -688,7 +689,7 @@ FFCodec ff_mjpeg_encoder = {
 static const AVClass amv_class = {
     .class_name = "amv encoder",
     .item_name  = av_default_item_name,
-    .option     = options,
+    .option     = options + AMV_OPTIONS_OFFSET,
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-- 
2.45.2


[-- Attachment #38: 0037-avcodec-mjpegenc-Don-t-log-to-private-context.patch --]
[-- Type: text/x-patch, Size: 925 bytes --]

From 192919d6113288e5cbed2534fbcae55e4882fad9 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 01:42:24 +0100
Subject: [PATCH 37/40] avcodec/mjpegenc: Don't log to private context

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mjpegenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 22d2b4816f..cd8eb8f6c1 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -318,7 +318,7 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s)
         return ret;
 
     if (s->width > 65500 || s->height > 65500) {
-        av_log(s, AV_LOG_ERROR, "JPEG does not support resolutions above 65500x65500\n");
+        av_log(s->avctx, AV_LOG_ERROR, "JPEG does not support resolutions above 65500x65500\n");
         return AVERROR(EINVAL);
     }
 
-- 
2.45.2


[-- Attachment #39: 0038-avcodec-mpeg12enc-Simplify-writing-bits.patch --]
[-- Type: text/x-patch, Size: 2333 bytes --]

From af2f3abfa6e5932ed50d148a24549c23fdd39a1c Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 18:42:13 +0100
Subject: [PATCH 38/40] avcodec/mpeg12enc: Simplify writing bits

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12enc.c | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 3f23045afc..ca51430fce 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -594,10 +594,8 @@ void ff_mpeg1_encode_picture_header(MpegEncContext *s)
 
         if (fpa_type != 0) {
             put_header(s, USER_START_CODE);
-            put_bits(&s->pb, 8, 'J');   // S3D_video_format_signaling_identifier
-            put_bits(&s->pb, 8, 'P');
-            put_bits(&s->pb, 8, '3');
-            put_bits(&s->pb, 8, 'D');
+            // S3D_video_format_signaling_identifier
+            put_bits32(&s->pb, MKBETAG('J','P','3','D'));
             put_bits(&s->pb, 8, 0x03);  // S3D_video_format_length
 
             put_bits(&s->pb, 1, 1);     // reserved_bit
@@ -612,21 +610,15 @@ void ff_mpeg1_encode_picture_header(MpegEncContext *s)
             AV_FRAME_DATA_A53_CC);
         if (side_data) {
             if (side_data->size <= A53_MAX_CC_COUNT * 3 && side_data->size % 3 == 0) {
-                int i = 0;
-
                 put_header (s, USER_START_CODE);
 
-                put_bits(&s->pb, 8, 'G');                   // user_identifier
-                put_bits(&s->pb, 8, 'A');
-                put_bits(&s->pb, 8, '9');
-                put_bits(&s->pb, 8, '4');
+                put_bits32(&s->pb, MKBETAG('G','A','9','4')); // user_identifier
                 put_bits(&s->pb, 8, 3);                     // user_data_type_code
                 put_bits(&s->pb, 8,
                     (side_data->size / 3 & A53_MAX_CC_COUNT) | 0x40); // flags, cc_count
                 put_bits(&s->pb, 8, 0xff);                  // em_data
 
-                for (i = 0; i < side_data->size; i++)
-                    put_bits(&s->pb, 8, side_data->data[i]);
+                ff_copy_bits(&s->pb, side_data->data, side_data->size);
 
                 put_bits(&s->pb, 8, 0xff);                  // marker_bits
             } else {
-- 
2.45.2


[-- Attachment #40: 0039-avcodec-mpegvideo-Move-vbv_delay-to-Mpeg1Context.patch --]
[-- Type: text/x-patch, Size: 2400 bytes --]

From e555a17f96dbbee4f6f032127e5d18c3fed42b85 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 29 Jan 2022 06:50:51 +0100
Subject: [PATCH 39/40] avcodec/mpegvideo: Move vbv_delay to Mpeg1Context

Only used there and only by the main thread.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12dec.c | 5 +++--
 libavcodec/mpegvideo.h | 1 -
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index ba40c1f06f..b019c092a2 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -90,6 +90,7 @@ typedef struct Mpeg1Context {
     int tmpgexs;
     int first_slice;
     int extradata_decoded;
+    int vbv_delay;
     int64_t timecode_frame_start;  /*< GOP timecode frame start number, in non drop frame format */
 } Mpeg1Context;
 
@@ -953,7 +954,7 @@ static int mpeg_decode_postinit(AVCodecContext *avctx)
             (s->bit_rate != 0x3FFFF*400)) {
             avctx->rc_max_rate = s->bit_rate;
         } else if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO && s->bit_rate &&
-                   (s->bit_rate != 0x3FFFF*400 || s->vbv_delay != 0xFFFF)) {
+                   (s->bit_rate != 0x3FFFF*400 || s1->vbv_delay != 0xFFFF)) {
             avctx->bit_rate = s->bit_rate;
         }
         s1->save_aspect          = s->avctx->sample_aspect_ratio;
@@ -1024,7 +1025,7 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, const uint8_t *buf,
         return AVERROR_INVALIDDATA;
 
     vbv_delay = get_bits(&s->gb, 16);
-    s->vbv_delay = vbv_delay;
+    s1->vbv_delay = vbv_delay;
     if (s->pict_type == AV_PICTURE_TYPE_P ||
         s->pict_type == AV_PICTURE_TYPE_B) {
         s->full_pel[0] = get_bits1(&s->gb);
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 43d4bbfbcb..10be87450a 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -204,7 +204,6 @@ typedef struct MpegEncContext {
     int adaptive_quant;         ///< use adaptive quantization
     int dquant;                 ///< qscale difference to prev qscale
     int pict_type;              ///< AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, ...
-    int vbv_delay;
     int last_pict_type; //FIXME removes
     int last_non_b_pict_type;   ///< used for MPEG-4 gmc B-frames & ratecontrol
     int droppable;
-- 
2.45.2


[-- Attachment #41: 0040-avcodec-mpegvideo_enc-motion_est-Pre-center-fcode_ta.patch --]
[-- Type: text/x-patch, Size: 3302 bytes --]

From 63ac6c415235198a6ee77475f01eae2a60bc456a Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 17 Feb 2022 16:54:20 +0100
Subject: [PATCH 40/40] avcodec/mpegvideo_enc, motion_est: Pre-center fcode_tab

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/ituh263enc.c    | 2 +-
 libavcodec/motion_est.c    | 3 +--
 libavcodec/mpeg12enc.c     | 2 +-
 libavcodec/mpeg4videoenc.c | 2 +-
 libavcodec/mpegvideo_enc.c | 2 +-
 5 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 5beb857a6e..188996a4d1 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -843,7 +843,7 @@ av_cold void ff_h263_encode_init(MpegEncContext *s)
         break;
     case AV_CODEC_ID_H263P:
         if(s->umvplus)
-            s->fcode_tab= umv_fcode_tab;
+            s->fcode_tab = umv_fcode_tab + MAX_MV;
         if(s->modified_quant){
             s->min_qcoeff= -2047;
             s->max_qcoeff=  2047;
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index 46c4ca2dd9..4940da21f3 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -1619,8 +1619,7 @@ int ff_get_best_fcode(MpegEncContext * s, const int16_t (*mv_table)[2], int type
                 if(s->mb_type[xy] & type){
                     int mx= mv_table[xy][0];
                     int my= mv_table[xy][1];
-                    int fcode= FFMAX(fcode_tab[mx + MAX_MV],
-                                     fcode_tab[my + MAX_MV]);
+                    int fcode = FFMAX(fcode_tab[mx], fcode_tab[my]);
                     int j;
 
                     if (mx >= range || mx < -range ||
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index ca51430fce..0586b8cfe2 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -1157,7 +1157,7 @@ av_cold void ff_mpeg1_encode_init(MpegEncContext *s)
     s->c_dc_scale_table = ff_mpeg12_dc_scale_table[s->intra_dc_precision];
 
     s->me.mv_penalty = mv_penalty;
-    s->fcode_tab     = fcode_tab;
+    s->fcode_tab     = fcode_tab + MAX_MV;
     if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
         s->min_qcoeff = -255;
         s->max_qcoeff = 255;
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 26f9b40ff7..6ce5bc4462 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -1290,7 +1290,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
 
     ff_thread_once(&init_static_once, mpeg4_encode_init_static);
 
-    s->fcode_tab                = fcode_tab;
+    s->fcode_tab                = fcode_tab + MAX_MV;
     s->min_qcoeff               = -2048;
     s->max_qcoeff               = 2047;
     s->intra_ac_vlc_length      = uni_mpeg4_intra_rl_len;
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 4e4b4c1ba9..4aeefcaf8d 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -286,7 +286,7 @@ static void mpv_encode_defaults(MpegEncContext *s)
 
     ff_thread_once(&init_static_once, mpv_encode_init_static);
 
-    s->fcode_tab     = default_fcode_tab;
+    s->fcode_tab     = default_fcode_tab + MAX_MV;
 
     s->input_picture_number  = 0;
     s->picture_in_gop_number = 0;
-- 
2.45.2


[-- Attachment #42: Type: text/plain, Size: 251 bytes --]

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [FFmpeg-devel] Misc mpegvideo patches
  2025-03-04 13:42 [FFmpeg-devel] Misc mpegvideo patches Andreas Rheinhardt
@ 2025-03-04 16:30 ` Ramiro Polla
  2025-03-04 17:04   ` Andreas Rheinhardt
  0 siblings, 1 reply; 6+ messages in thread
From: Ramiro Polla @ 2025-03-04 16:30 UTC (permalink / raw)
  To: ffmpeg-devel


On 3/4/25 14:42, Andreas Rheinhardt wrote:
> (Mostly trivial) patches attached. A branch is at
> https://github.com/mkver/FFmpeg/tree/mpegvideo_misc


[PATCH 10/40] avcodec/mpegvideo_enc: Move default_mv_penalty to h261enc.c

> diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
> index dabab9d80a..e33bf35a8a 100644
> --- a/libavcodec/h261enc.c
> +++ b/libavcodec/h261enc.c
> @@ -46,6 +46,7 @@ static struct VLCLUT {
>      uint16_t code;
>  } vlc_lut[H261_MAX_RUN + 1][32 /* 0..2 * H261_MAX_LEN are used */];
>  
> +static uint8_t mv_penalty[MAX_FCODE + 1][MAX_DMV * 2 + 1];
>  static uint8_t uni_h261_rl_len     [64 * 128];
>  static uint8_t uni_h261_rl_len_last[64 * 128];
>  static uint8_t h261_mv_codes[64][2];
> @@ -370,6 +371,8 @@ av_cold int ff_h261_encode_init(MpegEncContext *s)
>      s->max_qcoeff       = 127;
>      s->ac_esc_length    = H261_ESC_LEN;
>  
> +    s->me.mv_penalty = mv_penalty;
> +
>      s->intra_ac_vlc_length      = s->inter_ac_vlc_length      = uni_h261_rl_len;
>      s->intra_ac_vlc_last_length = s->inter_ac_vlc_last_length = uni_h261_rl_len_last;
>      ff_thread_once(&init_static_once, h261_encode_init_static);

This global mv_penalty doesn't seem to be ever initialized; it could be 
declared const.
But it also makes me think that whatever code is using this mv_penalty, 
which is always set to zero, might be calculating things wrong.


[PATCH 15/40] avcodec/ituh263enc: Make SVQ1+Snowenc stop calling 
ff_h263_encode_init()

> diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
> index 02da090ba4..8313b2c2c1 100644
> --- a/libavcodec/ituh263enc.c
> +++ b/libavcodec/ituh263enc.c
> @@ -65,6 +65,127 @@ static uint8_t  uni_h263_inter_rl_len [64*64*2*2];
[...]
> +static av_cold void h263_encode_init_static(void)
> +{
> +    static uint8_t rl_intra_table[2][2 * MAX_RUN + MAX_LEVEL + 3];
> +
> +    ff_rl_init(&ff_rl_intra_aic, rl_intra_table);
> +    ff_h263_init_rl_inter();
> +
> +    init_uni_h263_rl_tab(&ff_rl_intra_aic,  uni_h263_intra_aic_rl_len);
> +    init_uni_h263_rl_tab(&ff_h263_rl_inter, uni_h263_inter_rl_len);
> +
> +    init_mv_penalty_and_fcode();
> +}
> +
> +av_cold const uint8_t (*ff_h263_get_mv_penalty(void))[MAX_DMV*2+1]
> +{
> +    static AVOnce init_static_once = AV_ONCE_INIT;
> +
> +    ff_thread_once(&init_static_once, h263_encode_init_static);
> +
> +    return mv_penalty;
> +}
> +

This approach kind of hides the rest of h263_encode_init_static() inside 
ff_h263_get_mv_penalty(), so the name is a bit misleading. I'd expect 
h263 to still call some init function and ff_h263_get_mv_penalty(), and 
SVQ1 and Snow to only call ff_h263_get_mv_penalty(), which would only 
take care of the mv_penalty table.


[PATCH 18/40] avcodec/ituh263dec: Reorder branches

> diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c
> index e0f3034e57..93349a3b0e 100644
> --- a/libavcodec/ituh263dec.c
> +++ b/libavcodec/ituh263dec.c
> @@ -543,6 +543,8 @@ static int h263_decode_block(MpegEncContext * s, int16_t * block,
>      if (s->h263_aic && s->mb_intra) {
>          rl = &ff_rl_intra_aic;
>          i = 0;
> +        if (!coded)
> +            goto not_coded;

Why not move the if before setting rl (doesn't seem to be used) and i 
(will be overwritten anyways)?

>          if (s->ac_pred) {
>              if (s->h263_aic_dir)
>                  scan_table = s->permutated_intra_v_scantable; /* left */
> @@ -587,8 +589,6 @@ static int h263_decode_block(MpegEncContext * s, int16_t * block,
>          i = 0;
>      }
>      if (!coded) {
> -        if (s->mb_intra && s->h263_aic)
> -            goto not_coded;
>          s->block_last_index[n] = i - 1;
>          return 0;
>      }


[PATCH 20/40] avcodec/mpeg4video: Split ff_mpeg4_pred_dc()

> diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
> index 64fb96a0cf..26f9b40ff7 100644
> --- a/libavcodec/mpeg4videoenc.c
> +++ b/libavcodec/mpeg4videoenc.c
> @@ -806,8 +806,14 @@ void ff_mpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64],
>          const uint8_t *scan_table[6];
>          int i;
>  
> -        for (i = 0; i < 6; i++)
> -            dc_diff[i] = ff_mpeg4_pred_dc(s, i, block[i][0], &dir[i], 1);
> +        for (int i = 0; i < 6; i++) {

Redeclaring i inside for.

> +            int pred  = ff_mpeg4_pred_dc(s, i, &dir[i]);
> +            int scale = i < 4 ? s->y_dc_scale : s->c_dc_scale;
> +
> +            pred = FASTDIV((pred + (scale >> 1)), scale);
> +            dc_diff[i] = block[i][0] - pred;
> +            s->dc_val[0][s->block_index[i]] = av_clip_uintp2(block[i][0] * scale, 11);
> +        }
>  
>          if (s->avctx->flags & AV_CODEC_FLAG_AC_PRED) {
>              s->ac_pred = decide_ac_pred(s, block, dir, scan_table, zigzag_last_index);


[PATCH 35/40] avcodec/speedhqenc: Inline ff_speedhq_mb_y_order_to_mb()

Why? I'm not against this, but it doesn't seem to have a greater reason.

Ramiro

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [FFmpeg-devel] Misc mpegvideo patches
  2025-03-04 16:30 ` Ramiro Polla
@ 2025-03-04 17:04   ` Andreas Rheinhardt
  2025-03-04 18:39     ` Ramiro Polla
  0 siblings, 1 reply; 6+ messages in thread
From: Andreas Rheinhardt @ 2025-03-04 17:04 UTC (permalink / raw)
  To: ffmpeg-devel

Ramiro Polla:
> 
> On 3/4/25 14:42, Andreas Rheinhardt wrote:
>> (Mostly trivial) patches attached. A branch is at
>> https://github.com/mkver/FFmpeg/tree/mpegvideo_misc
> 
> 
> [PATCH 10/40] avcodec/mpegvideo_enc: Move default_mv_penalty to h261enc.c
> 
>> diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
>> index dabab9d80a..e33bf35a8a 100644
>> --- a/libavcodec/h261enc.c
>> +++ b/libavcodec/h261enc.c
>> @@ -46,6 +46,7 @@ static struct VLCLUT {
>>      uint16_t code;
>>  } vlc_lut[H261_MAX_RUN + 1][32 /* 0..2 * H261_MAX_LEN are used */];
>>  
>> +static uint8_t mv_penalty[MAX_FCODE + 1][MAX_DMV * 2 + 1];
>>  static uint8_t uni_h261_rl_len     [64 * 128];
>>  static uint8_t uni_h261_rl_len_last[64 * 128];
>>  static uint8_t h261_mv_codes[64][2];
>> @@ -370,6 +371,8 @@ av_cold int ff_h261_encode_init(MpegEncContext *s)
>>      s->max_qcoeff       = 127;
>>      s->ac_esc_length    = H261_ESC_LEN;
>>  
>> +    s->me.mv_penalty = mv_penalty;
>> +
>>      s->intra_ac_vlc_length      = s->inter_ac_vlc_length      =
>> uni_h261_rl_len;
>>      s->intra_ac_vlc_last_length = s->inter_ac_vlc_last_length =
>> uni_h261_rl_len_last;
>>      ff_thread_once(&init_static_once, h261_encode_init_static);
> 
> This global mv_penalty doesn't seem to be ever initialized; it could be
> declared const.

But then it would no longer be placed in .bss, but instead in .rodata
and increase binary size.

> But it also makes me think that whatever code is using this mv_penalty,
> which is always set to zero, might be calculating things wrong.
> 

It is obviously done to avoid branches for the codecs that matter. H.261
does not matter much. Apart from that, it is a very cheap workaround
given that this table is .bss.

> 
> [PATCH 15/40] avcodec/ituh263enc: Make SVQ1+Snowenc stop calling
> ff_h263_encode_init()
> 
>> diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
>> index 02da090ba4..8313b2c2c1 100644
>> --- a/libavcodec/ituh263enc.c
>> +++ b/libavcodec/ituh263enc.c
>> @@ -65,6 +65,127 @@ static uint8_t  uni_h263_inter_rl_len [64*64*2*2];
> [...]
>> +static av_cold void h263_encode_init_static(void)
>> +{
>> +    static uint8_t rl_intra_table[2][2 * MAX_RUN + MAX_LEVEL + 3];
>> +
>> +    ff_rl_init(&ff_rl_intra_aic, rl_intra_table);
>> +    ff_h263_init_rl_inter();
>> +
>> +    init_uni_h263_rl_tab(&ff_rl_intra_aic,  uni_h263_intra_aic_rl_len);
>> +    init_uni_h263_rl_tab(&ff_h263_rl_inter, uni_h263_inter_rl_len);
>> +
>> +    init_mv_penalty_and_fcode();
>> +}
>> +
>> +av_cold const uint8_t (*ff_h263_get_mv_penalty(void))[MAX_DMV*2+1]
>> +{
>> +    static AVOnce init_static_once = AV_ONCE_INIT;
>> +
>> +    ff_thread_once(&init_static_once, h263_encode_init_static);
>> +
>> +    return mv_penalty;
>> +}
>> +
> 
> This approach kind of hides the rest of h263_encode_init_static() inside
> ff_h263_get_mv_penalty(), so the name is a bit misleading. I'd expect
> h263 to still call some init function and ff_h263_get_mv_penalty(), and
> SVQ1 and Snow to only call ff_h263_get_mv_penalty(), which would only
> take care of the mv_penalty table.
> 

This would entail using another AVOnce etc. and this level of
granularity is just not worth it.
The name is chosen for what it does for an outsider (i.e. from the
perspective of svq1enc or snowenc, not the actual H.263 based encoders).

> 
> [PATCH 18/40] avcodec/ituh263dec: Reorder branches
> 
>> diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c
>> index e0f3034e57..93349a3b0e 100644
>> --- a/libavcodec/ituh263dec.c
>> +++ b/libavcodec/ituh263dec.c
>> @@ -543,6 +543,8 @@ static int h263_decode_block(MpegEncContext * s,
>> int16_t * block,
>>      if (s->h263_aic && s->mb_intra) {
>>          rl = &ff_rl_intra_aic;
>>          i = 0;
>> +        if (!coded)
>> +            goto not_coded;
> 
> Why not move the if before setting rl (doesn't seem to be used) and i
> (will be overwritten anyways)?

Ok, will do. I will also make not_coded jump to after the "if
(s->mb_intra && s->h263_aic)".

> 
>>          if (s->ac_pred) {
>>              if (s->h263_aic_dir)
>>                  scan_table = s->permutated_intra_v_scantable; /* left */
>> @@ -587,8 +589,6 @@ static int h263_decode_block(MpegEncContext * s,
>> int16_t * block,
>>          i = 0;
>>      }
>>      if (!coded) {
>> -        if (s->mb_intra && s->h263_aic)
>> -            goto not_coded;
>>          s->block_last_index[n] = i - 1;
>>          return 0;
>>      }
> 
> 
> [PATCH 20/40] avcodec/mpeg4video: Split ff_mpeg4_pred_dc()
> 
>> diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
>> index 64fb96a0cf..26f9b40ff7 100644
>> --- a/libavcodec/mpeg4videoenc.c
>> +++ b/libavcodec/mpeg4videoenc.c
>> @@ -806,8 +806,14 @@ void ff_mpeg4_encode_mb(MpegEncContext *s,
>> int16_t block[6][64],
>>          const uint8_t *scan_table[6];
>>          int i;
>>  
>> -        for (i = 0; i < 6; i++)
>> -            dc_diff[i] = ff_mpeg4_pred_dc(s, i, block[i][0], &dir[i],
>> 1);
>> +        for (int i = 0; i < 6; i++) {
> 
> Redeclaring i inside for.

There are other loops which use this i as loop variable. The shadowing
is IMO less bad than keeping loops in their current form (with iterators
that don't have loop-scope).

> 
>> +            int pred  = ff_mpeg4_pred_dc(s, i, &dir[i]);
>> +            int scale = i < 4 ? s->y_dc_scale : s->c_dc_scale;
>> +
>> +            pred = FASTDIV((pred + (scale >> 1)), scale);
>> +            dc_diff[i] = block[i][0] - pred;
>> +            s->dc_val[0][s->block_index[i]] = av_clip_uintp2(block[i]
>> [0] * scale, 11);
>> +        }
>>  
>>          if (s->avctx->flags & AV_CODEC_FLAG_AC_PRED) {
>>              s->ac_pred = decide_ac_pred(s, block, dir, scan_table,
>> zigzag_last_index);
> 
> 
> [PATCH 35/40] avcodec/speedhqenc: Inline ff_speedhq_mb_y_order_to_mb()
> 
> Why? I'm not against this, but it doesn't seem to have a greater reason.
> 

It is an extremely simple function that is only called once, no need for
it to be not inlined.

- Andreas

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [FFmpeg-devel] Misc mpegvideo patches
  2025-03-04 17:04   ` Andreas Rheinhardt
@ 2025-03-04 18:39     ` Ramiro Polla
  2025-03-04 21:06       ` Andreas Rheinhardt
  0 siblings, 1 reply; 6+ messages in thread
From: Ramiro Polla @ 2025-03-04 18:39 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On Tue, Mar 4, 2025 at 6:05 PM Andreas Rheinhardt
<andreas.rheinhardt@outlook.com> wrote:
> Ramiro Polla:
> >
> > On 3/4/25 14:42, Andreas Rheinhardt wrote:
> >> (Mostly trivial) patches attached. A branch is at
> >> https://github.com/mkver/FFmpeg/tree/mpegvideo_misc
> >
> >
> > [PATCH 10/40] avcodec/mpegvideo_enc: Move default_mv_penalty to h261enc.c
> >
> >> diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
> >> index dabab9d80a..e33bf35a8a 100644
> >> --- a/libavcodec/h261enc.c
> >> +++ b/libavcodec/h261enc.c
> >> @@ -46,6 +46,7 @@ static struct VLCLUT {
> >>      uint16_t code;
> >>  } vlc_lut[H261_MAX_RUN + 1][32 /* 0..2 * H261_MAX_LEN are used */];
> >>
> >> +static uint8_t mv_penalty[MAX_FCODE + 1][MAX_DMV * 2 + 1];
> >>  static uint8_t uni_h261_rl_len     [64 * 128];
> >>  static uint8_t uni_h261_rl_len_last[64 * 128];
> >>  static uint8_t h261_mv_codes[64][2];
> >> @@ -370,6 +371,8 @@ av_cold int ff_h261_encode_init(MpegEncContext *s)
> >>      s->max_qcoeff       = 127;
> >>      s->ac_esc_length    = H261_ESC_LEN;
> >>
> >> +    s->me.mv_penalty = mv_penalty;
> >> +
> >>      s->intra_ac_vlc_length      = s->inter_ac_vlc_length      =
> >> uni_h261_rl_len;
> >>      s->intra_ac_vlc_last_length = s->inter_ac_vlc_last_length =
> >> uni_h261_rl_len_last;
> >>      ff_thread_once(&init_static_once, h261_encode_init_static);
> >
> > This global mv_penalty doesn't seem to be ever initialized; it could be
> > declared const.
>
> But then it would no longer be placed in .bss, but instead in .rodata
> and increase binary size.

Wow, that's a huge array.

> > But it also makes me think that whatever code is using this mv_penalty,
> > which is always set to zero, might be calculating things wrong.
> >
>
> It is obviously done to avoid branches for the codecs that matter. H.261
> does not matter much. Apart from that, it is a very cheap workaround
> given that this table is .bss.

Could you add some comments (either next to the declaration or the
commit message) to reflect this? (save space from .rodata, and this
being a noop for h.261, which doesn't matter that much)

> > [PATCH 15/40] avcodec/ituh263enc: Make SVQ1+Snowenc stop calling
> > ff_h263_encode_init()
> >
> >> diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
> >> index 02da090ba4..8313b2c2c1 100644
> >> --- a/libavcodec/ituh263enc.c
> >> +++ b/libavcodec/ituh263enc.c
> >> @@ -65,6 +65,127 @@ static uint8_t  uni_h263_inter_rl_len [64*64*2*2];
> > [...]
> >> +static av_cold void h263_encode_init_static(void)
> >> +{
> >> +    static uint8_t rl_intra_table[2][2 * MAX_RUN + MAX_LEVEL + 3];
> >> +
> >> +    ff_rl_init(&ff_rl_intra_aic, rl_intra_table);
> >> +    ff_h263_init_rl_inter();
> >> +
> >> +    init_uni_h263_rl_tab(&ff_rl_intra_aic,  uni_h263_intra_aic_rl_len);
> >> +    init_uni_h263_rl_tab(&ff_h263_rl_inter, uni_h263_inter_rl_len);
> >> +
> >> +    init_mv_penalty_and_fcode();
> >> +}
> >> +
> >> +av_cold const uint8_t (*ff_h263_get_mv_penalty(void))[MAX_DMV*2+1]
> >> +{
> >> +    static AVOnce init_static_once = AV_ONCE_INIT;
> >> +
> >> +    ff_thread_once(&init_static_once, h263_encode_init_static);
> >> +
> >> +    return mv_penalty;
> >> +}
> >> +
> >
> > This approach kind of hides the rest of h263_encode_init_static() inside
> > ff_h263_get_mv_penalty(), so the name is a bit misleading. I'd expect
> > h263 to still call some init function and ff_h263_get_mv_penalty(), and
> > SVQ1 and Snow to only call ff_h263_get_mv_penalty(), which would only
> > take care of the mv_penalty table.
> >
>
> This would entail using another AVOnce etc. and this level of
> granularity is just not worth it.

Ok.

> The name is chosen for what it does for an outsider (i.e. from the
> perspective of svq1enc or snowenc, not the actual H.263 based encoders).

I'm still not quite happy with the name and how it's used, but it's
good enough so I won't insist.

> > [PATCH 20/40] avcodec/mpeg4video: Split ff_mpeg4_pred_dc()
> >
> >> diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
> >> index 64fb96a0cf..26f9b40ff7 100644
> >> --- a/libavcodec/mpeg4videoenc.c
> >> +++ b/libavcodec/mpeg4videoenc.c
> >> @@ -806,8 +806,14 @@ void ff_mpeg4_encode_mb(MpegEncContext *s,
> >> int16_t block[6][64],
> >>          const uint8_t *scan_table[6];
> >>          int i;
> >>
> >> -        for (i = 0; i < 6; i++)
> >> -            dc_diff[i] = ff_mpeg4_pred_dc(s, i, block[i][0], &dir[i],
> >> 1);
> >> +        for (int i = 0; i < 6; i++) {
> >
> > Redeclaring i inside for.
>
> There are other loops which use this i as loop variable. The shadowing
> is IMO less bad than keeping loops in their current form (with iterators
> that don't have loop-scope).

Agreed. I also prefer scoped iterators.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [FFmpeg-devel] Misc mpegvideo patches
  2025-03-04 18:39     ` Ramiro Polla
@ 2025-03-04 21:06       ` Andreas Rheinhardt
  2025-03-04 22:08         ` Ramiro Polla
  0 siblings, 1 reply; 6+ messages in thread
From: Andreas Rheinhardt @ 2025-03-04 21:06 UTC (permalink / raw)
  To: ffmpeg-devel

[-- Attachment #1: Type: text/plain, Size: 5121 bytes --]

Ramiro Polla:
> On Tue, Mar 4, 2025 at 6:05 PM Andreas Rheinhardt
> <andreas.rheinhardt@outlook.com> wrote:
>> Ramiro Polla:
>>>
>>> On 3/4/25 14:42, Andreas Rheinhardt wrote:
>>>> (Mostly trivial) patches attached. A branch is at
>>>> https://github.com/mkver/FFmpeg/tree/mpegvideo_misc
>>>
>>>
>>> [PATCH 10/40] avcodec/mpegvideo_enc: Move default_mv_penalty to h261enc.c
>>>
>>>> diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
>>>> index dabab9d80a..e33bf35a8a 100644
>>>> --- a/libavcodec/h261enc.c
>>>> +++ b/libavcodec/h261enc.c
>>>> @@ -46,6 +46,7 @@ static struct VLCLUT {
>>>>      uint16_t code;
>>>>  } vlc_lut[H261_MAX_RUN + 1][32 /* 0..2 * H261_MAX_LEN are used */];
>>>>
>>>> +static uint8_t mv_penalty[MAX_FCODE + 1][MAX_DMV * 2 + 1];
>>>>  static uint8_t uni_h261_rl_len     [64 * 128];
>>>>  static uint8_t uni_h261_rl_len_last[64 * 128];
>>>>  static uint8_t h261_mv_codes[64][2];
>>>> @@ -370,6 +371,8 @@ av_cold int ff_h261_encode_init(MpegEncContext *s)
>>>>      s->max_qcoeff       = 127;
>>>>      s->ac_esc_length    = H261_ESC_LEN;
>>>>
>>>> +    s->me.mv_penalty = mv_penalty;
>>>> +
>>>>      s->intra_ac_vlc_length      = s->inter_ac_vlc_length      =
>>>> uni_h261_rl_len;
>>>>      s->intra_ac_vlc_last_length = s->inter_ac_vlc_last_length =
>>>> uni_h261_rl_len_last;
>>>>      ff_thread_once(&init_static_once, h261_encode_init_static);
>>>
>>> This global mv_penalty doesn't seem to be ever initialized; it could be
>>> declared const.
>>
>> But then it would no longer be placed in .bss, but instead in .rodata
>> and increase binary size.
> 
> Wow, that's a huge array.
> 
>>> But it also makes me think that whatever code is using this mv_penalty,
>>> which is always set to zero, might be calculating things wrong.
>>>
>>
>> It is obviously done to avoid branches for the codecs that matter. H.261
>> does not matter much. Apart from that, it is a very cheap workaround
>> given that this table is .bss.
> 
> Could you add some comments (either next to the declaration or the
> commit message) to reflect this? (save space from .rodata, and this
> being a noop for h.261, which doesn't matter that much)
> 
>>> [PATCH 15/40] avcodec/ituh263enc: Make SVQ1+Snowenc stop calling
>>> ff_h263_encode_init()
>>>
>>>> diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
>>>> index 02da090ba4..8313b2c2c1 100644
>>>> --- a/libavcodec/ituh263enc.c
>>>> +++ b/libavcodec/ituh263enc.c
>>>> @@ -65,6 +65,127 @@ static uint8_t  uni_h263_inter_rl_len [64*64*2*2];
>>> [...]
>>>> +static av_cold void h263_encode_init_static(void)
>>>> +{
>>>> +    static uint8_t rl_intra_table[2][2 * MAX_RUN + MAX_LEVEL + 3];
>>>> +
>>>> +    ff_rl_init(&ff_rl_intra_aic, rl_intra_table);
>>>> +    ff_h263_init_rl_inter();
>>>> +
>>>> +    init_uni_h263_rl_tab(&ff_rl_intra_aic,  uni_h263_intra_aic_rl_len);
>>>> +    init_uni_h263_rl_tab(&ff_h263_rl_inter, uni_h263_inter_rl_len);
>>>> +
>>>> +    init_mv_penalty_and_fcode();
>>>> +}
>>>> +
>>>> +av_cold const uint8_t (*ff_h263_get_mv_penalty(void))[MAX_DMV*2+1]
>>>> +{
>>>> +    static AVOnce init_static_once = AV_ONCE_INIT;
>>>> +
>>>> +    ff_thread_once(&init_static_once, h263_encode_init_static);
>>>> +
>>>> +    return mv_penalty;
>>>> +}
>>>> +
>>>
>>> This approach kind of hides the rest of h263_encode_init_static() inside
>>> ff_h263_get_mv_penalty(), so the name is a bit misleading. I'd expect
>>> h263 to still call some init function and ff_h263_get_mv_penalty(), and
>>> SVQ1 and Snow to only call ff_h263_get_mv_penalty(), which would only
>>> take care of the mv_penalty table.
>>>
>>
>> This would entail using another AVOnce etc. and this level of
>> granularity is just not worth it.
> 
> Ok.
> 
>> The name is chosen for what it does for an outsider (i.e. from the
>> perspective of svq1enc or snowenc, not the actual H.263 based encoders).
> 
> I'm still not quite happy with the name and how it's used, but it's
> good enough so I won't insist.
> 
>>> [PATCH 20/40] avcodec/mpeg4video: Split ff_mpeg4_pred_dc()
>>>
>>>> diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
>>>> index 64fb96a0cf..26f9b40ff7 100644
>>>> --- a/libavcodec/mpeg4videoenc.c
>>>> +++ b/libavcodec/mpeg4videoenc.c
>>>> @@ -806,8 +806,14 @@ void ff_mpeg4_encode_mb(MpegEncContext *s,
>>>> int16_t block[6][64],
>>>>          const uint8_t *scan_table[6];
>>>>          int i;
>>>>
>>>> -        for (i = 0; i < 6; i++)
>>>> -            dc_diff[i] = ff_mpeg4_pred_dc(s, i, block[i][0], &dir[i],
>>>> 1);
>>>> +        for (int i = 0; i < 6; i++) {
>>>
>>> Redeclaring i inside for.
>>
>> There are other loops which use this i as loop variable. The shadowing
>> is IMO less bad than keeping loops in their current form (with iterators
>> that don't have loop-scope).
> 
> Agreed. I also prefer scoped iterators.

I added a comment to #10 and modified #18 as described. I also changed
#21 to protect the macro in parentheses and simplified the FF_RC_OFFSET
macro in #31. Furthermore, there are now five more patches. All
attached. https://github.com/mkver/FFmpeg/tree/mpegvideo_misc has been
force-pushed.

- Andreas

[-- Attachment #2: 0001-avcodec-rv34-Make-ff_rv34_get_start_offset-honor-its.patch --]
[-- Type: text/x-patch, Size: 2551 bytes --]

From 7bf6f6d334fd0cb60ecd7253ea75089e95e5e3f2 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 26 Feb 2025 11:13:15 +0100
Subject: [PATCH 01/45] avcodec/rv34: Make ff_rv34_get_start_offset() honor its
 name

Up until now, it only returned the number of bits for the
start offset, but not the start offset; the GetBitContext
passed to it was unused.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/rv30.c | 4 +---
 libavcodec/rv34.c | 2 +-
 libavcodec/rv40.c | 4 +---
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c
index 5e1dd01aa1..351276995b 100644
--- a/libavcodec/rv30.c
+++ b/libavcodec/rv30.c
@@ -38,7 +38,6 @@
 static int rv30_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si)
 {
     AVCodecContext *avctx = r->s.avctx;
-    int mb_bits;
     int w = r->s.width, h = r->s.height;
     int mb_size;
     int rpr;
@@ -76,8 +75,7 @@ static int rv30_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceIn
     si->width  = w;
     si->height = h;
     mb_size = ((w + 15) >> 4) * ((h + 15) >> 4);
-    mb_bits = ff_rv34_get_start_offset(gb, mb_size);
-    si->start = get_bits(gb, mb_bits);
+    si->start = ff_rv34_get_start_offset(gb, mb_size);
     skip_bits1(gb);
     return 0;
 }
diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c
index d8d307f969..ddc95c3a78 100644
--- a/libavcodec/rv34.c
+++ b/libavcodec/rv34.c
@@ -342,7 +342,7 @@ int ff_rv34_get_start_offset(GetBitContext *gb, int mb_size)
     for(i = 0; i < 5; i++)
         if(rv34_mb_max_sizes[i] >= mb_size - 1)
             break;
-    return rv34_mb_bits_sizes[i];
+    return get_bits(gb, rv34_mb_bits_sizes[i]);
 }
 
 /**
diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c
index 0a5136d129..d28e02c2d1 100644
--- a/libavcodec/rv40.c
+++ b/libavcodec/rv40.c
@@ -131,7 +131,6 @@ static void rv40_parse_picture_size(GetBitContext *gb, int *w, int *h)
 
 static int rv40_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si)
 {
-    int mb_bits;
     int w = r->s.width, h = r->s.height;
     int mb_size;
     int ret;
@@ -154,8 +153,7 @@ static int rv40_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceIn
     si->width  = w;
     si->height = h;
     mb_size = ((w + 15) >> 4) * ((h + 15) >> 4);
-    mb_bits = ff_rv34_get_start_offset(gb, mb_size);
-    si->start = get_bits(gb, mb_bits);
+    si->start = ff_rv34_get_start_offset(gb, mb_size);
 
     return 0;
 }
-- 
2.45.2


[-- Attachment #3: 0002-avcodec-vc1_block-vc1dec-Don-t-use-c_dc_scale-_table.patch --]
[-- Type: text/x-patch, Size: 6538 bytes --]

From af15d9d28e90598e8be00f78cf9925887898d329 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 27 Feb 2025 14:15:10 +0100
Subject: [PATCH 02/45] avcodec/vc1_block, vc1dec: Don't use
 c_dc_scale(_table)?

It coincides with the luma values.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/vc1_block.c | 43 +++++++++++-------------------------------
 libavcodec/vc1dec.c    |  1 -
 2 files changed, 11 insertions(+), 33 deletions(-)

diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c
index 1c422d902f..5dd2083385 100644
--- a/libavcodec/vc1_block.c
+++ b/libavcodec/vc1_block.c
@@ -354,8 +354,7 @@ static inline int vc1_i_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
     };
 
     /* find prediction - wmv3_dc_scale always used here in fact */
-    if (n < 4) scale = s->y_dc_scale;
-    else       scale = s->c_dc_scale;
+    scale = s->y_dc_scale;
 
     wrap   = s->block_wrap[n];
     dc_val = s->dc_val[0] + s->block_index[n];
@@ -611,11 +610,7 @@ static int vc1_decode_i_block(VC1Context *v, int16_t block[64], int n,
     *dc_val = dcdiff;
 
     /* Store the quantized DC coeff, used for prediction */
-    if (n < 4)
-        scale = s->y_dc_scale;
-    else
-        scale = s->c_dc_scale;
-    block[0] = dcdiff * scale;
+    block[0] = dcdiff * s->y_dc_scale;
 
     ac_val  = s->ac_val[0][s->block_index[n]];
     ac_val2 = ac_val;
@@ -752,11 +747,7 @@ static int vc1_decode_i_block_adv(VC1Context *v, int16_t block[64], int n,
     *dc_val = dcdiff;
 
     /* Store the quantized DC coeff, used for prediction */
-    if (n < 4)
-        scale = s->y_dc_scale;
-    else
-        scale = s->c_dc_scale;
-    block[0] = dcdiff * scale;
+    block[0] = dcdiff * s->y_dc_scale;
 
     /* check if AC is needed at all */
     if (!a_avail && !c_avail)
@@ -925,9 +916,8 @@ static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n,
     /* XXX: Guard against dumb values of mquant */
     quant = av_clip_uintp2(quant, 5);
 
-    /* Set DC scale - y and c use the same */
+    /* Set DC scale - y and c use the same so we only set y */
     s->y_dc_scale = s->y_dc_scale_table[quant];
-    s->c_dc_scale = s->c_dc_scale_table[quant];
 
     /* Get DC differential */
     dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_vlc[s->dc_table_index][n >= 4],
@@ -949,12 +939,7 @@ static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n,
     *dc_val = dcdiff;
 
     /* Store the quantized DC coeff, used for prediction */
-
-    if (n < 4) {
-        block[0] = dcdiff * s->y_dc_scale;
-    } else {
-        block[0] = dcdiff * s->c_dc_scale;
-    }
+    block[0] = dcdiff * s->y_dc_scale;
 
     //AC Decoding
     i = 1;
@@ -1593,9 +1578,8 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
             v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
             GET_MQUANT();
             s->cur_pic.qscale_table[mb_pos] = mquant;
-            /* Set DC scale - y and c use the same (not sure if necessary here) */
+            /* Set DC scale - y and c use the same so we only set y */
             s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
-            s->c_dc_scale = s->c_dc_scale_table[FFABS(mquant)];
             dst_idx = 0;
             for (i = 0; i < 6; i++) {
                 v->a_avail = v->c_avail          = 0;
@@ -1756,9 +1740,8 @@ static int vc1_decode_p_mb_intfi(VC1Context *v)
         s->cur_pic.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
         GET_MQUANT();
         s->cur_pic.qscale_table[mb_pos] = mquant;
-        /* Set DC scale - y and c use the same (not sure if necessary here) */
+        /* Set DC scale - y and c use the same so we only set y */
         s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
-        s->c_dc_scale = s->c_dc_scale_table[FFABS(mquant)];
         v->s.ac_pred  = v->acpred_plane[mb_pos] = get_bits1(gb);
         mb_has_coeffs = idx_mbmode & 1;
         if (mb_has_coeffs)
@@ -2044,9 +2027,8 @@ static int vc1_decode_b_mb_intfi(VC1Context *v)
         s->cur_pic.mb_type[mb_pos + v->mb_off]         = MB_TYPE_INTRA;
         GET_MQUANT();
         s->cur_pic.qscale_table[mb_pos] = mquant;
-        /* Set DC scale - y and c use the same (not sure if necessary here) */
+        /* Set DC scale - y and c use the same so we only set y */
         s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
-        s->c_dc_scale = s->c_dc_scale_table[FFABS(mquant)];
         v->s.ac_pred  = v->acpred_plane[mb_pos] = get_bits1(gb);
         mb_has_coeffs = idx_mbmode & 1;
         if (mb_has_coeffs)
@@ -2245,9 +2227,8 @@ static int vc1_decode_b_mb_intfr(VC1Context *v)
         v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
         GET_MQUANT();
         s->cur_pic.qscale_table[mb_pos] = mquant;
-        /* Set DC scale - y and c use the same (not sure if necessary here) */
+        /* Set DC scale - y and c use the same so we only set y */
         s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
-        s->c_dc_scale = s->c_dc_scale_table[FFABS(mquant)];
         dst_idx = 0;
         for (i = 0; i < 6; i++) {
             v->a_avail = v->c_avail          = 0;
@@ -2568,9 +2549,8 @@ static void vc1_decode_i_blocks(VC1Context *v)
         break;
     }
 
-    /* Set DC scale - y and c use the same */
+    /* Set DC scale - y and c use the same so we only set y */
     s->y_dc_scale = s->y_dc_scale_table[v->pq];
-    s->c_dc_scale = s->c_dc_scale_table[v->pq];
 
     //do frame decode
     s->mb_x = s->mb_y = 0;
@@ -2738,9 +2718,8 @@ static int vc1_decode_i_blocks_adv(VC1Context *v)
             GET_MQUANT();
 
             s->cur_pic.qscale_table[mb_pos] = mquant;
-            /* Set DC scale - y and c use the same */
+            /* Set DC scale - y and c use the same so we only set y */
             s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
-            s->c_dc_scale = s->c_dc_scale_table[FFABS(mquant)];
 
             for (k = 0; k < 6; k++) {
                 v->mb_type[0][s->block_index[k]] = 1;
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index cfd97c4ca6..bd6f090c55 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -472,7 +472,6 @@ av_cold int ff_vc1_decode_init(AVCodecContext *avctx)
         return ret;
 
     s->y_dc_scale_table = ff_wmv3_dc_scale_table;
-    s->c_dc_scale_table = ff_wmv3_dc_scale_table;
 
     ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable,
                       ff_wmv1_scantable[1]);
-- 
2.45.2


[-- Attachment #4: 0003-avcodec-vc1_block-Inline-y_dc_scale_table.patch --]
[-- Type: text/x-patch, Size: 5796 bytes --]

From 7b4f8fd62259a81fc9bdc0e4d813a64d767526f3 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 27 Feb 2025 14:58:43 +0100
Subject: [PATCH 03/45] avcodec/vc1_block: Inline y_dc_scale_table

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/vc1_block.c | 22 +++++++++++-----------
 libavcodec/vc1dec.c    |  2 --
 2 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c
index 5dd2083385..8babbde38c 100644
--- a/libavcodec/vc1_block.c
+++ b/libavcodec/vc1_block.c
@@ -417,7 +417,7 @@ static inline int ff_vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
 
     /* scale predictors if needed */
     q1 = FFABS(s->cur_pic.qscale_table[mb_pos]);
-    dqscale_index = s->y_dc_scale_table[q1] - 1;
+    dqscale_index = ff_wmv3_dc_scale_table[q1] - 1;
     if (dqscale_index < 0)
         return 0;
 
@@ -434,12 +434,12 @@ static inline int ff_vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
     if (c_avail && (n != 1 && n != 3)) {
         q2 = FFABS(s->cur_pic.qscale_table[mb_pos - 1]);
         if (q2 && q2 != q1)
-            c = (int)((unsigned)c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
+            c = (int)((unsigned)c * ff_wmv3_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
     }
     if (a_avail && (n != 2 && n != 3)) {
         q2 = FFABS(s->cur_pic.qscale_table[mb_pos - s->mb_stride]);
         if (q2 && q2 != q1)
-            a = (int)((unsigned)a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
+            a = (int)((unsigned)a * ff_wmv3_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
     }
     if (a_avail && c_avail && (n != 3)) {
         int off = mb_pos;
@@ -449,7 +449,7 @@ static inline int ff_vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
             off -= s->mb_stride;
         q2 = FFABS(s->cur_pic.qscale_table[off]);
         if (q2 && q2 != q1)
-            b = (int)((unsigned)b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
+            b = (int)((unsigned)b * ff_wmv3_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
     }
 
     if (c_avail && (!a_avail || abs(a - b) <= abs(b - c))) {
@@ -917,7 +917,7 @@ static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n,
     quant = av_clip_uintp2(quant, 5);
 
     /* Set DC scale - y and c use the same so we only set y */
-    s->y_dc_scale = s->y_dc_scale_table[quant];
+    s->y_dc_scale = ff_wmv3_dc_scale_table[quant];
 
     /* Get DC differential */
     dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_vlc[s->dc_table_index][n >= 4],
@@ -1579,7 +1579,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
             GET_MQUANT();
             s->cur_pic.qscale_table[mb_pos] = mquant;
             /* Set DC scale - y and c use the same so we only set y */
-            s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
+            s->y_dc_scale = ff_wmv3_dc_scale_table[FFABS(mquant)];
             dst_idx = 0;
             for (i = 0; i < 6; i++) {
                 v->a_avail = v->c_avail          = 0;
@@ -1741,7 +1741,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v)
         GET_MQUANT();
         s->cur_pic.qscale_table[mb_pos] = mquant;
         /* Set DC scale - y and c use the same so we only set y */
-        s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
+        s->y_dc_scale = ff_wmv3_dc_scale_table[FFABS(mquant)];
         v->s.ac_pred  = v->acpred_plane[mb_pos] = get_bits1(gb);
         mb_has_coeffs = idx_mbmode & 1;
         if (mb_has_coeffs)
@@ -2028,7 +2028,7 @@ static int vc1_decode_b_mb_intfi(VC1Context *v)
         GET_MQUANT();
         s->cur_pic.qscale_table[mb_pos] = mquant;
         /* Set DC scale - y and c use the same so we only set y */
-        s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
+        s->y_dc_scale = ff_wmv3_dc_scale_table[FFABS(mquant)];
         v->s.ac_pred  = v->acpred_plane[mb_pos] = get_bits1(gb);
         mb_has_coeffs = idx_mbmode & 1;
         if (mb_has_coeffs)
@@ -2228,7 +2228,7 @@ static int vc1_decode_b_mb_intfr(VC1Context *v)
         GET_MQUANT();
         s->cur_pic.qscale_table[mb_pos] = mquant;
         /* Set DC scale - y and c use the same so we only set y */
-        s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
+        s->y_dc_scale = ff_wmv3_dc_scale_table[FFABS(mquant)];
         dst_idx = 0;
         for (i = 0; i < 6; i++) {
             v->a_avail = v->c_avail          = 0;
@@ -2550,7 +2550,7 @@ static void vc1_decode_i_blocks(VC1Context *v)
     }
 
     /* Set DC scale - y and c use the same so we only set y */
-    s->y_dc_scale = s->y_dc_scale_table[v->pq];
+    s->y_dc_scale = ff_wmv3_dc_scale_table[v->pq];
 
     //do frame decode
     s->mb_x = s->mb_y = 0;
@@ -2719,7 +2719,7 @@ static int vc1_decode_i_blocks_adv(VC1Context *v)
 
             s->cur_pic.qscale_table[mb_pos] = mquant;
             /* Set DC scale - y and c use the same so we only set y */
-            s->y_dc_scale = s->y_dc_scale_table[FFABS(mquant)];
+            s->y_dc_scale = ff_wmv3_dc_scale_table[FFABS(mquant)];
 
             for (k = 0; k < 6; k++) {
                 v->mb_type[0][s->block_index[k]] = 1;
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index bd6f090c55..7256ad9557 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -471,8 +471,6 @@ av_cold int ff_vc1_decode_init(AVCodecContext *avctx)
     if (ret < 0)
         return ret;
 
-    s->y_dc_scale_table = ff_wmv3_dc_scale_table;
-
     ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable,
                       ff_wmv1_scantable[1]);
 
-- 
2.45.2


[-- Attachment #5: 0004-avcodec-vc1dec-Don-t-initialize-unused-parts-of-Scan.patch --]
[-- Type: text/x-patch, Size: 1088 bytes --]

From 4ce1bdfb79cd192035eded62e5564247a86ce80d Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 03:36:57 +0100
Subject: [PATCH 04/45] avcodec/vc1dec: Don't initialize unused parts of
 ScanTable

The VC-1 decoders don't need ScanTable.raster_end as
they don't call any of the unquantize functions.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/vc1dec.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 7256ad9557..d92a7da8ab 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -471,8 +471,8 @@ av_cold int ff_vc1_decode_init(AVCodecContext *avctx)
     if (ret < 0)
         return ret;
 
-    ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable,
-                      ff_wmv1_scantable[1]);
+    ff_permute_scantable(s->intra_scantable.permutated, ff_wmv1_scantable[1],
+                         s->idsp.idct_permutation);
 
     ret = vc1_decode_init_alloc_tables(v);
     if (ret < 0) {
-- 
2.45.2


[-- Attachment #6: 0005-avcodec-Remove-leftover-alpha-declarations.patch --]
[-- Type: text/x-patch, Size: 4178 bytes --]

From a3734572694ec6e618e5e66305b1dda1a52ee00e Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 2 Mar 2025 05:18:43 +0100
Subject: [PATCH 05/45] avcodec: Remove leftover alpha declarations

Forgotten in cdd139d760688b14849d02ee1907f68fe692c24e.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/blockdsp.h    | 1 -
 libavcodec/hpeldsp.h     | 1 -
 libavcodec/idctdsp.h     | 2 --
 libavcodec/me_cmp.h      | 1 -
 libavcodec/mpegvideo.h   | 1 -
 libavcodec/pixblockdsp.h | 2 --
 6 files changed, 8 deletions(-)

diff --git a/libavcodec/blockdsp.h b/libavcodec/blockdsp.h
index 6d751d797b..f83068ce53 100644
--- a/libavcodec/blockdsp.h
+++ b/libavcodec/blockdsp.h
@@ -38,7 +38,6 @@ typedef struct BlockDSPContext {
 
 void ff_blockdsp_init(BlockDSPContext *c);
 
-void ff_blockdsp_init_alpha(BlockDSPContext *c);
 void ff_blockdsp_init_arm(BlockDSPContext *c);
 void ff_blockdsp_init_ppc(BlockDSPContext *c);
 void ff_blockdsp_init_riscv(BlockDSPContext *c);
diff --git a/libavcodec/hpeldsp.h b/libavcodec/hpeldsp.h
index 45e81b10a5..41a46f0760 100644
--- a/libavcodec/hpeldsp.h
+++ b/libavcodec/hpeldsp.h
@@ -97,7 +97,6 @@ typedef struct HpelDSPContext {
 void ff_hpeldsp_init(HpelDSPContext *c, int flags);
 
 void ff_hpeldsp_init_aarch64(HpelDSPContext *c, int flags);
-void ff_hpeldsp_init_alpha(HpelDSPContext *c, int flags);
 void ff_hpeldsp_init_arm(HpelDSPContext *c, int flags);
 void ff_hpeldsp_init_ppc(HpelDSPContext *c, int flags);
 void ff_hpeldsp_init_x86(HpelDSPContext *c, int flags);
diff --git a/libavcodec/idctdsp.h b/libavcodec/idctdsp.h
index c08242881c..7783d7098a 100644
--- a/libavcodec/idctdsp.h
+++ b/libavcodec/idctdsp.h
@@ -98,8 +98,6 @@ void ff_idctdsp_init(IDCTDSPContext *c, struct AVCodecContext *avctx);
 
 void ff_idctdsp_init_aarch64(IDCTDSPContext *c, struct AVCodecContext *avctx,
                              unsigned high_bit_depth);
-void ff_idctdsp_init_alpha(IDCTDSPContext *c, struct AVCodecContext *avctx,
-                           unsigned high_bit_depth);
 void ff_idctdsp_init_arm(IDCTDSPContext *c, struct AVCodecContext *avctx,
                          unsigned high_bit_depth);
 void ff_idctdsp_init_ppc(IDCTDSPContext *c, struct AVCodecContext *avctx,
diff --git a/libavcodec/me_cmp.h b/libavcodec/me_cmp.h
index 9053327c4c..4aefcf1622 100644
--- a/libavcodec/me_cmp.h
+++ b/libavcodec/me_cmp.h
@@ -76,7 +76,6 @@ typedef struct MECmpContext {
 
 void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx);
 void ff_me_cmp_init_aarch64(MECmpContext *c, AVCodecContext *avctx);
-void ff_me_cmp_init_alpha(MECmpContext *c, AVCodecContext *avctx);
 void ff_me_cmp_init_arm(MECmpContext *c, AVCodecContext *avctx);
 void ff_me_cmp_init_ppc(MECmpContext *c, AVCodecContext *avctx);
 void ff_me_cmp_init_riscv(MECmpContext *c, AVCodecContext *avctx);
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 48fc1d418e..ac38d112f9 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -561,7 +561,6 @@ void ff_mpv_common_defaults(MpegEncContext *s);
 
 int ff_mpv_common_init(MpegEncContext *s);
 void ff_mpv_common_init_arm(MpegEncContext *s);
-void ff_mpv_common_init_axp(MpegEncContext *s);
 void ff_mpv_common_init_neon(MpegEncContext *s);
 void ff_mpv_common_init_ppc(MpegEncContext *s);
 void ff_mpv_common_init_x86(MpegEncContext *s);
diff --git a/libavcodec/pixblockdsp.h b/libavcodec/pixblockdsp.h
index cac5f3d4a2..215b0905d7 100644
--- a/libavcodec/pixblockdsp.h
+++ b/libavcodec/pixblockdsp.h
@@ -44,8 +44,6 @@ typedef struct PixblockDSPContext {
 void ff_pixblockdsp_init(PixblockDSPContext *c, AVCodecContext *avctx);
 void ff_pixblockdsp_init_aarch64(PixblockDSPContext *c, AVCodecContext *avctx,
                                  unsigned high_bit_depth);
-void ff_pixblockdsp_init_alpha(PixblockDSPContext *c, AVCodecContext *avctx,
-                               unsigned high_bit_depth);
 void ff_pixblockdsp_init_arm(PixblockDSPContext *c, AVCodecContext *avctx,
                              unsigned high_bit_depth);
 void ff_pixblockdsp_init_ppc(PixblockDSPContext *c, AVCodecContext *avctx,
-- 
2.45.2


[-- Attachment #7: 0006-avcodec-mpeg12dec-Don-t-count-errors-from-first-thre.patch --]
[-- Type: text/x-patch, Size: 3395 bytes --]

From 5f010a7d1e8851516de9ef56e654f42b2bb207ae Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 1 Mar 2025 22:36:35 +0100
Subject: [PATCH 06/45] avcodec/mpeg12dec: Don't count errors from first thread
 twice

Compilers can not perform this optimization on their own
given that they don't know that the different thread_context
pointers don't alias.
Also avoid using sequentially consistent operations with
atomics when only a single thread accesses them.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12dec.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index 843640edbf..6bbb8e7afd 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -29,6 +29,7 @@
 
 #define UNCHECKED_BITSTREAM_READER 1
 #include <inttypes.h>
+#include <stdatomic.h>
 
 #include "libavutil/attributes.h"
 #include "libavutil/emms.h"
@@ -46,7 +47,6 @@
 #include "hwaccel_internal.h"
 #include "hwconfig.h"
 #include "idctdsp.h"
-#include "internal.h"
 #include "mpeg_er.h"
 #include "mpeg12.h"
 #include "mpeg12codecs.h"
@@ -2252,6 +2252,7 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture,
                 if (HAVE_THREADS &&
                     (avctx->active_thread_type & FF_THREAD_SLICE) &&
                     !avctx->hwaccel) {
+                    int error_count = 0;
                     int i;
                     av_assert0(avctx->thread_count > 1);
 
@@ -2259,7 +2260,10 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture,
                                    &s2->thread_context[0], NULL,
                                    s->slice_count, sizeof(void *));
                     for (i = 0; i < s->slice_count; i++)
-                        s2->er.error_count += s2->thread_context[i]->er.error_count;
+                        error_count += atomic_load_explicit(&s2->thread_context[i]->er.error_count,
+                                                            memory_order_relaxed);
+                    atomic_store_explicit(&s2->er.error_count, error_count,
+                                          memory_order_relaxed);
                 }
 
                 ret = slice_end(avctx, picture, got_output);
@@ -2321,13 +2325,17 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture,
             }
             if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) &&
                 !avctx->hwaccel && s->slice_count) {
+                int error_count = 0;
                 int i;
 
                 avctx->execute(avctx, slice_decode_thread,
                                s2->thread_context, NULL,
                                s->slice_count, sizeof(void *));
                 for (i = 0; i < s->slice_count; i++)
-                    s2->er.error_count += s2->thread_context[i]->er.error_count;
+                    error_count += atomic_load_explicit(&s2->thread_context[i]->er.error_count,
+                                                        memory_order_relaxed);
+                atomic_store_explicit(&s2->er.error_count, error_count,
+                                      memory_order_relaxed);
                 s->slice_count = 0;
             }
             if (last_code == 0 || last_code == SLICE_MIN_START_CODE) {
-- 
2.45.2


[-- Attachment #8: 0007-avcodec-mpeg12dec-Mark-flush-as-cold.patch --]
[-- Type: text/x-patch, Size: 797 bytes --]

From 611d939a8b86d97bd0eb7b99af3dd44ebd7b9f14 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 03:30:40 +0100
Subject: [PATCH 07/45] avcodec/mpeg12dec: Mark flush as cold

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12dec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index 6bbb8e7afd..ba40c1f06f 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -2641,7 +2641,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, AVFrame *picture,
     return ret;
 }
 
-static void flush(AVCodecContext *avctx)
+static av_cold void flush(AVCodecContext *avctx)
 {
     Mpeg1Context *s = avctx->priv_data;
 
-- 
2.45.2


[-- Attachment #9: 0008-avcodec-h261dec-Don-t-call-ff_set_qscale.patch --]
[-- Type: text/x-patch, Size: 1544 bytes --]

From 96a103537ac0f1bf92821204939f73725f2af677 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 1 Mar 2025 21:32:51 +0100
Subject: [PATCH 08/45] avcodec/h261dec: Don't call ff_set_qscale()

Most of what it does is unneeded for H.261.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/h261dec.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c
index 8a2c4d35b4..c32ddd2ddf 100644
--- a/libavcodec/h261dec.c
+++ b/libavcodec/h261dec.c
@@ -155,6 +155,7 @@ static int h261_decode_gob_header(H261DecContext *h)
         av_log(s->avctx, AV_LOG_ERROR, "qscale has forbidden 0 value\n");
         if (s->avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_COMPLIANT))
             return -1;
+        s->qscale = 1;
     }
 
     /* For the first transmitted macroblock in a GOB, MBA is the absolute
@@ -380,8 +381,11 @@ static int h261_decode_mb(H261DecContext *h)
     }
 
     // Read mquant
-    if (IS_QUANT(com->mtype))
-        ff_set_qscale(s, get_bits(&s->gb, 5));
+    if (IS_QUANT(com->mtype)) {
+        s->qscale = get_bits(&s->gb, 5);
+        if (!s->qscale)
+            s->qscale = 1;
+    }
 
     s->mb_intra = IS_INTRA4x4(com->mtype);
 
@@ -511,8 +515,6 @@ static int h261_decode_gob(H261DecContext *h)
 {
     MpegEncContext *const s = &h->s;
 
-    ff_set_qscale(s, s->qscale);
-
     /* decode mb's */
     while (h->current_mba <= MBA_STUFFING) {
         int ret;
-- 
2.45.2


[-- Attachment #10: 0009-avcodec-h261-Use-forward-declaration-for-MpegEncCont.patch --]
[-- Type: text/x-patch, Size: 1036 bytes --]

From be8ed1b410fea954bcb4015f94ec7b1ec7170f93 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 28 Feb 2025 18:13:59 +0100
Subject: [PATCH 09/45] avcodec/h261: Use forward-declaration for
 MpegEncContext

Avoids an indirect inclusion of mpegvideo.h in h261data.c.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/h261.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/h261.h b/libavcodec/h261.h
index 4279a12677..fb5fc6f940 100644
--- a/libavcodec/h261.h
+++ b/libavcodec/h261.h
@@ -29,7 +29,6 @@
 #define AVCODEC_H261_H
 
 #include "mpegutils.h"
-#include "mpegvideo.h"
 #include "rl.h"
 
 /**
@@ -54,6 +53,7 @@ extern const uint16_t ff_h261_tcoeff_vlc[65][2];
 extern const int8_t ff_h261_tcoeff_level[64];
 extern const int8_t ff_h261_tcoeff_run[64];
 
-void ff_h261_loop_filter(MpegEncContext *s);
+struct MpegEncContext;
+void ff_h261_loop_filter(struct MpegEncContext *s);
 
 #endif /* AVCODEC_H261_H */
-- 
2.45.2


[-- Attachment #11: 0010-avcodec-mpegvideo_enc-Move-default_mv_penalty-to-h26.patch --]
[-- Type: text/x-patch, Size: 2694 bytes --]

From 8f7569db689151c01543e4e41c7d414cdb03d3f2 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 20:53:33 +0100
Subject: [PATCH 10/45] avcodec/mpegvideo_enc: Move default_mv_penalty to
 h261enc.c

MPEG-1/2 and the H.263-based encoders overwrite the default later
and SpeedHQ and MJPEG-based encoders are intra-only and don't
need a mv_penalty table at all. So only H.261 uses this table.

Also add a comment to explain why it exists and is non-const.

Reviewed-by: Ramiro Polla <ramiro.polla@gmail.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/h261enc.c       | 6 ++++++
 libavcodec/mpegvideo_enc.c | 2 --
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index dabab9d80a..5253e82129 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -46,6 +46,10 @@ static struct VLCLUT {
     uint16_t code;
 } vlc_lut[H261_MAX_RUN + 1][32 /* 0..2 * H261_MAX_LEN are used */];
 
+// Not const despite never being initialized because doing so would
+// put it into .rodata instead of .bss and bloat the binary.
+// mv_penalty exists so that the motion estimation code can avoid branches.
+static uint8_t mv_penalty[MAX_FCODE + 1][MAX_DMV * 2 + 1];
 static uint8_t uni_h261_rl_len     [64 * 128];
 static uint8_t uni_h261_rl_len_last[64 * 128];
 static uint8_t h261_mv_codes[64][2];
@@ -370,6 +374,8 @@ av_cold int ff_h261_encode_init(MpegEncContext *s)
     s->max_qcoeff       = 127;
     s->ac_esc_length    = H261_ESC_LEN;
 
+    s->me.mv_penalty = mv_penalty;
+
     s->intra_ac_vlc_length      = s->inter_ac_vlc_length      = uni_h261_rl_len;
     s->intra_ac_vlc_last_length = s->inter_ac_vlc_last_length = uni_h261_rl_len_last;
     ff_thread_once(&init_static_once, h261_encode_init_static);
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 8c22dbb5f5..1fe69f89a6 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -93,7 +93,6 @@ static int dct_quantize_c(MpegEncContext *s,
                           int qscale, int *overflow);
 static int dct_quantize_trellis_c(MpegEncContext *s, int16_t *block, int n, int qscale, int *overflow);
 
-static uint8_t default_mv_penalty[MAX_FCODE + 1][MAX_DMV * 2 + 1];
 static uint8_t default_fcode_tab[MAX_MV * 2 + 1];
 
 static const AVOption mpv_generic_options[] = {
@@ -287,7 +286,6 @@ static void mpv_encode_defaults(MpegEncContext *s)
 
     ff_thread_once(&init_static_once, mpv_encode_init_static);
 
-    s->me.mv_penalty = default_mv_penalty;
     s->fcode_tab     = default_fcode_tab;
 
     s->input_picture_number  = 0;
-- 
2.45.2


[-- Attachment #12: 0011-avcodec-mpegutils-Move-MAX_FCODE-to-mpegvideoenc.h.patch --]
[-- Type: text/x-patch, Size: 1138 bytes --]

From d117e013c740e19438fd3883853167feb5891d74 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 21:01:31 +0100
Subject: [PATCH 11/45] avcodec/mpegutils: Move MAX_FCODE to mpegvideoenc.h

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegutils.h    | 1 -
 libavcodec/mpegvideoenc.h | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/mpegutils.h b/libavcodec/mpegutils.h
index e4ce26d299..9967762a79 100644
--- a/libavcodec/mpegutils.h
+++ b/libavcodec/mpegutils.h
@@ -33,7 +33,6 @@
 #define PICT_FRAME         3
 
 #define MAX_MB_BYTES    (30 * 16 * 16 * 3 / 8 + 120)
-#define MAX_FCODE        7
 
 /* MB types */
 #define MB_TYPE_INTRA4x4   (1 <<  0)
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index f5044a0309..2d7f76c57a 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -33,6 +33,7 @@
 #include "libavutil/opt.h"
 #include "mpegvideo.h"
 
+#define MAX_FCODE        7
 #define UNI_AC_ENC_INDEX(run,level) ((run)*128 + (level))
 #define INPLACE_OFFSET 16
 
-- 
2.45.2


[-- Attachment #13: 0012-avcodec-ituh263enc-Move-MPEG-4-fcode_tab-to-mpeg4vid.patch --]
[-- Type: text/x-patch, Size: 2959 bytes --]

From b048eabff1eee461c5ba26b6225fc720d85c4265 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 21:04:49 +0100
Subject: [PATCH 12/45] avcodec/ituh263enc: Move MPEG-4 fcode_tab to
 mpeg4videoenc.c

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/ituh263enc.c    | 12 ------------
 libavcodec/mpeg4videoenc.c | 11 +++++++++++
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 1ef4a8f88e..2152046b43 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -52,11 +52,6 @@
  */
 static uint8_t mv_penalty[MAX_FCODE+1][MAX_DMV*2+1];
 
-/**
- * Minimal fcode that a motion vector component would need.
- */
-static uint8_t fcode_tab[MAX_MV*2+1];
-
 /**
  * Minimal fcode that a motion vector component would need in umv.
  * All entries in this table are 1.
@@ -762,12 +757,6 @@ static av_cold void init_mv_penalty_and_fcode(void)
         }
     }
 
-    for(f_code=MAX_FCODE; f_code>0; f_code--){
-        for(mv=-(16<<f_code); mv<(16<<f_code); mv++){
-            fcode_tab[mv+MAX_MV]= f_code;
-        }
-    }
-
     for(mv=0; mv<MAX_MV*2+1; mv++){
         umv_fcode_tab[mv]= 1;
     }
@@ -844,7 +833,6 @@ av_cold void ff_h263_encode_init(MpegEncContext *s)
     // use fcodes >1 only for MPEG-4 & H.263 & H.263+ FIXME
     switch(s->codec_id){
     case AV_CODEC_ID_MPEG4:
-        s->fcode_tab= fcode_tab;
         break;
     case AV_CODEC_ID_H263P:
         if(s->umvplus)
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 0b31576dc5..64fb96a0cf 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -37,6 +37,11 @@
 #include "profiles.h"
 #include "version.h"
 
+/**
+ * Minimal fcode that a motion vector component would need.
+ */
+static uint8_t fcode_tab[MAX_MV*2+1];
+
 /* The uni_DCtab_* tables below contain unified bits+length tables to encode DC
  * differences in MPEG-4. Unified in the sense that the specification specifies
  * this encoding in several steps. */
@@ -1255,6 +1260,11 @@ static av_cold void mpeg4_encode_init_static(void)
 
     init_uni_mpeg4_rl_tab(&ff_mpeg4_rl_intra, uni_mpeg4_intra_rl_bits, uni_mpeg4_intra_rl_len);
     init_uni_mpeg4_rl_tab(&ff_h263_rl_inter,  uni_mpeg4_inter_rl_bits, uni_mpeg4_inter_rl_len);
+
+    for (int f_code = MAX_FCODE; f_code > 0; f_code--) {
+        for (int mv = -(16 << f_code); mv < (16 << f_code); mv++)
+            fcode_tab[mv + MAX_MV] = f_code;
+    }
 }
 
 static av_cold int encode_init(AVCodecContext *avctx)
@@ -1274,6 +1284,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
 
     ff_thread_once(&init_static_once, mpeg4_encode_init_static);
 
+    s->fcode_tab                = fcode_tab;
     s->min_qcoeff               = -2048;
     s->max_qcoeff               = 2047;
     s->intra_ac_vlc_length      = uni_mpeg4_intra_rl_len;
-- 
2.45.2


[-- Attachment #14: 0013-avcodec-ituh263enc-Remove-redundant-setting-of-dc_sc.patch --]
[-- Type: text/x-patch, Size: 1170 bytes --]

From d6664f30736a1d33bcc7625e2d3bea84ffc01bfc Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 20:32:59 +0100
Subject: [PATCH 13/45] avcodec/ituh263enc: Remove redundant setting of
 dc_scale_tables

ff_mpeg1_dc_scale_table is already the default dc_scale table
for both y and c.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/ituh263enc.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 2152046b43..ba2a373571 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -36,7 +36,6 @@
 #include "avcodec.h"
 #include "codec_internal.h"
 #include "mpegvideo.h"
-#include "mpegvideodata.h"
 #include "flvenc.h"
 #include "mpegvideoenc.h"
 #include "h263.h"
@@ -862,9 +861,6 @@ av_cold void ff_h263_encode_init(MpegEncContext *s)
     if(s->h263_aic){
          s->y_dc_scale_table=
          s->c_dc_scale_table= ff_aic_dc_scale_table;
-    }else{
-        s->y_dc_scale_table=
-        s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
     }
 
 #if CONFIG_H263_ENCODER // Snow and SVQ1 call this
-- 
2.45.2


[-- Attachment #15: 0014-avcodec-ituh263enc-Combine-branches.patch --]
[-- Type: text/x-patch, Size: 1260 bytes --]

From de6b5334662cdb20f1142a4582715aea08f19f45 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 21:15:30 +0100
Subject: [PATCH 14/45] avcodec/ituh263enc: Combine branches

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/ituh263enc.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index ba2a373571..02da090ba4 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -826,6 +826,9 @@ av_cold void ff_h263_encode_init(MpegEncContext *s)
     if(s->h263_aic){
         s->intra_ac_vlc_length     = uni_h263_intra_aic_rl_len;
         s->intra_ac_vlc_last_length= uni_h263_intra_aic_rl_len + 128*64;
+
+        s->y_dc_scale_table =
+        s->c_dc_scale_table = ff_aic_dc_scale_table;
     }
     s->ac_esc_length= 7+1+6+8;
 
@@ -858,10 +861,6 @@ av_cold void ff_h263_encode_init(MpegEncContext *s)
         s->min_qcoeff= -127;
         s->max_qcoeff=  127;
     }
-    if(s->h263_aic){
-         s->y_dc_scale_table=
-         s->c_dc_scale_table= ff_aic_dc_scale_table;
-    }
 
 #if CONFIG_H263_ENCODER // Snow and SVQ1 call this
     ff_h263dsp_init(&s->h263dsp);
-- 
2.45.2


[-- Attachment #16: 0015-avcodec-ituh263enc-Make-SVQ1-Snowenc-stop-calling-ff.patch --]
[-- Type: text/x-patch, Size: 10809 bytes --]

From ae1e415c9180b7ee6fe97deca6e97ea6ced180e2 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 22:32:40 +0100
Subject: [PATCH 15/45] avcodec/ituh263enc: Make SVQ1+Snowenc stop calling
 ff_h263_encode_init()

They only do it for the mv_penalty table. Factor initializating
the static tables out into a function of its own; also move
everything not needed by SVQ1 or Snow behind #if CONFIG_H263_ENCODER
(this involved moving ff_h263_encode_motion() which is used
by svq1enc).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/h263enc.h    |   2 +
 libavcodec/ituh263enc.c | 247 ++++++++++++++++++++--------------------
 libavcodec/snowenc.c    |   2 +-
 libavcodec/svq1enc.c    |   2 +-
 4 files changed, 127 insertions(+), 126 deletions(-)

diff --git a/libavcodec/h263enc.h b/libavcodec/h263enc.h
index 784500ca7a..71e30931aa 100644
--- a/libavcodec/h263enc.h
+++ b/libavcodec/h263enc.h
@@ -24,6 +24,8 @@
 #include "h263data.h"
 #include "mpegvideoenc.h"
 
+const uint8_t (*ff_h263_get_mv_penalty(void))[MAX_DMV*2+1];
+
 void ff_h263_encode_init(MpegEncContext *s);
 void ff_h263_encode_picture_header(MpegEncContext *s);
 void ff_h263_encode_gob_header(MpegEncContext * s, int mb_line);
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 02da090ba4..8313b2c2c1 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -65,6 +65,127 @@ static uint8_t  uni_h263_inter_rl_len [64*64*2*2];
 //#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run) + (level)*64)
 #define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run)*128 + (level))
 
+static av_cold void init_mv_penalty_and_fcode(void)
+{
+    for (int f_code = 1; f_code <= MAX_FCODE; f_code++) {
+        for (int mv = -MAX_DMV; mv <= MAX_DMV; mv++) {
+            int len;
+
+            if (mv == 0) len = 1; // ff_mvtab[0][1]
+            else {
+                int val, bit_size, code;
+
+                bit_size = f_code - 1;
+
+                val = mv;
+                if (val < 0)
+                    val = -val;
+                val--;
+                code = (val >> bit_size) + 1;
+                if (code < 33) {
+                    len = ff_mvtab[code][1] + 1 + bit_size;
+                } else {
+                    len = 12 /* ff_mvtab[32][1] */ + av_log2(code>>5) + 2 + bit_size;
+                }
+            }
+
+            mv_penalty[f_code][mv + MAX_DMV] = len;
+        }
+    }
+
+    for (int mv = 0; mv < MAX_MV * 2 + 1; mv++)
+        umv_fcode_tab[mv]= 1;
+}
+
+static av_cold void init_uni_h263_rl_tab(const RLTable *rl, uint8_t *len_tab)
+{
+    av_assert0(MAX_LEVEL >= 64);
+    av_assert0(MAX_RUN   >= 63);
+
+    for (int slevel = -64; slevel < 64; slevel++) {
+        if (slevel == 0) continue;
+        for (int run = 0; run < 64; run++) {
+            for (int last = 0; last <= 1; last++) {
+                const int index = UNI_MPEG4_ENC_INDEX(last, run, slevel + 64);
+                int level = slevel < 0 ? -slevel : slevel;
+                int sign  = slevel < 0 ? 1 : 0;
+                int bits, len, code;
+
+                len_tab[index] = 100;
+
+                /* ESC0 */
+                code = get_rl_index(rl, last, run, level);
+                bits = rl->table_vlc[code][0];
+                len  = rl->table_vlc[code][1];
+                bits = bits * 2 + sign;
+                len++;
+
+                if (code != rl->n && len < len_tab[index])
+                    len_tab[index] = len;
+
+                /* ESC */
+                bits = rl->table_vlc[rl->n][0];
+                len  = rl->table_vlc[rl->n][1];
+                bits = bits *   2 + last; len++;
+                bits = bits *  64 + run;  len += 6;
+                bits = bits * 256 + (level & 0xff); len += 8;
+
+                if (len < len_tab[index])
+                    len_tab[index] = len;
+            }
+        }
+    }
+}
+
+static av_cold void h263_encode_init_static(void)
+{
+    static uint8_t rl_intra_table[2][2 * MAX_RUN + MAX_LEVEL + 3];
+
+    ff_rl_init(&ff_rl_intra_aic, rl_intra_table);
+    ff_h263_init_rl_inter();
+
+    init_uni_h263_rl_tab(&ff_rl_intra_aic,  uni_h263_intra_aic_rl_len);
+    init_uni_h263_rl_tab(&ff_h263_rl_inter, uni_h263_inter_rl_len);
+
+    init_mv_penalty_and_fcode();
+}
+
+av_cold const uint8_t (*ff_h263_get_mv_penalty(void))[MAX_DMV*2+1]
+{
+    static AVOnce init_static_once = AV_ONCE_INIT;
+
+    ff_thread_once(&init_static_once, h263_encode_init_static);
+
+    return mv_penalty;
+}
+
+void ff_h263_encode_motion(PutBitContext *pb, int val, int f_code)
+{
+    if (val == 0) {
+        /* zero vector -- corresponds to ff_mvtab[0] */
+        put_bits(pb, 1, 1);
+    } else {
+        int sign, code, bits;
+        int bit_size = f_code - 1;
+        int range = 1 << bit_size;
+        /* modulo encoding */
+        val = sign_extend(val, 6 + bit_size);
+        sign = val>>31;
+        val= (val^sign)-sign;
+        sign&=1;
+
+        val--;
+        code = (val >> bit_size) + 1;
+        bits = val & (range - 1);
+
+        put_bits(pb, ff_mvtab[code][1] + 1, (ff_mvtab[code][0] << 1) | sign);
+        if (bit_size > 0) {
+            put_bits(pb, bit_size, bits);
+        }
+    }
+}
+
+#if CONFIG_H263_ENCODER // Snow and SVQ1 need the above
 static const uint8_t wrong_run[102] = {
  1,  2,  3,  5,  4, 10,  9,  8,
 11, 15, 17, 16, 23, 22, 21, 20,
@@ -698,128 +819,9 @@ void ff_h263_update_mb(MpegEncContext *s)
     ff_h263_update_motion_val(s);
 }
 
-void ff_h263_encode_motion(PutBitContext *pb, int val, int f_code)
-{
-    int range, bit_size, sign, code, bits;
-
-    if (val == 0) {
-        /* zero vector -- corresponds to ff_mvtab[0] */
-        put_bits(pb, 1, 1);
-    } else {
-        bit_size = f_code - 1;
-        range = 1 << bit_size;
-        /* modulo encoding */
-        val = sign_extend(val, 6 + bit_size);
-        sign = val>>31;
-        val= (val^sign)-sign;
-        sign&=1;
-
-        val--;
-        code = (val >> bit_size) + 1;
-        bits = val & (range - 1);
-
-        put_bits(pb, ff_mvtab[code][1] + 1, (ff_mvtab[code][0] << 1) | sign);
-        if (bit_size > 0) {
-            put_bits(pb, bit_size, bits);
-        }
-    }
-}
-
-static av_cold void init_mv_penalty_and_fcode(void)
-{
-    int f_code;
-    int mv;
-
-    for(f_code=1; f_code<=MAX_FCODE; f_code++){
-        for(mv=-MAX_DMV; mv<=MAX_DMV; mv++){
-            int len;
-
-            if (mv==0) len = 1; // ff_mvtab[0][1]
-            else{
-                int val, bit_size, code;
-
-                bit_size = f_code - 1;
-
-                val=mv;
-                if (val < 0)
-                    val = -val;
-                val--;
-                code = (val >> bit_size) + 1;
-                if(code<33){
-                    len= ff_mvtab[code][1] + 1 + bit_size;
-                }else{
-                    len = 12 /* ff_mvtab[32][1] */ + av_log2(code>>5) + 2 + bit_size;
-                }
-            }
-
-            mv_penalty[f_code][mv+MAX_DMV]= len;
-        }
-    }
-
-    for(mv=0; mv<MAX_MV*2+1; mv++){
-        umv_fcode_tab[mv]= 1;
-    }
-}
-
-static av_cold void init_uni_h263_rl_tab(const RLTable *rl, uint8_t *len_tab)
-{
-    int slevel, run, last;
-
-    av_assert0(MAX_LEVEL >= 64);
-    av_assert0(MAX_RUN   >= 63);
-
-    for(slevel=-64; slevel<64; slevel++){
-        if(slevel==0) continue;
-        for(run=0; run<64; run++){
-            for(last=0; last<=1; last++){
-                const int index= UNI_MPEG4_ENC_INDEX(last, run, slevel+64);
-                int level= slevel < 0 ? -slevel : slevel;
-                int sign= slevel < 0 ? 1 : 0;
-                int bits, len, code;
-
-                len_tab[index]= 100;
-
-                /* ESC0 */
-                code= get_rl_index(rl, last, run, level);
-                bits= rl->table_vlc[code][0];
-                len=  rl->table_vlc[code][1];
-                bits=bits*2+sign; len++;
-
-                if (code != rl->n && len < len_tab[index])
-                    len_tab [index]= len;
-
-                /* ESC */
-                bits= rl->table_vlc[rl->n][0];
-                len = rl->table_vlc[rl->n][1];
-                bits=bits*2+last; len++;
-                bits=bits*64+run; len+=6;
-                bits=bits*256+(level&0xff); len+=8;
-
-                if (len < len_tab[index])
-                    len_tab [index]= len;
-            }
-        }
-    }
-}
-
-static av_cold void h263_encode_init_static(void)
-{
-    static uint8_t rl_intra_table[2][2 * MAX_RUN + MAX_LEVEL + 3];
-
-    ff_rl_init(&ff_rl_intra_aic, rl_intra_table);
-    ff_h263_init_rl_inter();
-
-    init_uni_h263_rl_tab(&ff_rl_intra_aic,  uni_h263_intra_aic_rl_len);
-    init_uni_h263_rl_tab(&ff_h263_rl_inter, uni_h263_inter_rl_len);
-
-    init_mv_penalty_and_fcode();
-}
-
 av_cold void ff_h263_encode_init(MpegEncContext *s)
 {
-    static AVOnce init_static_once = AV_ONCE_INIT;
-
-    s->me.mv_penalty= mv_penalty; // FIXME exact table for MSMPEG4 & H.263+
+    s->me.mv_penalty = ff_h263_get_mv_penalty(); // FIXME exact table for MSMPEG4 & H.263+
 
     s->intra_ac_vlc_length     =s->inter_ac_vlc_length     = uni_h263_inter_rl_len;
     s->intra_ac_vlc_last_length=s->inter_ac_vlc_last_length= uni_h263_inter_rl_len + 128*64;
@@ -862,11 +864,7 @@ av_cold void ff_h263_encode_init(MpegEncContext *s)
         s->max_qcoeff=  127;
     }
 
-#if CONFIG_H263_ENCODER // Snow and SVQ1 call this
     ff_h263dsp_init(&s->h263dsp);
-#endif
-
-    ff_thread_once(&init_static_once, h263_encode_init_static);
 }
 
 void ff_h263_encode_mba(MpegEncContext *s)
@@ -945,3 +943,4 @@ const FFCodec ff_h263p_encoder = {
     FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
 };
+#endif
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index 0623c9d196..5f539a57df 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -240,7 +240,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
         return AVERROR(ENOMEM);
     mpv->me.score_map = mpv->me.map + ME_MAP_SIZE;
 
-    ff_h263_encode_init(mpv); //mv_penalty
+    mpv->me.mv_penalty = ff_h263_get_mv_penalty();
 
     s->max_ref_frames = av_clip(avctx->refs, 1, MAX_REF_FRAMES);
 
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index d969be25c1..0d27a73500 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -631,7 +631,7 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx)
 
     ff_svq1enc_init(&s->svq1encdsp);
 
-    ff_h263_encode_init(&s->m); // mv_penalty
+    s->m.me.mv_penalty = ff_h263_get_mv_penalty();
 
     return write_ident(avctx, s->avctx->flags & AV_CODEC_FLAG_BITEXACT ? "Lavc" : LIBAVCODEC_IDENT);
 }
-- 
2.45.2


[-- Attachment #17: 0016-avcodec-ituh263enc-Use-memset-where-appropriate.patch --]
[-- Type: text/x-patch, Size: 1035 bytes --]

From 3ff3f93243eb7247242889fa0c45581021e6003b Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 22:45:57 +0100
Subject: [PATCH 16/45] avcodec/ituh263enc: Use memset where appropriate

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/ituh263enc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 8313b2c2c1..2d750439d1 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -30,6 +30,7 @@
 #include "config_components.h"
 
 #include <limits.h>
+#include <string.h>
 
 #include "libavutil/attributes.h"
 #include "libavutil/thread.h"
@@ -93,8 +94,7 @@ static av_cold void init_mv_penalty_and_fcode(void)
         }
     }
 
-    for (int mv = 0; mv < MAX_MV * 2 + 1; mv++)
-        umv_fcode_tab[mv]= 1;
+    memset(umv_fcode_tab, 1, sizeof(umv_fcode_tab));
 }
 
 static av_cold void init_uni_h263_rl_tab(const RLTable *rl, uint8_t *len_tab)
-- 
2.45.2


[-- Attachment #18: 0017-avcodec-flvenc-Remove-redundant-setting-of-dc_scale_.patch --]
[-- Type: text/x-patch, Size: 1474 bytes --]

From 1ea16b2a26a70863f9e7391520affcb260a46e32 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 20:09:58 +0100
Subject: [PATCH 17/45] avcodec/flvenc: Remove redundant setting of
 dc_scale_tables

h263_aic is always zero for FLV and ff_mpeg1_dc_scale_table
is already the default dc_scale table for both y and c.
h263_aic is also always zero for the FLV decoder.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/flvenc.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/libavcodec/flvenc.c b/libavcodec/flvenc.c
index cbe3b7f056..192c2a929f 100644
--- a/libavcodec/flvenc.c
+++ b/libavcodec/flvenc.c
@@ -20,9 +20,7 @@
 
 #include "codec_internal.h"
 #include "flvenc.h"
-#include "h263data.h"
 #include "mpegvideo.h"
-#include "mpegvideodata.h"
 #include "mpegvideoenc.h"
 
 void ff_flv_encode_picture_header(MpegEncContext *s)
@@ -63,14 +61,6 @@ void ff_flv_encode_picture_header(MpegEncContext *s)
     put_bits(&s->pb, 1, 1);   /* DeblockingFlag: on */
     put_bits(&s->pb, 5, s->qscale);   /* Quantizer */
     put_bits(&s->pb, 1, 0);   /* ExtraInformation */
-
-    if (s->h263_aic) {
-        s->y_dc_scale_table =
-        s->c_dc_scale_table = ff_aic_dc_scale_table;
-    } else {
-        s->y_dc_scale_table =
-        s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
-    }
 }
 
 void ff_flv2_encode_ac_esc(PutBitContext *pb, int slevel, int level,
-- 
2.45.2


[-- Attachment #19: 0018-avcodec-ituh263dec-Reorder-branches.patch --]
[-- Type: text/x-patch, Size: 1499 bytes --]

From 9621b803454b15f880835e305d3ac77fae17e3fc Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 2 Mar 2025 23:02:26 +0100
Subject: [PATCH 18/45] avcodec/ituh263dec: Reorder branches

(To perform this optimization a compiler would have to look
at both ff_rv_decode_dc() and av_log(). The latter seems very
unlikely.)

Reviewed-by: Ramiro Polla <ramiro.polla@gmail.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/ituh263dec.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c
index e0f3034e57..9fee33da71 100644
--- a/libavcodec/ituh263dec.c
+++ b/libavcodec/ituh263dec.c
@@ -541,6 +541,8 @@ static int h263_decode_block(MpegEncContext * s, int16_t * block,
 
     scan_table = s->intra_scantable.permutated;
     if (s->h263_aic && s->mb_intra) {
+        if (!coded)
+            goto not_coded;
         rl = &ff_rl_intra_aic;
         i = 0;
         if (s->ac_pred) {
@@ -587,8 +589,6 @@ static int h263_decode_block(MpegEncContext * s, int16_t * block,
         i = 0;
     }
     if (!coded) {
-        if (s->mb_intra && s->h263_aic)
-            goto not_coded;
         s->block_last_index[n] = i - 1;
         return 0;
     }
@@ -669,8 +669,8 @@ retry:
         block[j] = level;
     }
     }
-not_coded:
     if (s->mb_intra && s->h263_aic) {
+not_coded:
         h263_pred_acdc(s, block, n);
         i = 63;
     }
-- 
2.45.2


[-- Attachment #20: 0019-avcodec-mpeg4videodec-Bail-out-earlier-when-parsing.patch --]
[-- Type: text/x-patch, Size: 1907 bytes --]

From 148797d3d933dc2e0d778c4a89eb58dde9665b25 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 2 Mar 2025 23:09:39 +0100
Subject: [PATCH 19/45] avcodec/mpeg4videodec: Bail out earlier when parsing

The scantables are unused for the parser (and in fact
the IDCT permutation used has not been initialized at all).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg4videodec.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index eace43b4cb..2a340ea682 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -3250,6 +3250,12 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb,
         } else
             s->alternate_scan = 0;
     }
+    /* Skip at this point when only parsing since the remaining
+     * data is not useful for a parser and requires the
+     * sprite_trajectory VLC to be initialized. */
+    if (parse_only)
+        goto end;
+
     if (s->alternate_scan) {
         ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable,   ff_alternate_vertical_scan);
         ff_permute_scantable(s->permutated_intra_h_scantable, ff_alternate_vertical_scan,
@@ -3262,12 +3268,6 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb,
     ff_permute_scantable(s->permutated_intra_v_scantable, ff_alternate_vertical_scan,
                          s->idsp.idct_permutation);
 
-    /* Skip at this point when only parsing since the remaining
-     * data is not useful for a parser and requires the
-     * sprite_trajectory VLC to be initialized. */
-    if (parse_only)
-        goto end;
-
     if (s->pict_type == AV_PICTURE_TYPE_S) {
         if((ctx->vol_sprite_usage == STATIC_SPRITE ||
             ctx->vol_sprite_usage == GMC_SPRITE)) {
-- 
2.45.2


[-- Attachment #21: 0020-avcodec-mpeg4video-Split-ff_mpeg4_pred_dc.patch --]
[-- Type: text/x-patch, Size: 7713 bytes --]

From b8f3a569e7a320cb17d053e6b44db727fa32ff03 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 00:21:04 +0100
Subject: [PATCH 20/45] avcodec/mpeg4video: Split ff_mpeg4_pred_dc()

It currently does two things: a) Get a prediction for the dc
and the dc direction and b) process said prediction. Processing
the prediction differs for encoding (getting a diff) and decoding
(getting the level via diff+prediction). So having a common function
performing b) makes no sense.

Even worse, there is a decoding mode where the dc coefficient (diff)
is not coded specially and therefore unavailable before entering
the block decoding loop, so that one can only perform a). Before
this commit, the decoder simply called ff_mpeg4_pred_dc() twice;
the results of the b) part of the call before the loop were ignored
(but the compiler could not elide them because they involved error
messages) and a) was also performed twice.

This commit changes this by splitting b) out of ff_mpeg4_pred_dc()
and moving this code to decoder and encoder.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg4video.h    | 47 ++++---------------------------------
 libavcodec/mpeg4videodec.c | 48 ++++++++++++++++++++++++++++++++++----
 libavcodec/mpeg4videoenc.c | 10 ++++++--
 3 files changed, 55 insertions(+), 50 deletions(-)

diff --git a/libavcodec/mpeg4video.h b/libavcodec/mpeg4video.h
index 29b11eb92e..9ac18943a2 100644
--- a/libavcodec/mpeg4video.h
+++ b/libavcodec/mpeg4video.h
@@ -44,24 +44,15 @@ int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my);
 
 /**
  * Predict the dc.
- * encoding quantized level -> quantized diff
- * decoding quantized diff -> quantized level
  * @param n block index (0-3 are luma, 4-5 are chroma)
  * @param dir_ptr pointer to an integer where the prediction direction will be stored
  */
-static inline int ff_mpeg4_pred_dc(MpegEncContext *s, int n, int level,
-                                   int *dir_ptr, int encoding)
+static inline int ff_mpeg4_pred_dc(MpegEncContext *s, int n, int *dir_ptr)
 {
-    int a, b, c, wrap, pred, scale, ret;
-    int16_t *dc_val;
+    int a, b, c, wrap, pred;
+    const int16_t *dc_val;
 
     /* find prediction */
-    if (n < 4)
-        scale = s->y_dc_scale;
-    else
-        scale = s->c_dc_scale;
-    if (IS_3IV1)
-        scale = 8;
 
     wrap   = s->block_wrap[n];
     dc_val = s->dc_val[0] + s->block_index[n];
@@ -93,37 +84,7 @@ static inline int ff_mpeg4_pred_dc(MpegEncContext *s, int n, int level,
         pred     = a;
         *dir_ptr = 0; /* left */
     }
-    /* we assume pred is positive */
-    pred = FASTDIV((pred + (scale >> 1)), scale);
-
-    if (encoding) {
-        ret = level - pred;
-    } else {
-        level += pred;
-        ret    = level;
-    }
-    level *= scale;
-    if (level & (~2047)) {
-        if (!s->encoding && (s->avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_AGGRESSIVE))) {
-            if (level < 0) {
-                av_log(s->avctx, AV_LOG_ERROR,
-                       "dc<0 at %dx%d\n", s->mb_x, s->mb_y);
-                return AVERROR_INVALIDDATA;
-            }
-            if (level > 2048 + scale) {
-                av_log(s->avctx, AV_LOG_ERROR,
-                       "dc overflow at %dx%d\n", s->mb_x, s->mb_y);
-                return AVERROR_INVALIDDATA;
-            }
-        }
-        if (level < 0)
-            level = 0;
-        else if (!(s->workaround_bugs & FF_BUG_DC_CLIP))
-            level = 2047;
-    }
-    dc_val[0] = level;
-
-    return ret;
+    return pred;
 }
 
 #endif /* AVCODEC_MPEG4VIDEO_H */
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 2a340ea682..31d00dd0b9 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -880,6 +880,43 @@ static inline int get_amv(Mpeg4DecContext *ctx, int n)
     return sum;
 }
 
+static inline int mpeg4_get_level_dc(MpegEncContext *s, int n, int pred, int level)
+{
+    int scale = n < 4 ? s->y_dc_scale : s->c_dc_scale;
+    int ret;
+
+    if (IS_3IV1)
+        scale = 8;
+
+    /* we assume pred is positive */
+    pred = FASTDIV((pred + (scale >> 1)), scale);
+
+    level += pred;
+    ret    = level;
+    level *= scale;
+    if (level & (~2047)) {
+        if (s->avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_AGGRESSIVE)) {
+            if (level < 0) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "dc<0 at %dx%d\n", s->mb_x, s->mb_y);
+                return AVERROR_INVALIDDATA;
+            }
+            if (level > 2048 + scale) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "dc overflow at %dx%d\n", s->mb_x, s->mb_y);
+                return AVERROR_INVALIDDATA;
+            }
+        }
+        if (level < 0)
+            level = 0;
+        else if (!(s->workaround_bugs & FF_BUG_DC_CLIP))
+            level = 2047;
+    }
+    s->dc_val[0][s->block_index[n]] = level;
+
+    return ret;
+}
+
 /**
  * Decode the dc value.
  * @param n block index (0-3 are luma, 4-5 are chroma)
@@ -888,7 +925,7 @@ static inline int get_amv(Mpeg4DecContext *ctx, int n)
  */
 static inline int mpeg4_decode_dc(MpegEncContext *s, int n, int *dir_ptr)
 {
-    int level, code;
+    int level, code, pred;
 
     if (n < 4)
         code = get_vlc2(&s->gb, dc_lum, DC_VLC_BITS, 1);
@@ -926,7 +963,8 @@ static inline int mpeg4_decode_dc(MpegEncContext *s, int n, int *dir_ptr)
         }
     }
 
-    return ff_mpeg4_pred_dc(s, n, level, dir_ptr, 0);
+    pred = ff_mpeg4_pred_dc(s, n, dir_ptr);
+    return mpeg4_get_level_dc(s, n, pred, level);
 }
 
 /**
@@ -1290,7 +1328,7 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block,
                                      int use_intra_dc_vlc, int rvlc)
 {
     MpegEncContext *s = &ctx->m;
-    int level, i, last, run, qmul, qadd;
+    int level, i, last, run, qmul, qadd, pred;
     int av_uninit(dc_pred_dir);
     const RLTable *rl;
     const RL_VLC_ELEM *rl_vlc;
@@ -1317,7 +1355,7 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block,
             i        = 0;
         } else {
             i = -1;
-            ff_mpeg4_pred_dc(s, n, 0, &dc_pred_dir, 0);
+            pred = ff_mpeg4_pred_dc(s, n, &dc_pred_dir);
         }
         if (!coded)
             goto not_coded;
@@ -1540,7 +1578,7 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block,
 not_coded:
     if (intra) {
         if (!use_intra_dc_vlc) {
-            block[0] = ff_mpeg4_pred_dc(s, n, block[0], &dc_pred_dir, 0);
+            block[0] = mpeg4_get_level_dc(s, n, pred, block[0]);
 
             i -= i >> 31;  // if (i == -1) i = 0;
         }
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 64fb96a0cf..26f9b40ff7 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -806,8 +806,14 @@ void ff_mpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64],
         const uint8_t *scan_table[6];
         int i;
 
-        for (i = 0; i < 6; i++)
-            dc_diff[i] = ff_mpeg4_pred_dc(s, i, block[i][0], &dir[i], 1);
+        for (int i = 0; i < 6; i++) {
+            int pred  = ff_mpeg4_pred_dc(s, i, &dir[i]);
+            int scale = i < 4 ? s->y_dc_scale : s->c_dc_scale;
+
+            pred = FASTDIV((pred + (scale >> 1)), scale);
+            dc_diff[i] = block[i][0] - pred;
+            s->dc_val[0][s->block_index[i]] = av_clip_uintp2(block[i][0] * scale, 11);
+        }
 
         if (s->avctx->flags & AV_CODEC_FLAG_AC_PRED) {
             s->ac_pred = decide_ac_pred(s, block, dir, scan_table, zigzag_last_index);
-- 
2.45.2


[-- Attachment #22: 0021-avcodec-mpeg4video-Move-IS_3IV1-macro-to-mpeg4videod.patch --]
[-- Type: text/x-patch, Size: 1672 bytes --]

From 26bfad1b45e9d7e8f6e6747dab4159c771fadc7b Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 01:12:02 +0100
Subject: [PATCH 21/45] avcodec/mpeg4video: Move IS_3IV1 macro to
 mpeg4videodec.c

Also make the macro safer by adding parentheses the replacement.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg4video.h    | 6 ------
 libavcodec/mpeg4videodec.c | 6 ++++++
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/libavcodec/mpeg4video.h b/libavcodec/mpeg4video.h
index 9ac18943a2..cfc6dcb684 100644
--- a/libavcodec/mpeg4video.h
+++ b/libavcodec/mpeg4video.h
@@ -36,12 +36,6 @@ void ff_mpeg4_init_direct_mv(MpegEncContext *s);
  */
 int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my);
 
-#if 0 //3IV1 is quite rare and it slows things down a tiny bit
-#define IS_3IV1 s->codec_tag == AV_RL32("3IV1")
-#else
-#define IS_3IV1 0
-#endif
-
 /**
  * Predict the dc.
  * @param n block index (0-3 are luma, 4-5 are chroma)
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 31d00dd0b9..139b6d4b08 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -49,6 +49,12 @@
 #include "xvididct.h"
 #include "unary.h"
 
+#if 0 //3IV1 is quite rare and it slows things down a tiny bit
+#define IS_3IV1 (s->codec_tag == AV_RL32("3IV1"))
+#else
+#define IS_3IV1 0
+#endif
+
 /* The defines below define the number of bits that are read at once for
  * reading vlc values. Changing these may improve speed and data cache needs
  * be aware though that decreasing them may need the number of stages that is
-- 
2.45.2


[-- Attachment #23: 0022-avcodec-mpegvideo_enc-Only-allocate-chroma-intra-mat.patch --]
[-- Type: text/x-patch, Size: 3113 bytes --]

From b426c542f537d31e5e31ea14d728cf290b054e78 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 27 Feb 2025 19:01:03 +0100
Subject: [PATCH 22/45] avcodec/mpegvideo_enc: Only allocate chroma intra
 matrices when needed

Also start factoring the matrix-init code out into a function
of its own to declutter ff_mpv_encode_init().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 27 ++++++++++++++++++---------
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 1fe69f89a6..79d6bfc056 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -348,6 +348,20 @@ static av_cold int me_cmp_init(MpegEncContext *s, AVCodecContext *avctx)
     return 0;
 }
 
+static av_cold int init_matrices(MpegEncContext *s, AVCodecContext *avctx)
+{
+    if (s->out_format == FMT_MJPEG) {
+        if (!FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix,   32) ||
+            !FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix16, 32))
+            return AVERROR(ENOMEM);
+    } else {
+        s->q_chroma_intra_matrix   = s->q_intra_matrix;
+        s->q_chroma_intra_matrix16 = s->q_intra_matrix16;
+    }
+
+    return 0;
+}
+
 /* init video encoder */
 av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 {
@@ -866,10 +880,8 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 
     if (!(avctx->stats_out = av_mallocz(256))               ||
         !FF_ALLOCZ_TYPED_ARRAY(s->q_intra_matrix,          32) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix,   32) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->q_inter_matrix,          32) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->q_intra_matrix16,        32) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix16, 32) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->q_inter_matrix16,        32) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->input_picture,           MAX_B_FRAMES + 1) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->reordered_input_picture, MAX_B_FRAMES + 1) ||
@@ -877,6 +889,10 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         !(s->picture_pool = ff_mpv_alloc_pic_pool(0)))
         return AVERROR(ENOMEM);
 
+    ret = init_matrices(s, avctx);
+    if (ret < 0)
+        return ret;
+
     /* Allocate MV tables; the MV and MB tables will be copied
      * to slice contexts by ff_update_duplicate_context().  */
     mv_table_size = (s->mb_height + 2) * s->mb_stride + 1;
@@ -3700,13 +3716,6 @@ static int encode_picture(MpegEncContext *s, const AVPacket *pkt)
         update_qscale(s);
     }
 
-    if (s->out_format != FMT_MJPEG) {
-        if(s->q_chroma_intra_matrix   != s->q_intra_matrix  ) av_freep(&s->q_chroma_intra_matrix);
-        if(s->q_chroma_intra_matrix16 != s->q_intra_matrix16) av_freep(&s->q_chroma_intra_matrix16);
-        s->q_chroma_intra_matrix   = s->q_intra_matrix;
-        s->q_chroma_intra_matrix16 = s->q_intra_matrix16;
-    }
-
     ff_me_init_pic(s);
 
     s->mb_intra=0; //for the rate distortion & bit compare functions
-- 
2.45.2


[-- Attachment #24: 0023-avcodec-mpegvideo_enc-Set-chroma_intra_matrix-for-Sp.patch --]
[-- Type: text/x-patch, Size: 1426 bytes --]

From d806e0cab5baf5ff2ba9ebdb84579fe9d1e31ca5 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 27 Feb 2025 21:13:03 +0100
Subject: [PATCH 23/45] avcodec/mpegvideo_enc: Set chroma_intra_matrix for
 SpeedHQ

Used with trellis; notice that inter_matrix is unused for
(intra-only) SpeedHQ, so it is irrelevant that its value changes.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 79d6bfc056..11ebbe6a30 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -992,11 +992,8 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) {
             s->intra_matrix[j] =
             s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i];
-        } else if (CONFIG_SPEEDHQ_ENCODER && s->codec_id == AV_CODEC_ID_SPEEDHQ) {
-            s->intra_matrix[j] =
-            s->inter_matrix[j] = ff_mpeg1_default_intra_matrix[i];
         } else {
-            /* MPEG-1/2 */
+            /* MPEG-1/2, SpeedHQ */
             s->chroma_intra_matrix[j] =
             s->intra_matrix[j] = ff_mpeg1_default_intra_matrix[i];
             s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i];
-- 
2.45.2


[-- Attachment #25: 0024-avcodec-mpegvideo_enc-Factor-checks-out-of-loop.patch --]
[-- Type: text/x-patch, Size: 3364 bytes --]

From db5466d8d607b8b9d4eca16fd6b8800b447284ec Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 27 Feb 2025 22:01:12 +0100
Subject: [PATCH 24/45] avcodec/mpegvideo_enc: Factor checks out of loop

Also move this code to handle_matrices().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 49 +++++++++++++++++++++-----------------
 1 file changed, 27 insertions(+), 22 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 11ebbe6a30..aab82248e0 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -350,6 +350,8 @@ static av_cold int me_cmp_init(MpegEncContext *s, AVCodecContext *avctx)
 
 static av_cold int init_matrices(MpegEncContext *s, AVCodecContext *avctx)
 {
+    const uint16_t *intra_matrix, *inter_matrix;
+
     if (s->out_format == FMT_MJPEG) {
         if (!FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix,   32) ||
             !FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix16, 32))
@@ -359,6 +361,31 @@ static av_cold int init_matrices(MpegEncContext *s, AVCodecContext *avctx)
         s->q_chroma_intra_matrix16 = s->q_intra_matrix16;
     }
 
+    if (CONFIG_MPEG4_ENCODER && s->codec_id == AV_CODEC_ID_MPEG4 &&
+        s->mpeg_quant) {
+        intra_matrix = ff_mpeg4_default_intra_matrix;
+        inter_matrix = ff_mpeg4_default_non_intra_matrix;
+    } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) {
+        intra_matrix =
+        inter_matrix = ff_mpeg1_default_non_intra_matrix;
+    } else {
+        /* MPEG-1/2, SpeedHQ */
+        intra_matrix = ff_mpeg1_default_intra_matrix;
+        inter_matrix = ff_mpeg1_default_non_intra_matrix;
+    }
+    if (avctx->intra_matrix)
+        intra_matrix = avctx->intra_matrix;
+    if (avctx->inter_matrix)
+        inter_matrix = avctx->inter_matrix;
+
+    /* init q matrix */
+    for (int i = 0; i < 64; i++) {
+        int j = s->idsp.idct_permutation[i];
+
+        s->intra_matrix[j] = s->chroma_intra_matrix[j] = intra_matrix[i];
+        s->inter_matrix[j] = inter_matrix[i];
+    }
+
     return 0;
 }
 
@@ -982,28 +1009,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 #endif
     }
 
-    /* init q matrix */
-    for (i = 0; i < 64; i++) {
-        int j = s->idsp.idct_permutation[i];
-        if (CONFIG_MPEG4_ENCODER && s->codec_id == AV_CODEC_ID_MPEG4 &&
-            s->mpeg_quant) {
-            s->intra_matrix[j] = ff_mpeg4_default_intra_matrix[i];
-            s->inter_matrix[j] = ff_mpeg4_default_non_intra_matrix[i];
-        } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) {
-            s->intra_matrix[j] =
-            s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i];
-        } else {
-            /* MPEG-1/2, SpeedHQ */
-            s->chroma_intra_matrix[j] =
-            s->intra_matrix[j] = ff_mpeg1_default_intra_matrix[i];
-            s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i];
-        }
-        if (avctx->intra_matrix)
-            s->intra_matrix[j] = avctx->intra_matrix[i];
-        if (avctx->inter_matrix)
-            s->inter_matrix[j] = avctx->inter_matrix[i];
-    }
-
     /* precompute matrix */
     /* for mjpeg, we do include qscale in the matrix */
     if (s->out_format != FMT_MJPEG) {
-- 
2.45.2


[-- Attachment #26: 0025-avcodec-mpegvideo_enc-Only-allocate-inter-matrices-w.patch --]
[-- Type: text/x-patch, Size: 4132 bytes --]

From 560d3cb87d029c55ce1e65144bc2d017ba15bdb7 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 27 Feb 2025 22:29:58 +0100
Subject: [PATCH 25/45] avcodec/mpegvideo_enc: Only allocate inter matrices
 when needed

Also allocate them jointly with intra matrices when needed.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index aab82248e0..e4b89983ad 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -348,18 +348,27 @@ static av_cold int me_cmp_init(MpegEncContext *s, AVCodecContext *avctx)
     return 0;
 }
 
+#define ALLOCZ_ARRAYS(p, mult, numb) ((p) = av_calloc(numb, mult * sizeof(*(p))))
 static av_cold int init_matrices(MpegEncContext *s, AVCodecContext *avctx)
 {
+    const int nb_matrices = 1 + (s->out_format == FMT_MJPEG) + !s->intra_only;
     const uint16_t *intra_matrix, *inter_matrix;
 
+    if (!ALLOCZ_ARRAYS(s->q_intra_matrix,   32, nb_matrices) ||
+        !ALLOCZ_ARRAYS(s->q_intra_matrix16, 32, nb_matrices))
+        return AVERROR(ENOMEM);
+
     if (s->out_format == FMT_MJPEG) {
-        if (!FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix,   32) ||
-            !FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix16, 32))
-            return AVERROR(ENOMEM);
+        s->q_chroma_intra_matrix   = s->q_intra_matrix   + 32;
+        s->q_chroma_intra_matrix16 = s->q_intra_matrix16 + 32;
     } else {
         s->q_chroma_intra_matrix   = s->q_intra_matrix;
         s->q_chroma_intra_matrix16 = s->q_intra_matrix16;
     }
+    if (!s->intra_only) {
+        s->q_inter_matrix   = s->q_intra_matrix   + 32;
+        s->q_inter_matrix16 = s->q_intra_matrix16 + 32;
+    }
 
     if (CONFIG_MPEG4_ENCODER && s->codec_id == AV_CODEC_ID_MPEG4 &&
         s->mpeg_quant) {
@@ -906,10 +915,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         return ret;
 
     if (!(avctx->stats_out = av_mallocz(256))               ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->q_intra_matrix,          32) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->q_inter_matrix,          32) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->q_intra_matrix16,        32) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->q_inter_matrix16,        32) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->input_picture,           MAX_B_FRAMES + 1) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->reordered_input_picture, MAX_B_FRAMES + 1) ||
         !(s->new_pic = av_frame_alloc()) ||
@@ -948,7 +953,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         !(s->mb_mean = av_mallocz(mb_array_size)))
         return AVERROR(ENOMEM);
 
-#define ALLOCZ_ARRAYS(p, mult, numb) ((p) = av_calloc(numb, mult * sizeof(*(p))))
     if (s->codec_id == AV_CODEC_ID_MPEG4 ||
         (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
         int16_t (*tmp1)[2];
@@ -1019,6 +1023,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         ff_convert_matrix(s, s->q_intra_matrix, s->q_intra_matrix16,
                           s->intra_matrix, s->intra_quant_bias, avctx->qmin,
                           31, 1);
+        if (s->q_inter_matrix)
         ff_convert_matrix(s, s->q_inter_matrix, s->q_inter_matrix16,
                           s->inter_matrix, s->inter_quant_bias, avctx->qmin,
                           31, 0);
@@ -1093,14 +1098,8 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
     av_freep(&s->cplx_tab);
     av_freep(&s->bits_tab);
 
-    if(s->q_chroma_intra_matrix   != s->q_intra_matrix  ) av_freep(&s->q_chroma_intra_matrix);
-    if(s->q_chroma_intra_matrix16 != s->q_intra_matrix16) av_freep(&s->q_chroma_intra_matrix16);
-    s->q_chroma_intra_matrix=   NULL;
-    s->q_chroma_intra_matrix16= NULL;
     av_freep(&s->q_intra_matrix);
-    av_freep(&s->q_inter_matrix);
     av_freep(&s->q_intra_matrix16);
-    av_freep(&s->q_inter_matrix16);
     av_freep(&s->input_picture);
     av_freep(&s->reordered_input_picture);
     av_freep(&s->dct_offset);
-- 
2.45.2


[-- Attachment #27: 0026-avcodec-mpegvideo_enc-Don-t-init-matrices-unnecessar.patch --]
[-- Type: text/x-patch, Size: 1190 bytes --]

From 785bbc2bf3a3fad3738f28e1b60a61f297a94d63 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 27 Feb 2025 22:44:21 +0100
Subject: [PATCH 26/45] avcodec/mpegvideo_enc: Don't init matrices
 unnecessarily for MJPEG

The MJPEG initialization happens later.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index e4b89983ad..81e004d1a8 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -361,6 +361,10 @@ static av_cold int init_matrices(MpegEncContext *s, AVCodecContext *avctx)
     if (s->out_format == FMT_MJPEG) {
         s->q_chroma_intra_matrix   = s->q_intra_matrix   + 32;
         s->q_chroma_intra_matrix16 = s->q_intra_matrix16 + 32;
+        // No need to set q_inter_matrix
+        av_assert1(s->intra_only);
+        // intra_matrix, chroma_intra_matrix will be set later for MJPEG.
+        return 0;
     } else {
         s->q_chroma_intra_matrix   = s->q_intra_matrix;
         s->q_chroma_intra_matrix16 = s->q_intra_matrix16;
-- 
2.45.2


[-- Attachment #28: 0027-avcodec-mpegvideo_enc-Move-q_matrix-init-to-init_mat.patch --]
[-- Type: text/x-patch, Size: 2561 bytes --]

From 2d01c382ed6b9848491c4bd7110e41bf0106c759 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 27 Feb 2025 22:56:59 +0100
Subject: [PATCH 27/45] avcodec/mpegvideo_enc: Move q_matrix init to
 init_matrices()

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 30 ++++++++++++++----------------
 1 file changed, 14 insertions(+), 16 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 81e004d1a8..5eea676dd4 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -353,6 +353,7 @@ static av_cold int init_matrices(MpegEncContext *s, AVCodecContext *avctx)
 {
     const int nb_matrices = 1 + (s->out_format == FMT_MJPEG) + !s->intra_only;
     const uint16_t *intra_matrix, *inter_matrix;
+    int ret;
 
     if (!ALLOCZ_ARRAYS(s->q_intra_matrix,   32, nb_matrices) ||
         !ALLOCZ_ARRAYS(s->q_intra_matrix16, 32, nb_matrices))
@@ -399,6 +400,19 @@ static av_cold int init_matrices(MpegEncContext *s, AVCodecContext *avctx)
         s->inter_matrix[j] = inter_matrix[i];
     }
 
+    /* precompute matrix */
+    ret = ff_check_codec_matrices(avctx, FF_MATRIX_TYPE_INTRA | FF_MATRIX_TYPE_INTER, 1, 255);
+    if (ret < 0)
+        return ret;
+
+    ff_convert_matrix(s, s->q_intra_matrix, s->q_intra_matrix16,
+                      s->intra_matrix, s->intra_quant_bias, avctx->qmin,
+                      31, 1);
+    if (s->q_inter_matrix)
+        ff_convert_matrix(s, s->q_inter_matrix, s->q_inter_matrix16,
+                          s->inter_matrix, s->inter_quant_bias, avctx->qmin,
+                          31, 0);
+
     return 0;
 }
 
@@ -1017,22 +1031,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 #endif
     }
 
-    /* precompute matrix */
-    /* for mjpeg, we do include qscale in the matrix */
-    if (s->out_format != FMT_MJPEG) {
-        ret = ff_check_codec_matrices(avctx, FF_MATRIX_TYPE_INTRA | FF_MATRIX_TYPE_INTER, 1, 255);
-        if (ret < 0)
-            return ret;
-
-        ff_convert_matrix(s, s->q_intra_matrix, s->q_intra_matrix16,
-                          s->intra_matrix, s->intra_quant_bias, avctx->qmin,
-                          31, 1);
-        if (s->q_inter_matrix)
-        ff_convert_matrix(s, s->q_inter_matrix, s->q_inter_matrix16,
-                          s->inter_matrix, s->inter_quant_bias, avctx->qmin,
-                          31, 0);
-    }
-
     if ((ret = ff_rate_control_init(s)) < 0)
         return ret;
 
-- 
2.45.2


[-- Attachment #29: 0028-avcodec-mpegvideo_enc-Move-q_scale_type-check-to-mpe.patch --]
[-- Type: text/x-patch, Size: 1914 bytes --]

From e98475e365b280167dee63354bb52471b851c5dc Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 28 Feb 2025 00:05:28 +0100
Subject: [PATCH 28/45] avcodec/mpegvideo_enc: Move q_scale_type check to
 mpeg12enc.c

The MPEG-2 encoder is the only encoder supporting q_scale_type.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12enc.c     | 8 ++++++++
 libavcodec/mpegvideo_enc.c | 8 --------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 52264ac6a0..90baf1ed95 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -201,6 +201,14 @@ static av_cold int encode_init(AVCodecContext *avctx)
         }
     }
 
+    if (mpeg12->mpeg.q_scale_type == 1) {
+        if (avctx->qmax > 28) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "non linear quant only supports qmax <= 28 currently\n");
+            return AVERROR_PATCHWELCOME;
+        }
+    }
+
     if (avctx->profile == AV_PROFILE_UNKNOWN) {
         if (avctx->level != AV_LEVEL_UNKNOWN) {
             av_log(avctx, AV_LOG_ERROR, "Set profile and level\n");
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 5eea676dd4..da9247ec25 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -705,14 +705,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         }
     }
 
-    if (s->q_scale_type == 1) {
-        if (avctx->qmax > 28) {
-            av_log(avctx, AV_LOG_ERROR,
-                   "non linear quant only supports qmax <= 28 currently\n");
-            return AVERROR_PATCHWELCOME;
-        }
-    }
-
     if (avctx->slices > 1 &&
         !(avctx->codec->capabilities & AV_CODEC_CAP_SLICE_THREADS)) {
         av_log(avctx, AV_LOG_ERROR, "Multiple slices are not supported by this codec\n");
-- 
2.45.2


[-- Attachment #30: 0029-avcodec-mpegvideo_enc-Move-vbv_delay-warning-to-mpeg.patch --]
[-- Type: text/x-patch, Size: 2283 bytes --]

From 6b08da6215a5b5094e486805d819af22c2e188cc Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 28 Feb 2025 00:46:23 +0100
Subject: [PATCH 29/45] avcodec/mpegvideo_enc: Move vbv_delay warning to
 mpeg12enc.c

It is MPEG-1/2 only.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12enc.c     |  9 +++++++++
 libavcodec/mpegvideo_enc.c | 11 -----------
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 90baf1ed95..3f23045afc 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -255,6 +255,15 @@ static av_cold int encode_init(AVCodecContext *avctx)
         }
     }
 
+    if (avctx->rc_max_rate &&
+        avctx->rc_min_rate == avctx->rc_max_rate &&
+        90000LL * (avctx->rc_buffer_size - 1) >
+            avctx->rc_max_rate * 0xFFFFLL) {
+        av_log(avctx, AV_LOG_INFO,
+               "Warning vbv_delay will be set to 0xFFFF (=VBR) as the "
+               "specified vbv buffer is too large for the given bitrate!\n");
+    }
+
     if (mpeg12->drop_frame_timecode)
         mpeg12->tc.flags |= AV_TIMECODE_FLAG_DROPFRAME;
     if (mpeg12->drop_frame_timecode && mpeg12->frame_rate_index != 4) {
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index da9247ec25..cbfea534d9 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -588,17 +588,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
             avctx->bit_rate_tolerance = INT_MAX;
     }
 
-    if (avctx->rc_max_rate &&
-        avctx->rc_min_rate == avctx->rc_max_rate &&
-        (s->codec_id == AV_CODEC_ID_MPEG1VIDEO ||
-         s->codec_id == AV_CODEC_ID_MPEG2VIDEO) &&
-        90000LL * (avctx->rc_buffer_size - 1) >
-            avctx->rc_max_rate * 0xFFFFLL) {
-        av_log(avctx, AV_LOG_INFO,
-               "Warning vbv_delay will be set to 0xFFFF (=VBR) as the "
-               "specified vbv buffer is too large for the given bitrate!\n");
-    }
-
     if ((avctx->flags & AV_CODEC_FLAG_4MV) && s->codec_id != AV_CODEC_ID_MPEG4 &&
         s->codec_id != AV_CODEC_ID_H263 && s->codec_id != AV_CODEC_ID_H263P &&
         s->codec_id != AV_CODEC_ID_FLV1) {
-- 
2.45.2


[-- Attachment #31: 0030-avcodec-mpegvideo_enc-Move-H.263-specific-check-to-i.patch --]
[-- Type: text/x-patch, Size: 1472 bytes --]

From d7bb6dd88c5c6dea6b35b6ef73e72245e9b5e346 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 1 Mar 2025 21:05:59 +0100
Subject: [PATCH 30/45] avcodec/mpegvideo_enc: Move H.263 specific check to
 ituh263enc.c

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/ituh263enc.c    | 3 +++
 libavcodec/mpegvideo_enc.c | 3 ---
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 2d750439d1..5beb857a6e 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -834,6 +834,9 @@ av_cold void ff_h263_encode_init(MpegEncContext *s)
     }
     s->ac_esc_length= 7+1+6+8;
 
+    if (s->modified_quant)
+        s->chroma_qscale_table = ff_h263_chroma_qscale_table;
+
     // use fcodes >1 only for MPEG-4 & H.263 & H.263+ FIXME
     switch(s->codec_id){
     case AV_CODEC_ID_MPEG4:
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index cbfea534d9..656d312d28 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -994,9 +994,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         s->dct_unquantize_inter = s->dct_unquantize_mpeg1_inter;
     }
 
-    if ((CONFIG_H263P_ENCODER || CONFIG_RV20_ENCODER) && s->modified_quant)
-        s->chroma_qscale_table = ff_h263_chroma_qscale_table;
-
     if (s->slice_context_count > 1) {
         s->rtp_mode = 1;
 
-- 
2.45.2


[-- Attachment #32: 0031-avcodec-mpegvideo-Move-ratecontrol-only-options-to-R.patch --]
[-- Type: text/x-patch, Size: 11146 bytes --]

From 7131325b69fc6b36f99a3e7764afe291f726ba3f Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 28 Feb 2025 23:47:52 +0100
Subject: [PATCH 31/45] avcodec/mpegvideo: Move ratecontrol-only options to
 RateControlContext

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.h    | 11 -----------
 libavcodec/mpegvideoenc.h | 13 +++++++------
 libavcodec/ratecontrol.c  | 25 +++++++++++++------------
 libavcodec/ratecontrol.h  | 11 +++++++++++
 libavcodec/snowenc.c      |  2 +-
 5 files changed, 32 insertions(+), 30 deletions(-)

diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index ac38d112f9..5fef008cc5 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -507,21 +507,10 @@ typedef struct MpegEncContext {
     me_cmp_func sse_cmp[2];
     int (*sum_abs_dctelem)(const int16_t *block);
 
-    /**
-     * ratecontrol qmin qmax limiting method
-     * 0-> clipping, 1-> use a nice continuous function to limit qscale within qmin/qmax.
-     */
-    float rc_qsquish;
-    float rc_qmod_amp;
-    int   rc_qmod_freq;
-    float rc_initial_cplx;
-    float rc_buffer_aggressivity;
     float border_masking;
     int lmin, lmax;
     int vbv_ignore_qmax;
 
-    char *rc_eq;
-
     /* temp buffers for rate control */
     float *cplx_tab, *bits_tab;
 
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 2d7f76c57a..6dd382a3c6 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -81,6 +81,7 @@
 { "msad",   "Sum of absolute differences, median predicted", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_MEDIAN_SAD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, .unit = "cmp_func" }
 
 #define FF_MPV_OFFSET(x) offsetof(MpegEncContext, x)
+#define FF_RC_OFFSET(x)  offsetof(MpegEncContext, rc_context.x)
 #define FF_MPV_OPT_FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
 #define FF_MPV_COMMON_OPTS \
 FF_MPV_OPT_CMP_FUNC, \
@@ -99,16 +100,16 @@ FF_MPV_OPT_CMP_FUNC, \
 { "error_rate", "Simulate errors in the bitstream to test error concealment.",                                                                                                  \
                                                                     FF_MPV_OFFSET(error_rate),              AV_OPT_TYPE_INT, { .i64 = 0 },       0, INT_MAX, FF_MPV_OPT_FLAGS },\
 {"qsquish", "how to keep quantizer between qmin and qmax (0 = clip, 1 = use differentiable function)",                                                                          \
-                                                                    FF_MPV_OFFSET(rc_qsquish), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, 0, 99, FF_MPV_OPT_FLAGS},                        \
-{"rc_qmod_amp", "experimental quantizer modulation",                FF_MPV_OFFSET(rc_qmod_amp), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS},           \
-{"rc_qmod_freq", "experimental quantizer modulation",               FF_MPV_OFFSET(rc_qmod_freq), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS},             \
+                                                                    FF_RC_OFFSET(qsquish), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, 0, 99, FF_MPV_OPT_FLAGS},                        \
+{"rc_qmod_amp", "experimental quantizer modulation",                FF_RC_OFFSET(qmod_amp), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS},           \
+{"rc_qmod_freq", "experimental quantizer modulation",               FF_RC_OFFSET(qmod_freq), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS},             \
 {"rc_eq", "Set rate control equation. When computing the expression, besides the standard functions "                                                                           \
           "defined in the section 'Expression Evaluation', the following functions are available: "                                                                             \
           "bits2qp(bits), qp2bits(qp). Also the following constants are available: iTex pTex tex mv "                                                                           \
           "fCode iCount mcVar var isI isP isB avgQP qComp avgIITex avgPITex avgPPTex avgBPTex avgTex.",                                                                         \
-                                                                    FF_MPV_OFFSET(rc_eq), AV_OPT_TYPE_STRING,                           .flags = FF_MPV_OPT_FLAGS },            \
-{"rc_init_cplx", "initial complexity for 1-pass encoding",          FF_MPV_OFFSET(rc_initial_cplx), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS},       \
-{"rc_buf_aggressivity", "currently useless",                        FF_MPV_OFFSET(rc_buffer_aggressivity), AV_OPT_TYPE_FLOAT, {.dbl = 1.0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \
+                                                                    FF_RC_OFFSET(rc_eq), AV_OPT_TYPE_STRING,                           .flags = FF_MPV_OPT_FLAGS },            \
+{"rc_init_cplx", "initial complexity for 1-pass encoding",          FF_RC_OFFSET(initial_cplx), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS},       \
+{"rc_buf_aggressivity", "currently useless",                        FF_RC_OFFSET(buffer_aggressivity), AV_OPT_TYPE_FLOAT, {.dbl = 1.0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \
 {"border_mask", "increase the quantizer for macroblocks close to borders", FF_MPV_OFFSET(border_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS},    \
 {"lmin", "minimum Lagrange factor (VBR)",                           FF_MPV_OFFSET(lmin), AV_OPT_TYPE_INT, {.i64 =  2*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS },            \
 {"lmax", "maximum Lagrange factor (VBR)",                           FF_MPV_OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 31*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS },            \
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index 86ec7a3443..f383c433c4 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -182,10 +182,10 @@ static double modify_qscale(MpegEncContext *s, const RateControlEntry *rce,
     get_qminmax(&qmin, &qmax, s, pict_type);
 
     /* modulation */
-    if (s->rc_qmod_freq &&
-        frame_num % s->rc_qmod_freq == 0 &&
+    if (rcc->qmod_freq &&
+        frame_num % rcc->qmod_freq == 0 &&
         pict_type == AV_PICTURE_TYPE_P)
-        q *= s->rc_qmod_amp;
+        q *= rcc->qmod_amp;
 
     /* buffer overflow/underflow protection */
     if (buffer_size) {
@@ -198,7 +198,7 @@ static double modify_qscale(MpegEncContext *s, const RateControlEntry *rce,
                 d = 1.0;
             else if (d < 0.0001)
                 d = 0.0001;
-            q *= pow(d, 1.0 / s->rc_buffer_aggressivity);
+            q *= pow(d, 1.0 / rcc->buffer_aggressivity);
 
             q_limit = bits2qp(rce,
                               FFMAX((min_rate - buffer_size + rcc->buffer_index) *
@@ -218,7 +218,7 @@ static double modify_qscale(MpegEncContext *s, const RateControlEntry *rce,
                 d = 1.0;
             else if (d < 0.0001)
                 d = 0.0001;
-            q /= pow(d, 1.0 / s->rc_buffer_aggressivity);
+            q /= pow(d, 1.0 / rcc->buffer_aggressivity);
 
             q_limit = bits2qp(rce,
                               FFMAX(rcc->buffer_index *
@@ -234,8 +234,8 @@ static double modify_qscale(MpegEncContext *s, const RateControlEntry *rce,
     }
     ff_dlog(s, "q:%f max:%f min:%f size:%f index:%f agr:%f\n",
             q, max_rate, min_rate, buffer_size, rcc->buffer_index,
-            s->rc_buffer_aggressivity);
-    if (s->rc_qsquish == 0.0 || qmin == qmax) {
+            rcc->buffer_aggressivity);
+    if (rcc->qsquish == 0.0 || qmin == qmax) {
         if (q < qmin)
             q = qmin;
         else if (q > qmax)
@@ -295,7 +295,7 @@ static double get_qscale(MpegEncContext *s, RateControlEntry *rce,
 
     bits = av_expr_eval(rcc->rc_eq_eval, const_values, rce);
     if (isnan(bits)) {
-        av_log(s->avctx, AV_LOG_ERROR, "Error evaluating rc_eq \"%s\"\n", s->rc_eq);
+        av_log(s->avctx, AV_LOG_ERROR, "Error evaluating rc_eq \"%s\"\n", rcc->rc_eq);
         return -1;
     }
 
@@ -541,11 +541,11 @@ av_cold int ff_rate_control_init(MpegEncContext *s)
     }
 
     res = av_expr_parse(&rcc->rc_eq_eval,
-                        s->rc_eq ? s->rc_eq : "tex^qComp",
+                        rcc->rc_eq ? rcc->rc_eq : "tex^qComp",
                         const_names, func1_names, func1,
                         NULL, NULL, 0, s->avctx);
     if (res < 0) {
-        av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", s->rc_eq);
+        av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", rcc->rc_eq);
         return res;
     }
 
@@ -649,9 +649,9 @@ av_cold int ff_rate_control_init(MpegEncContext *s)
             return -1;
         }
         /* init stuff with the user specified complexity */
-        if (s->rc_initial_cplx) {
+        if (rcc->initial_cplx) {
             for (i = 0; i < 60 * 30; i++) {
-                double bits = s->rc_initial_cplx * (i / 10000.0 + 1.0) * s->mb_num;
+                double bits = rcc->initial_cplx * (i / 10000.0 + 1.0) * s->mb_num;
                 RateControlEntry rce;
 
                 if (i % ((s->gop_size + 3) / 4) == 0)
@@ -701,6 +701,7 @@ av_cold void ff_rate_control_uninit(RateControlContext *rcc)
 {
     emms_c();
 
+    // rc_eq is always managed via an AVOption and therefore not freed here.
     av_expr_free(rcc->rc_eq_eval);
     rcc->rc_eq_eval = NULL;
     av_freep(&rcc->entry);
diff --git a/libavcodec/ratecontrol.h b/libavcodec/ratecontrol.h
index 4d71a181b5..edeccbc6cd 100644
--- a/libavcodec/ratecontrol.h
+++ b/libavcodec/ratecontrol.h
@@ -77,6 +77,17 @@ typedef struct RateControlContext{
     int frame_count[5];
     int last_non_b_pict_type;
 
+    /**
+     * ratecontrol qmin qmax limiting method
+     * 0-> clipping, 1-> use a nice continuous function to limit qscale within qmin/qmax.
+     */
+    float qsquish;
+    float qmod_amp;
+    int   qmod_freq;
+    float initial_cplx;
+    float buffer_aggressivity;
+
+    char *rc_eq;
     struct AVExpr *rc_eq_eval;
 }RateControlContext;
 
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index 5f539a57df..fe8ffdcdcd 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -2118,7 +2118,7 @@ static const AVOption options[] = {
      "defined in the section 'Expression Evaluation', the following functions are available: "
      "bits2qp(bits), qp2bits(qp). Also the following constants are available: iTex pTex tex mv "
      "fCode iCount mcVar var isI isP isB avgQP qComp avgIITex avgPITex avgPPTex avgBPTex avgTex.",
-                                                                                  OFFSET(m.rc_eq), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VE },
+                                                                                  OFFSET(m.rc_context.rc_eq), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VE },
     { NULL },
 };
 
-- 
2.45.2


[-- Attachment #33: 0032-avcodec-mpegvideo-Move-temp-ratecontrol-bufs-to-Rate.patch --]
[-- Type: text/x-patch, Size: 4675 bytes --]

From e6856ae1d22733a3489ea1547dd7dd8c627afbdb Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 1 Mar 2025 00:04:43 +0100
Subject: [PATCH 32/45] avcodec/mpegvideo: Move temp ratecontrol bufs to
 RateControlContext

Also only allocate them when they are needed (namely iff
adaptive quant is true) and allocate them jointly.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.h     |  3 ---
 libavcodec/mpegvideo_enc.c |  5 -----
 libavcodec/ratecontrol.c   | 19 +++++++++++++++----
 libavcodec/ratecontrol.h   |  2 ++
 4 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 5fef008cc5..43d4bbfbcb 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -511,9 +511,6 @@ typedef struct MpegEncContext {
     int lmin, lmax;
     int vbv_ignore_qmax;
 
-    /* temp buffers for rate control */
-    float *cplx_tab, *bits_tab;
-
     /* flag to indicate a reinitialization is required, e.g. after
      * a frame size change */
     int context_reinit;
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 656d312d28..4e4b4c1ba9 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -945,8 +945,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     mb_array_size = s->mb_stride * s->mb_height;
     if (!FF_ALLOCZ_TYPED_ARRAY(s->mb_type,      mb_array_size) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->lambda_table, mb_array_size) ||
-        !FF_ALLOC_TYPED_ARRAY (s->cplx_tab,     mb_array_size) ||
-        !FF_ALLOC_TYPED_ARRAY (s->bits_tab,     mb_array_size) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->mc_mb_var,    mb_array_size) ||
         !FF_ALLOCZ_TYPED_ARRAY(s->mb_var, mb_array_size) ||
         !(s->mb_mean = av_mallocz(mb_array_size)))
@@ -1075,9 +1073,6 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
     av_freep(&s->mb_type);
     av_freep(&s->lambda_table);
 
-    av_freep(&s->cplx_tab);
-    av_freep(&s->bits_tab);
-
     av_freep(&s->q_intra_matrix);
     av_freep(&s->q_intra_matrix16);
     av_freep(&s->input_picture);
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index f383c433c4..86fdacd7b1 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -694,6 +694,15 @@ av_cold int ff_rate_control_init(MpegEncContext *s)
         }
     }
 
+    if (s->adaptive_quant) {
+        unsigned mb_array_size = s->mb_stride * s->mb_height;
+
+        rcc->cplx_tab = av_malloc_array(2 * sizeof(rcc->cplx_tab), mb_array_size);
+        if (!rcc->cplx_tab)
+            return AVERROR(ENOMEM);
+        rcc->bits_tab = rcc->cplx_tab + mb_array_size;
+    }
+
     return 0;
 }
 
@@ -705,6 +714,7 @@ av_cold void ff_rate_control_uninit(RateControlContext *rcc)
     av_expr_free(rcc->rc_eq_eval);
     rcc->rc_eq_eval = NULL;
     av_freep(&rcc->entry);
+    av_freep(&rcc->cplx_tab);
 }
 
 int ff_vbv_update(MpegEncContext *s, int frame_size)
@@ -766,7 +776,8 @@ static void update_predictor(Predictor *p, double q, double var, double size)
     p->coeff += new_coeff;
 }
 
-static void adaptive_quantization(MpegEncContext *s, double q)
+static void adaptive_quantization(RateControlContext *const rcc,
+                                  MpegEncContext *const s, double q)
 {
     int i;
     const float lumi_masking         = s->avctx->lumi_masking / (128.0 * 128.0);
@@ -777,8 +788,8 @@ static void adaptive_quantization(MpegEncContext *s, double q)
     const float border_masking       = s->border_masking;
     float bits_sum                   = 0.0;
     float cplx_sum                   = 0.0;
-    float *cplx_tab                  = s->cplx_tab;
-    float *bits_tab                  = s->bits_tab;
+    float *cplx_tab                  = rcc->cplx_tab;
+    float *bits_tab                  = rcc->bits_tab;
     const int qmin                   = s->avctx->mb_lmin;
     const int qmax                   = s->avctx->mb_lmax;
     const int mb_width               = s->mb_width;
@@ -1048,7 +1059,7 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
         q = qmax;
 
     if (s->adaptive_quant)
-        adaptive_quantization(s, q);
+        adaptive_quantization(rcc, s, q);
     else
         q = (int)(q + 0.5);
 
diff --git a/libavcodec/ratecontrol.h b/libavcodec/ratecontrol.h
index edeccbc6cd..b889491335 100644
--- a/libavcodec/ratecontrol.h
+++ b/libavcodec/ratecontrol.h
@@ -89,6 +89,8 @@ typedef struct RateControlContext{
 
     char *rc_eq;
     struct AVExpr *rc_eq_eval;
+
+    float *cplx_tab, *bits_tab;
 }RateControlContext;
 
 struct MpegEncContext;
-- 
2.45.2


[-- Attachment #34: 0033-avcodec-mpegvideo-Mark-ff_mpv_common_defaults-as-av_.patch --]
[-- Type: text/x-patch, Size: 956 bytes --]

From a52d35c75f7299d4312e8fdba15ff27587f73951 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 17:39:16 +0100
Subject: [PATCH 33/45] avcodec/mpegvideo: Mark ff_mpv_common_defaults() as
 av_cold

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 73c513acbd..f114dd8c0c 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -480,7 +480,7 @@ int ff_update_duplicate_context(MpegEncContext *dst, const MpegEncContext *src)
  * The changed fields will not depend upon the
  * prior state of the MpegEncContext.
  */
-void ff_mpv_common_defaults(MpegEncContext *s)
+av_cold void ff_mpv_common_defaults(MpegEncContext *s)
 {
     s->y_dc_scale_table      =
     s->c_dc_scale_table      = ff_mpeg1_dc_scale_table;
-- 
2.45.2


[-- Attachment #35: 0034-avcodec-speedhqenc-Don-t-log-to-the-private-context.patch --]
[-- Type: text/x-patch, Size: 1283 bytes --]

From c2fa3181e9adac7e6e8501683f316123abbd630c Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 2 Mar 2025 00:12:05 +0100
Subject: [PATCH 34/45] avcodec/speedhqenc: Don't log to the private context

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/speedhqenc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/speedhqenc.c b/libavcodec/speedhqenc.c
index ac40fd6e75..dda5444434 100644
--- a/libavcodec/speedhqenc.c
+++ b/libavcodec/speedhqenc.c
@@ -100,13 +100,13 @@ av_cold int ff_speedhq_encode_init(MpegEncContext *s)
     static AVOnce init_static_once = AV_ONCE_INIT;
 
     if (s->width > 65500 || s->height > 65500) {
-        av_log(s, AV_LOG_ERROR, "SpeedHQ does not support resolutions above 65500x65500\n");
+        av_log(s->avctx, AV_LOG_ERROR, "SpeedHQ does not support resolutions above 65500x65500\n");
         return AVERROR(EINVAL);
     }
 
     // border is not implemented correctly at the moment, see ticket #10078
     if (s->width % 16) {
-        av_log(s, AV_LOG_ERROR, "width must be a multiple of 16\n");
+        av_log(s->avctx, AV_LOG_ERROR, "width must be a multiple of 16\n");
         return AVERROR_PATCHWELCOME;
     }
 
-- 
2.45.2


[-- Attachment #36: 0035-avcodec-speedhqenc-Inline-ff_speedhq_mb_y_order_to_m.patch --]
[-- Type: text/x-patch, Size: 2507 bytes --]

From 0bd008ba4b78076e7a79e252a969fb6e4735540f Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 16:27:44 +0100
Subject: [PATCH 35/45] avcodec/speedhqenc: Inline
 ff_speedhq_mb_y_order_to_mb()

It is an extremely simple function that is only called once,
so it should be inlined.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/speedhqenc.c | 16 ----------------
 libavcodec/speedhqenc.h | 16 +++++++++++++++-
 2 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/libavcodec/speedhqenc.c b/libavcodec/speedhqenc.c
index dda5444434..87497f5f85 100644
--- a/libavcodec/speedhqenc.c
+++ b/libavcodec/speedhqenc.c
@@ -272,22 +272,6 @@ void ff_speedhq_encode_mb(MpegEncContext *s, int16_t block[12][64])
     s->i_tex_bits += get_bits_diff(s);
 }
 
-static int ff_speedhq_mb_rows_in_slice(int slice_num, int mb_height)
-{
-    return mb_height / 4 + (slice_num < (mb_height % 4));
-}
-
-int ff_speedhq_mb_y_order_to_mb(int mb_y_order, int mb_height, int *first_in_slice)
-{
-    int slice_num = 0;
-    while (mb_y_order >= ff_speedhq_mb_rows_in_slice(slice_num, mb_height)) {
-         mb_y_order -= ff_speedhq_mb_rows_in_slice(slice_num, mb_height);
-         slice_num++;
-    }
-    *first_in_slice = (mb_y_order == 0);
-    return mb_y_order * 4 + slice_num;
-}
-
 const FFCodec ff_speedhq_encoder = {
     .p.name         = "speedhq",
     CODEC_LONG_NAME("NewTek SpeedHQ"),
diff --git a/libavcodec/speedhqenc.h b/libavcodec/speedhqenc.h
index 0c52e6a380..15be9764d7 100644
--- a/libavcodec/speedhqenc.h
+++ b/libavcodec/speedhqenc.h
@@ -40,6 +40,20 @@ void ff_speedhq_encode_mb(MpegEncContext *s, int16_t block[12][64]);
 void ff_speedhq_encode_picture_header(MpegEncContext *s);
 void ff_speedhq_end_slice(MpegEncContext *s);
 
-int ff_speedhq_mb_y_order_to_mb(int mb_y_order, int mb_height, int *first_in_slice);
+static inline int ff_speedhq_mb_rows_in_slice(int slice_num, int mb_height)
+{
+    return mb_height / 4 + (slice_num < (mb_height % 4));
+}
+
+static inline int ff_speedhq_mb_y_order_to_mb(int mb_y_order, int mb_height, int *first_in_slice)
+{
+    int slice_num = 0;
+    while (mb_y_order >= ff_speedhq_mb_rows_in_slice(slice_num, mb_height)) {
+         mb_y_order -= ff_speedhq_mb_rows_in_slice(slice_num, mb_height);
+         slice_num++;
+    }
+    *first_in_slice = (mb_y_order == 0);
+    return mb_y_order * 4 + slice_num;
+}
 
 #endif /* AVCODEC_SPEEDHQENC_H */
-- 
2.45.2


[-- Attachment #37: 0036-avcodec-mjpegenc-Remove-nonsensical-AMV-options.patch --]
[-- Type: text/x-patch, Size: 2234 bytes --]

From 0030a6b276ff761a03d2ef71e27057b87d496a22 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 01:36:39 +0100
Subject: [PATCH 36/45] avcodec/mjpegenc: Remove nonsensical AMV options

Both these options are unsupported and silently ignored for AMV;
so it is better to not offer them at all.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mjpegenc.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index c2e8b93a34..22d2b4816f 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -301,7 +301,7 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s)
                  (s->avctx->active_thread_type & FF_THREAD_SLICE) &&
                  s->avctx->thread_count > 1;
 
-    if (s->codec_id == AV_CODEC_ID_AMV || use_slices)
+    if (use_slices)
         m->huffman = HUFFMAN_TABLE_DEFAULT;
 
     if (s->mpv_flags & FF_MPV_FLAG_QP_RD) {
@@ -624,11 +624,12 @@ static int amv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
 #define OFFSET(x) offsetof(MJPEGEncContext, mjpeg.x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-FF_MPV_COMMON_OPTS
+#define AMV_OPTIONS_OFFSET 4
 { "huffman", "Huffman table strategy", OFFSET(huffman), AV_OPT_TYPE_INT, { .i64 = HUFFMAN_TABLE_OPTIMAL }, 0, NB_HUFFMAN_TABLE_OPTION - 1, VE, .unit = "huffman" },
     { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = HUFFMAN_TABLE_DEFAULT }, INT_MIN, INT_MAX, VE, .unit = "huffman" },
     { "optimal", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = HUFFMAN_TABLE_OPTIMAL }, INT_MIN, INT_MAX, VE, .unit = "huffman" },
 { "force_duplicated_matrix", "Always write luma and chroma matrix for mjpeg, useful for rtp streaming.", OFFSET(force_duplicated_matrix), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, VE },
+FF_MPV_COMMON_OPTS
 { NULL},
 };
 
@@ -688,7 +689,7 @@ FFCodec ff_mjpeg_encoder = {
 static const AVClass amv_class = {
     .class_name = "amv encoder",
     .item_name  = av_default_item_name,
-    .option     = options,
+    .option     = options + AMV_OPTIONS_OFFSET,
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-- 
2.45.2


[-- Attachment #38: 0037-avcodec-mjpegenc-Don-t-log-to-private-context.patch --]
[-- Type: text/x-patch, Size: 925 bytes --]

From f893480ece9e2f253d4f433c4e1914b84aa770a7 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 01:42:24 +0100
Subject: [PATCH 37/45] avcodec/mjpegenc: Don't log to private context

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mjpegenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 22d2b4816f..cd8eb8f6c1 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -318,7 +318,7 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s)
         return ret;
 
     if (s->width > 65500 || s->height > 65500) {
-        av_log(s, AV_LOG_ERROR, "JPEG does not support resolutions above 65500x65500\n");
+        av_log(s->avctx, AV_LOG_ERROR, "JPEG does not support resolutions above 65500x65500\n");
         return AVERROR(EINVAL);
     }
 
-- 
2.45.2


[-- Attachment #39: 0038-avcodec-mpeg12enc-Simplify-writing-bits.patch --]
[-- Type: text/x-patch, Size: 2333 bytes --]

From f186740046f64e71f490393c26e3c0de2b82c8b8 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 18:42:13 +0100
Subject: [PATCH 38/45] avcodec/mpeg12enc: Simplify writing bits

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12enc.c | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 3f23045afc..ca51430fce 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -594,10 +594,8 @@ void ff_mpeg1_encode_picture_header(MpegEncContext *s)
 
         if (fpa_type != 0) {
             put_header(s, USER_START_CODE);
-            put_bits(&s->pb, 8, 'J');   // S3D_video_format_signaling_identifier
-            put_bits(&s->pb, 8, 'P');
-            put_bits(&s->pb, 8, '3');
-            put_bits(&s->pb, 8, 'D');
+            // S3D_video_format_signaling_identifier
+            put_bits32(&s->pb, MKBETAG('J','P','3','D'));
             put_bits(&s->pb, 8, 0x03);  // S3D_video_format_length
 
             put_bits(&s->pb, 1, 1);     // reserved_bit
@@ -612,21 +610,15 @@ void ff_mpeg1_encode_picture_header(MpegEncContext *s)
             AV_FRAME_DATA_A53_CC);
         if (side_data) {
             if (side_data->size <= A53_MAX_CC_COUNT * 3 && side_data->size % 3 == 0) {
-                int i = 0;
-
                 put_header (s, USER_START_CODE);
 
-                put_bits(&s->pb, 8, 'G');                   // user_identifier
-                put_bits(&s->pb, 8, 'A');
-                put_bits(&s->pb, 8, '9');
-                put_bits(&s->pb, 8, '4');
+                put_bits32(&s->pb, MKBETAG('G','A','9','4')); // user_identifier
                 put_bits(&s->pb, 8, 3);                     // user_data_type_code
                 put_bits(&s->pb, 8,
                     (side_data->size / 3 & A53_MAX_CC_COUNT) | 0x40); // flags, cc_count
                 put_bits(&s->pb, 8, 0xff);                  // em_data
 
-                for (i = 0; i < side_data->size; i++)
-                    put_bits(&s->pb, 8, side_data->data[i]);
+                ff_copy_bits(&s->pb, side_data->data, side_data->size);
 
                 put_bits(&s->pb, 8, 0xff);                  // marker_bits
             } else {
-- 
2.45.2


[-- Attachment #40: 0039-avcodec-mpegvideo-Move-vbv_delay-to-Mpeg1Context.patch --]
[-- Type: text/x-patch, Size: 2400 bytes --]

From c46015047a0a995b3da3ca4679aff6935f568369 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 29 Jan 2022 06:50:51 +0100
Subject: [PATCH 39/45] avcodec/mpegvideo: Move vbv_delay to Mpeg1Context

Only used there and only by the main thread.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12dec.c | 5 +++--
 libavcodec/mpegvideo.h | 1 -
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index ba40c1f06f..b019c092a2 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -90,6 +90,7 @@ typedef struct Mpeg1Context {
     int tmpgexs;
     int first_slice;
     int extradata_decoded;
+    int vbv_delay;
     int64_t timecode_frame_start;  /*< GOP timecode frame start number, in non drop frame format */
 } Mpeg1Context;
 
@@ -953,7 +954,7 @@ static int mpeg_decode_postinit(AVCodecContext *avctx)
             (s->bit_rate != 0x3FFFF*400)) {
             avctx->rc_max_rate = s->bit_rate;
         } else if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO && s->bit_rate &&
-                   (s->bit_rate != 0x3FFFF*400 || s->vbv_delay != 0xFFFF)) {
+                   (s->bit_rate != 0x3FFFF*400 || s1->vbv_delay != 0xFFFF)) {
             avctx->bit_rate = s->bit_rate;
         }
         s1->save_aspect          = s->avctx->sample_aspect_ratio;
@@ -1024,7 +1025,7 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, const uint8_t *buf,
         return AVERROR_INVALIDDATA;
 
     vbv_delay = get_bits(&s->gb, 16);
-    s->vbv_delay = vbv_delay;
+    s1->vbv_delay = vbv_delay;
     if (s->pict_type == AV_PICTURE_TYPE_P ||
         s->pict_type == AV_PICTURE_TYPE_B) {
         s->full_pel[0] = get_bits1(&s->gb);
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 43d4bbfbcb..10be87450a 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -204,7 +204,6 @@ typedef struct MpegEncContext {
     int adaptive_quant;         ///< use adaptive quantization
     int dquant;                 ///< qscale difference to prev qscale
     int pict_type;              ///< AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, ...
-    int vbv_delay;
     int last_pict_type; //FIXME removes
     int last_non_b_pict_type;   ///< used for MPEG-4 gmc B-frames & ratecontrol
     int droppable;
-- 
2.45.2


[-- Attachment #41: 0040-avcodec-mpegvideo_enc-motion_est-Pre-center-fcode_ta.patch --]
[-- Type: text/x-patch, Size: 3302 bytes --]

From 05c7ee55d8e6834e65dc025187e713636cbae48c Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 17 Feb 2022 16:54:20 +0100
Subject: [PATCH 40/45] avcodec/mpegvideo_enc, motion_est: Pre-center fcode_tab

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/ituh263enc.c    | 2 +-
 libavcodec/motion_est.c    | 3 +--
 libavcodec/mpeg12enc.c     | 2 +-
 libavcodec/mpeg4videoenc.c | 2 +-
 libavcodec/mpegvideo_enc.c | 2 +-
 5 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 5beb857a6e..188996a4d1 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -843,7 +843,7 @@ av_cold void ff_h263_encode_init(MpegEncContext *s)
         break;
     case AV_CODEC_ID_H263P:
         if(s->umvplus)
-            s->fcode_tab= umv_fcode_tab;
+            s->fcode_tab = umv_fcode_tab + MAX_MV;
         if(s->modified_quant){
             s->min_qcoeff= -2047;
             s->max_qcoeff=  2047;
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index 46c4ca2dd9..4940da21f3 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -1619,8 +1619,7 @@ int ff_get_best_fcode(MpegEncContext * s, const int16_t (*mv_table)[2], int type
                 if(s->mb_type[xy] & type){
                     int mx= mv_table[xy][0];
                     int my= mv_table[xy][1];
-                    int fcode= FFMAX(fcode_tab[mx + MAX_MV],
-                                     fcode_tab[my + MAX_MV]);
+                    int fcode = FFMAX(fcode_tab[mx], fcode_tab[my]);
                     int j;
 
                     if (mx >= range || mx < -range ||
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index ca51430fce..0586b8cfe2 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -1157,7 +1157,7 @@ av_cold void ff_mpeg1_encode_init(MpegEncContext *s)
     s->c_dc_scale_table = ff_mpeg12_dc_scale_table[s->intra_dc_precision];
 
     s->me.mv_penalty = mv_penalty;
-    s->fcode_tab     = fcode_tab;
+    s->fcode_tab     = fcode_tab + MAX_MV;
     if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
         s->min_qcoeff = -255;
         s->max_qcoeff = 255;
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 26f9b40ff7..6ce5bc4462 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -1290,7 +1290,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
 
     ff_thread_once(&init_static_once, mpeg4_encode_init_static);
 
-    s->fcode_tab                = fcode_tab;
+    s->fcode_tab                = fcode_tab + MAX_MV;
     s->min_qcoeff               = -2048;
     s->max_qcoeff               = 2047;
     s->intra_ac_vlc_length      = uni_mpeg4_intra_rl_len;
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 4e4b4c1ba9..4aeefcaf8d 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -286,7 +286,7 @@ static void mpv_encode_defaults(MpegEncContext *s)
 
     ff_thread_once(&init_static_once, mpv_encode_init_static);
 
-    s->fcode_tab     = default_fcode_tab;
+    s->fcode_tab     = default_fcode_tab + MAX_MV;
 
     s->input_picture_number  = 0;
     s->picture_in_gop_number = 0;
-- 
2.45.2


[-- Attachment #42: 0041-avcodec-mjpegenc-Use-forward-decl-for-MpegEncContext.patch --]
[-- Type: text/x-patch, Size: 3045 bytes --]

From 7dcba9f1abe845c3cad998f302163338e199d023 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 4 Mar 2025 16:44:15 +0100
Subject: [PATCH 41/45] avcodec/mjpegenc: Use forward decl for MpegEncContext,
 MJpegHuffmanCode

Avoids an indirect inclusion of mpegvideo.h in mjpegenc_common.c.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mjpegenc.c | 14 ++++++++++++++
 libavcodec/mjpegenc.h | 19 +++----------------
 2 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index cd8eb8f6c1..38d5ad3a11 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -45,6 +45,20 @@
 #include "mpegvideoenc.h"
 #include "profiles.h"
 
+/**
+ * Buffer of JPEG frame data.
+ *
+ * Optimal Huffman table generation requires the frame data to be loaded into
+ * a buffer so that the tables can be computed.
+ * There are at most mb_width*mb_height*12*64 of these per frame.
+ */
+typedef struct MJpegHuffmanCode {
+    // 0=DC lum, 1=DC chrom, 2=AC lum, 3=AC chrom
+    uint8_t table_id; ///< The Huffman table id associated with the data.
+    uint8_t code;     ///< The exponent.
+    uint16_t mant;    ///< The mantissa.
+} MJpegHuffmanCode;
+
 /* The following is the private context of MJPEG/AMV decoder.
  * Note that when using slice threading only the main thread's
  * MpegEncContext is followed by a MjpegContext; the other threads
diff --git a/libavcodec/mjpegenc.h b/libavcodec/mjpegenc.h
index a593b67e96..1ac0d6de7e 100644
--- a/libavcodec/mjpegenc.h
+++ b/libavcodec/mjpegenc.h
@@ -36,23 +36,8 @@
 #include <stdint.h>
 
 #include "mjpeg.h"
-#include "mpegvideo.h"
 #include "put_bits.h"
 
-/**
- * Buffer of JPEG frame data.
- *
- * Optimal Huffman table generation requires the frame data to be loaded into
- * a buffer so that the tables can be computed.
- * There are at most mb_width*mb_height*12*64 of these per frame.
- */
-typedef struct MJpegHuffmanCode {
-    // 0=DC lum, 1=DC chrom, 2=AC lum, 3=AC chrom
-    uint8_t table_id; ///< The Huffman table id associated with the data.
-    uint8_t code;     ///< The exponent.
-    uint16_t mant;    ///< The mantissa.
-} MJpegHuffmanCode;
-
 /**
  * Holds JPEG frame data and Huffman table data.
  */
@@ -89,7 +74,7 @@ typedef struct MJpegContext {
     uint8_t val_ac_chrominance[256]; ///< AC chrominance Huffman values.
 
     size_t huff_ncode;               ///< Number of current entries in the buffer.
-    MJpegHuffmanCode *huff_buffer;   ///< Buffer for Huffman code values.
+    struct MJpegHuffmanCode *huff_buffer; ///< Buffer for Huffman code values.
 } MJpegContext;
 
 /**
@@ -107,6 +92,8 @@ static inline void put_marker(PutBitContext *p, enum JpegMarker code)
     put_bits(p, 8, code);
 }
 
+typedef struct MpegEncContext MpegEncContext;
+
 int  ff_mjpeg_encode_init(MpegEncContext *s);
 void ff_mjpeg_amv_encode_picture_header(MpegEncContext *s);
 void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64]);
-- 
2.45.2


[-- Attachment #43: 0042-avcodec-mjpegenc-Don-t-use-ff_-prefix-for-static-fun.patch --]
[-- Type: text/x-patch, Size: 2983 bytes --]

From 9880dec9f9bcf7eb2d3c2521bf7f0008ff044592 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 4 Mar 2025 16:46:30 +0100
Subject: [PATCH 42/45] avcodec/mjpegenc: Don't use ff_ prefix for static
 functions

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mjpegenc.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 38d5ad3a11..0bd362c3af 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -390,7 +390,7 @@ static av_cold int mjpeg_encode_close(AVCodecContext *avctx)
  * @param table_id Which Huffman table the code belongs to.
  * @param code The encoded exponent of the coefficients and the run-bits.
  */
-static inline void ff_mjpeg_encode_code(MJpegContext *s, uint8_t table_id, int code)
+static inline void mjpeg_encode_code(MJpegContext *s, uint8_t table_id, int code)
 {
     MJpegHuffmanCode *c = &s->huff_buffer[s->huff_ncode++];
     c->table_id = table_id;
@@ -405,13 +405,13 @@ static inline void ff_mjpeg_encode_code(MJpegContext *s, uint8_t table_id, int c
  * @param val The coefficient.
  * @param run The run-bits.
  */
-static void ff_mjpeg_encode_coef(MJpegContext *s, uint8_t table_id, int val, int run)
+static void mjpeg_encode_coef(MJpegContext *s, uint8_t table_id, int val, int run)
 {
     int mant, code;
 
     if (val == 0) {
         av_assert0(run == 0);
-        ff_mjpeg_encode_code(s, table_id, 0);
+        mjpeg_encode_code(s, table_id, 0);
     } else {
         mant = val;
         if (val < 0) {
@@ -422,7 +422,7 @@ static void ff_mjpeg_encode_coef(MJpegContext *s, uint8_t table_id, int val, int
         code = (run << 4) | (av_log2_16bit(val) + 1);
 
         s->huff_buffer[s->huff_ncode].mant = mant;
-        ff_mjpeg_encode_code(s, table_id, code);
+        mjpeg_encode_code(s, table_id, code);
     }
 }
 
@@ -445,7 +445,7 @@ static void record_block(MpegEncContext *s, int16_t *block, int n)
     dc = block[0]; /* overflow is impossible */
     val = dc - s->last_dc[component];
 
-    ff_mjpeg_encode_coef(m, table_id, val, 0);
+    mjpeg_encode_coef(m, table_id, val, 0);
 
     s->last_dc[component] = dc;
 
@@ -463,17 +463,17 @@ static void record_block(MpegEncContext *s, int16_t *block, int n)
             run++;
         } else {
             while (run >= 16) {
-                ff_mjpeg_encode_code(m, table_id, 0xf0);
+                mjpeg_encode_code(m, table_id, 0xf0);
                 run -= 16;
             }
-            ff_mjpeg_encode_coef(m, table_id, val, run);
+            mjpeg_encode_coef(m, table_id, val, run);
             run = 0;
         }
     }
 
     /* output EOB only if not already 64 values */
     if (last_index < 63 || run != 0)
-        ff_mjpeg_encode_code(m, table_id, 0);
+        mjpeg_encode_code(m, table_id, 0);
 }
 
 static void encode_block(MpegEncContext *s, int16_t *block, int n)
-- 
2.45.2


[-- Attachment #44: 0043-avcodec-mjpegenc_common-Constify-ff_mjpeg_encode_-dc.patch --]
[-- Type: text/x-patch, Size: 4782 bytes --]

From ff335824cfbf06384f9d400a2d29c2ebe9aa2e65 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 4 Mar 2025 17:18:30 +0100
Subject: [PATCH 43/45] avcodec/mjpegenc_common: Constify
 ff_mjpeg_encode_{dc,picture_header}()

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mjpegenc_common.c | 16 ++++++++--------
 libavcodec/mjpegenc_common.h | 10 +++++-----
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/libavcodec/mjpegenc_common.c b/libavcodec/mjpegenc_common.c
index 751e43fd3b..e7a4f8f16a 100644
--- a/libavcodec/mjpegenc_common.c
+++ b/libavcodec/mjpegenc_common.c
@@ -56,10 +56,10 @@ static int put_huffman_table(PutBitContext *p, int table_class, int table_id,
 }
 
 static void jpeg_table_header(AVCodecContext *avctx, PutBitContext *p,
-                              MJpegContext *m,
+                              const MJpegContext *m,
                               const uint8_t intra_matrix_permutation[64],
-                              uint16_t luma_intra_matrix[64],
-                              uint16_t chroma_intra_matrix[64],
+                              const uint16_t luma_intra_matrix[64],
+                              const uint16_t chroma_intra_matrix[64],
                               int hsample[3], int use_slices, int matrices_differ)
 {
     int size;
@@ -246,7 +246,7 @@ static void jpeg_put_comments(AVCodecContext *avctx, PutBitContext *p,
     }
 }
 
-void ff_mjpeg_init_hvsample(AVCodecContext *avctx, int hsample[4], int vsample[4])
+void ff_mjpeg_init_hvsample(const AVCodecContext *avctx, int hsample[4], int vsample[4])
 {
     if (avctx->codec_id == AV_CODEC_ID_LJPEG &&
         (   avctx->pix_fmt == AV_PIX_FMT_BGR0
@@ -273,10 +273,10 @@ void ff_mjpeg_init_hvsample(AVCodecContext *avctx, int hsample[4], int vsample[4
 }
 
 void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb,
-                                    const AVFrame *frame, struct MJpegContext *m,
+                                    const AVFrame *frame, const struct MJpegContext *m,
                                     const uint8_t intra_matrix_permutation[64], int pred,
-                                    uint16_t luma_intra_matrix[64],
-                                    uint16_t chroma_intra_matrix[64],
+                                    const uint16_t luma_intra_matrix[64],
+                                    const uint16_t chroma_intra_matrix[64],
                                     int use_slices)
 {
     const int lossless = !m;
@@ -465,7 +465,7 @@ void ff_mjpeg_encode_picture_trailer(PutBitContext *pb, int header_bits)
 }
 
 void ff_mjpeg_encode_dc(PutBitContext *pb, int val,
-                        uint8_t *huff_size, uint16_t *huff_code)
+                        const uint8_t huff_size[], const uint16_t huff_code[])
 {
     int mant, nbits;
 
diff --git a/libavcodec/mjpegenc_common.h b/libavcodec/mjpegenc_common.h
index e9f0ea44a0..0cf5a72706 100644
--- a/libavcodec/mjpegenc_common.h
+++ b/libavcodec/mjpegenc_common.h
@@ -31,21 +31,21 @@ struct MJpegContext;
 int ff_mjpeg_add_icc_profile_size(AVCodecContext *avctx, const AVFrame *frame,
                                   size_t *max_pkt_size);
 void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb,
-                                    const AVFrame *frame, struct MJpegContext *m,
+                                    const AVFrame *frame, const struct MJpegContext *m,
                                     const uint8_t intra_matrix_permutation[64],
                                     int pred,
-                                    uint16_t luma_intra_matrix[64],
-                                    uint16_t chroma_intra_matrix[64],
+                                    const uint16_t luma_intra_matrix[64],
+                                    const uint16_t chroma_intra_matrix[64],
                                     int use_slices);
 void ff_mjpeg_encode_picture_trailer(PutBitContext *pb, int header_bits);
 void ff_mjpeg_escape_FF(PutBitContext *pb, int start);
 void ff_mjpeg_build_huffman_codes(uint8_t *huff_size, uint16_t *huff_code,
                                   const uint8_t *bits_table,
                                   const uint8_t *val_table);
-void ff_mjpeg_init_hvsample(AVCodecContext *avctx, int hsample[4], int vsample[4]);
+void ff_mjpeg_init_hvsample(const AVCodecContext *avctx, int hsample[4], int vsample[4]);
 
 void ff_mjpeg_encode_dc(PutBitContext *pb, int val,
-                        uint8_t *huff_size, uint16_t *huff_code);
+                        const uint8_t huff_size[], const uint16_t huff_code[]);
 
 int ff_mjpeg_encode_check_pix_fmt(AVCodecContext *avctx);
 
-- 
2.45.2


[-- Attachment #45: 0044-avcodec-mjpegenc-Constify-parent-ctx-in-encode_block.patch --]
[-- Type: text/x-patch, Size: 1205 bytes --]

From f199c0b66dfb1aeeb282559f120a1936ef8674a0 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 4 Mar 2025 18:07:23 +0100
Subject: [PATCH 44/45] avcodec/mjpegenc: Constify parent ctx in encode_block()

Said parent is shared between all slice contexts and encode_block()
can be run concurrently by slice threads, so the parent context
must not (and is not) be modified. So constify the pointers.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mjpegenc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 0bd362c3af..bcfc5523fb 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -480,9 +480,9 @@ static void encode_block(MpegEncContext *s, int16_t *block, int n)
 {
     int mant, nbits, code, i, j;
     int component, dc, run, last_index, val;
-    MJpegContext *m = s->mjpeg_ctx;
-    uint8_t *huff_size_ac;
-    uint16_t *huff_code_ac;
+    const MJpegContext *const m = s->mjpeg_ctx;
+    const uint16_t *huff_code_ac;
+    const uint8_t  *huff_size_ac;
 
     /* DC coef */
     component = (n <= 3 ? 0 : (n&1) + 1);
-- 
2.45.2


[-- Attachment #46: 0045-avcodec-mpeg12dec-Use-CHROMA_-defines.patch --]
[-- Type: text/x-patch, Size: 3701 bytes --]

From a584328f8c02096f3fc3657612c6293fd51cb672 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 4 Mar 2025 17:11:32 +0100
Subject: [PATCH 45/45] avcodec/mpeg12dec: Use CHROMA_* defines

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12dec.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index b019c092a2..dbecc64a14 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -780,7 +780,7 @@ static av_cold int mpeg_decode_init(AVCodecContext *avctx)
 
     ff_mpeg12_init_vlcs();
 
-    s2->chroma_format              = 1;
+    s2->chroma_format  = CHROMA_420;
     avctx->color_range             = AVCOL_RANGE_MPEG;
     return 0;
 }
@@ -864,11 +864,11 @@ static enum AVPixelFormat mpeg_get_pixelformat(AVCodecContext *avctx)
     if (CONFIG_GRAY && (avctx->flags & AV_CODEC_FLAG_GRAY))
         return AV_PIX_FMT_GRAY8;
 
-    if (s->chroma_format < 2)
+    if (s->chroma_format < CHROMA_422)
         pix_fmts = avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO ?
                                 mpeg1_hwaccel_pixfmt_list_420 :
                                 mpeg2_hwaccel_pixfmt_list_420;
-    else if (s->chroma_format == 2)
+    else if (s->chroma_format == CHROMA_422)
         pix_fmts = mpeg12_pixfmt_list_422;
     else
         pix_fmts = mpeg12_pixfmt_list_444;
@@ -990,9 +990,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
             switch (s->chroma_format) {
-            case 1: avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; break;
-            case 2:
-            case 3: avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT; break;
+            case CHROMA_420: avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; break;
+            case CHROMA_422:
+            case CHROMA_444: avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT; break;
             default: av_assert0(0);
             }
         } // MPEG-2
@@ -1066,7 +1066,7 @@ static void mpeg_decode_sequence_extension(Mpeg1Context *s1)
     s->chroma_format        = get_bits(&s->gb, 2); /* chroma_format 1=420, 2=422, 3=444 */
 
     if (!s->chroma_format) {
-        s->chroma_format = 1;
+        s->chroma_format = CHROMA_420;
         av_log(s->avctx, AV_LOG_WARNING, "Chroma format invalid\n");
     }
 
@@ -1545,7 +1545,7 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y,
 
             if (s->mb_y >= s->mb_height) {
                 int left   = get_bits_left(&s->gb);
-                int is_d10 = s->chroma_format == 2 &&
+                int is_d10 = s->chroma_format == CHROMA_422 &&
                              s->pict_type == AV_PICTURE_TYPE_I &&
                              avctx->profile == 0 && avctx->level == 5 &&
                              s->intra_dc_precision == 2 &&
@@ -1843,7 +1843,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx,
     s->picture_structure    = PICT_FRAME;
     s->first_field          = 0;
     s->frame_pred_frame_dct = 1;
-    s->chroma_format        = 1;
+    s->chroma_format        = CHROMA_420;
     s->codec_id             =
     s->avctx->codec_id      = AV_CODEC_ID_MPEG1VIDEO;
     if (s->avctx->flags & AV_CODEC_FLAG_LOW_DELAY)
@@ -1895,7 +1895,7 @@ static int vcr2_init_sequence(AVCodecContext *avctx)
     s->picture_structure     = PICT_FRAME;
     s->first_field           = 0;
     s->frame_pred_frame_dct  = 1;
-    s->chroma_format         = 1;
+    s->chroma_format         = CHROMA_420;
     if (s->codec_tag == AV_RL32("BW10")) {
         s->codec_id              = s->avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO;
     } else {
-- 
2.45.2


[-- Attachment #47: Type: text/plain, Size: 251 bytes --]

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [FFmpeg-devel] Misc mpegvideo patches
  2025-03-04 21:06       ` Andreas Rheinhardt
@ 2025-03-04 22:08         ` Ramiro Polla
  0 siblings, 0 replies; 6+ messages in thread
From: Ramiro Polla @ 2025-03-04 22:08 UTC (permalink / raw)
  To: ffmpeg-devel


On 3/4/25 22:06, Andreas Rheinhardt wrote:
> I added a comment to #10 and modified #18 as described. I also changed
> #21 to protect the macro in parentheses and simplified the FF_RC_OFFSET
> macro in #31. Furthermore, there are now five more patches. All
> attached. https://github.com/mkver/FFmpeg/tree/mpegvideo_misc has been
> force-pushed.

> Subject: [PATCH 24/45] avcodec/mpegvideo_enc: Factor checks out of loop
> 
> Also move this code to handle_matrices().

handle_matrices() -> init_matrices()

> Subject: [PATCH 44/45] avcodec/mjpegenc: Constify parent ctx in encode_block()
> 
> Said parent is shared between all slice contexts and encode_block()
> can be run concurrently by slice threads, so the parent context
> must not (and is not) be modified. So constify the pointers.

"most not be (and is not) modified."

No more comments from me.

Thank you for all this cleanup work, it is really appreciated!

Ramiro

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2025-03-04 22:08 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-03-04 13:42 [FFmpeg-devel] Misc mpegvideo patches Andreas Rheinhardt
2025-03-04 16:30 ` Ramiro Polla
2025-03-04 17:04   ` Andreas Rheinhardt
2025-03-04 18:39     ` Ramiro Polla
2025-03-04 21:06       ` Andreas Rheinhardt
2025-03-04 22:08         ` Ramiro Polla

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git