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; 4+ 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] 4+ messages in thread

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

Thread overview: 4+ 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

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