PR #21320 opened by mkver
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21320
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21320.patch

Also split WMV2DSP into idct and (decoder-only) motion compensation.


>From f391f3f08f3ecabe23f04410a0e96b597f77f3c1 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 25 Jun 2025 04:45:57 +0200
Subject: [PATCH 01/14] avcodec/wmv2: Don't initialize BlockDSPContext
 redundantly

ff_mpv_common_init() already does it for us.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/wmv2.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libavcodec/wmv2.c b/libavcodec/wmv2.c
index c2bcb988c4..903c1c9a44 100644
--- a/libavcodec/wmv2.c
+++ b/libavcodec/wmv2.c
@@ -29,7 +29,6 @@ av_cold void ff_wmv2_common_init(MpegEncContext *s)
 {
     WMV2Context *const w = s->private_ctx;
 
-    ff_blockdsp_init(&s->bdsp);
     ff_wmv2dsp_init(&w->wdsp);
     s->idsp.perm_type = w->wdsp.idct_perm;
     ff_init_scantable_permutation(s->idsp.idct_permutation,
-- 
2.49.1


>From d840b947afbcaa016c06f90824e5c637eac17be7 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 25 Jun 2025 05:37:05 +0200
Subject: [PATCH 02/14] avcodec/msmpeg4: Initialize WMV2 generically

WMV1 and WMV2 use other scantables and therefore
ff_msmpeg4_common_init() reinitializes them. Yet WMV2
also uses a different IDCT overwriting the ordinary one,
so that the IDCT permutation changes and therefore
ff_wmv2_common_init() (called after ff_msmpeg4_common_init())
needs to reinitialize the scantables again.

Avoid this by calling ff_wmv2_common_init() in
ff_msmpeg4_common_init().

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/msmpeg4.c | 8 +++++++-
 libavcodec/wmv2.c    | 9 ---------
 libavcodec/wmv2dec.c | 2 --
 libavcodec/wmv2enc.c | 2 --
 4 files changed, 7 insertions(+), 14 deletions(-)

diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c
index 5ceb100333..79a43602b1 100644
--- a/libavcodec/msmpeg4.c
+++ b/libavcodec/msmpeg4.c
@@ -28,6 +28,7 @@
  */
 
 #include "config.h"
+#include "config_components.h"
 
 #include "libavutil/thread.h"
 #if ARCH_X86
@@ -42,6 +43,7 @@
 #include "mpeg4videodata.h"
 #include "msmpeg4data.h"
 #include "msmpeg4_vc1_data.h"
+#include "wmv2.h"
 
 /*
  * You can also call this codec: MPEG-4 with a twist!
@@ -133,8 +135,12 @@ av_cold void ff_msmpeg4_common_init(MpegEncContext *s)
             s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;
         }
         break;
-    case MSMP4_WMV1:
+#if CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER
     case MSMP4_WMV2:
+        ff_wmv2_common_init(s);
+        // fallthrough
+#endif
+    case MSMP4_WMV1:
         s->y_dc_scale_table= ff_wmv1_y_dc_scale_table;
         s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
         break;
diff --git a/libavcodec/wmv2.c b/libavcodec/wmv2.c
index 903c1c9a44..d36ae66581 100644
--- a/libavcodec/wmv2.c
+++ b/libavcodec/wmv2.c
@@ -21,7 +21,6 @@
 #include "avcodec.h"
 #include "idctdsp.h"
 #include "mpegvideo.h"
-#include "msmpeg4_vc1_data.h"
 #include "wmv2.h"
 
 
@@ -33,14 +32,6 @@ av_cold void ff_wmv2_common_init(MpegEncContext *s)
     s->idsp.perm_type = w->wdsp.idct_perm;
     ff_init_scantable_permutation(s->idsp.idct_permutation,
                                   w->wdsp.idct_perm);
-    ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable,
-                      ff_wmv1_scantable[1]);
-    ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable,
-                      ff_wmv1_scantable[0]);
-    ff_permute_scantable(s->permutated_intra_h_scantable, ff_wmv1_scantable[2],
-                         s->idsp.idct_permutation);
-    ff_permute_scantable(s->permutated_intra_v_scantable, ff_wmv1_scantable[3],
-                         s->idsp.idct_permutation);
     s->idsp.idct_put = w->wdsp.idct_put;
     s->idsp.idct_add = w->wdsp.idct_add;
     s->idsp.idct     = NULL;
diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c
index 512d63b23e..5bac48385f 100644
--- a/libavcodec/wmv2dec.c
+++ b/libavcodec/wmv2dec.c
@@ -578,8 +578,6 @@ static av_cold int wmv2_decode_init(AVCodecContext *avctx)
     h->decode_header = wmv2_decode_picture_header;
     h->decode_mb = wmv2_decode_mb;
 
-    ff_wmv2_common_init(s);
-
     decode_ext_header(w);
 
     return ff_intrax8_common_init(avctx, &w->x8, h->block[0],
diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c
index b6811fde0e..5b3e2ae116 100644
--- a/libavcodec/wmv2enc.c
+++ b/libavcodec/wmv2enc.c
@@ -233,8 +233,6 @@ static av_cold int wmv2_encode_init(AVCodecContext *avctx)
     if (ret < 0)
         return ret;
 
-    ff_wmv2_common_init(&s->c);
-
     avctx->extradata_size = WMV2_EXTRADATA_SIZE;
     avctx->extradata      = av_mallocz(avctx->extradata_size + 
AV_INPUT_BUFFER_PADDING_SIZE);
     if (!avctx->extradata)
-- 
2.49.1


>From 0e7028d99d46a96fbc266e5af27e39efc341bee7 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 25 Jun 2025 07:08:41 +0200
Subject: [PATCH 03/14] avcodec/msmpeg4: Avoid branch

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/msmpeg4.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c
index 79a43602b1..45c56a9ad9 100644
--- a/libavcodec/msmpeg4.c
+++ b/libavcodec/msmpeg4.c
@@ -143,18 +143,14 @@ av_cold void ff_msmpeg4_common_init(MpegEncContext *s)
     case MSMP4_WMV1:
         s->y_dc_scale_table= ff_wmv1_y_dc_scale_table;
         s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
-        break;
-    }
-
-    if (s->msmpeg4_version >= MSMP4_WMV1) {
         ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable,   
ff_wmv1_scantable[1]);
         ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable,   
ff_wmv1_scantable[0]);
         ff_permute_scantable(s->permutated_intra_h_scantable, 
ff_wmv1_scantable[2],
                              s->idsp.idct_permutation);
         ff_permute_scantable(s->permutated_intra_v_scantable, 
ff_wmv1_scantable[3],
                              s->idsp.idct_permutation);
+        break;
     }
-    //Note the default tables are set in common_init in mpegvideo.c
 
     ff_thread_once(&init_static_once, msmpeg4_common_init_static);
 }
-- 
2.49.1


>From 4330861e6a6a91126e8e787228fa1a3b6a13bf2d Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 25 Jun 2025 07:22:06 +0200
Subject: [PATCH 04/14] avcodec/wmv2dec: Don't put skip_type in context

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/wmv2dec.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c
index 5bac48385f..f4b4b4ac84 100644
--- a/libavcodec/wmv2dec.c
+++ b/libavcodec/wmv2dec.c
@@ -51,7 +51,6 @@ typedef struct WMV2DecContext {
     int cbp_table_index;
     int top_left_mv_flag;
     int per_mb_rl_bit;
-    int skip_type;
 
     DECLARE_ALIGNED(32, int16_t, abt_block2)[6][64];
 } WMV2DecContext;
@@ -106,8 +105,8 @@ static int parse_mb_skip(WMV2DecContext *w)
     int coded_mb_count = 0;
     uint32_t *const mb_type = h->c.cur_pic.mb_type;
 
-    w->skip_type = get_bits(&h->gb, 2);
-    switch (w->skip_type) {
+    int skip_type = get_bits(&h->gb, 2);
+    switch (skip_type) {
     case SKIP_TYPE_NONE:
         for (int mb_y = 0; mb_y < h->c.mb_height; mb_y++)
             for (int mb_x = 0; mb_x < h->c.mb_width; mb_x++)
-- 
2.49.1


>From 1cedc7d0d8417d8a1a5631fd5768b69e85151b6c Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 25 Jun 2025 07:33:13 +0200
Subject: [PATCH 05/14] avcodec/wmv2dec: Mark unreachable code as unreachable

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/wmv2dec.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c
index f4b4b4ac84..2421513adf 100644
--- a/libavcodec/wmv2dec.c
+++ b/libavcodec/wmv2dec.c
@@ -18,6 +18,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/avassert.h"
 #include "libavutil/mem_internal.h"
 
 #include "avcodec.h"
@@ -77,7 +78,7 @@ static void wmv2_add_block(WMV2DecContext *w, int16_t 
blocks1[][64],
             h->c.bdsp.clear_block(w->abt_block2[n]);
             break;
         default:
-            av_log(h->c.avctx, AV_LOG_ERROR, "internal error in WMV2 abt\n");
+            av_unreachable("abt_type_table is read via decode012");
         }
     }
 }
-- 
2.49.1


>From 98ee3df4a07ce262893339284b61f3400020a53b Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Tue, 30 Dec 2025 12:24:02 +0100
Subject: [PATCH 06/14] avcodec/msmpeg4: Mark unreachable code as unreachable

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/msmpeg4.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c
index 45c56a9ad9..bca8dbd524 100644
--- a/libavcodec/msmpeg4.c
+++ b/libavcodec/msmpeg4.c
@@ -30,6 +30,7 @@
 #include "config.h"
 #include "config_components.h"
 
+#include "libavutil/avassert.h"
 #include "libavutil/thread.h"
 #if ARCH_X86
 #include "libavutil/x86/asm.h"
@@ -122,6 +123,8 @@ av_cold void ff_msmpeg4_common_init(MpegEncContext *s)
     static AVOnce init_static_once = AV_ONCE_INIT;
 
     switch(s->msmpeg4_version){
+    default:
+        av_unreachable("ff_msmpeg4_common_init only called MSMP4 1-3 and 
WMV1/2");
     case MSMP4_V1:
     case MSMP4_V2:
         // Correct *_dc_scale_tables (ff_mpeg1_dc_scale_table) is the default
-- 
2.49.1


>From 0fed11931b698ce228c5de59646acb781e8cbb38 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 25 Jun 2025 08:30:22 +0200
Subject: [PATCH 07/14] avcodec/wmv2: Move ff_msmpel_motion() to the decoder

mspel is not supported by the encoder.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/mpegvideo_motion.c |  8 ++--
 libavcodec/wmv2.c             | 90 -----------------------------------
 libavcodec/wmv2.h             |  7 ---
 libavcodec/wmv2dec.c          | 89 ++++++++++++++++++++++++++++++++++
 libavcodec/wmv2dec.h          |  6 +++
 5 files changed, 100 insertions(+), 100 deletions(-)

diff --git a/libavcodec/mpegvideo_motion.c b/libavcodec/mpegvideo_motion.c
index a48b898dac..741927d809 100644
--- a/libavcodec/mpegvideo_motion.c
+++ b/libavcodec/mpegvideo_motion.c
@@ -34,7 +34,7 @@
 #include "mpegvideo.h"
 #include "mpeg4videodec.h"
 #include "qpeldsp.h"
-#include "wmv2.h"
+#include "wmv2dec.h"
 
 static inline int hpel_motion(MpegEncContext *s,
                               uint8_t *dest, uint8_t *src,
@@ -706,11 +706,13 @@ static av_always_inline void 
mpv_motion_internal(MpegEncContext *s,
                         0, 0, 0,
                         ref_picture, pix_op, qpix_op,
                         s->mv[dir][0][0], s->mv[dir][0][1], 16);
-        } else if (!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) 
&&
-                   s->mspel && s->codec_id == AV_CODEC_ID_WMV2) {
+#if CONFIG_WMV2_DECODER
+        } else if (!is_mpeg12 && s->mspel && s->codec_id == AV_CODEC_ID_WMV2) {
+            av_assert2(av_codec_is_decoder(s->avctx->codec));
             ff_mspel_motion(s, dest_y, dest_cb, dest_cr,
                             ref_picture, pix_op,
                             s->mv[dir][0][0], s->mv[dir][0][1], 16);
+#endif
         } else {
             mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,
                         ref_picture, pix_op,
diff --git a/libavcodec/wmv2.c b/libavcodec/wmv2.c
index d36ae66581..b29037cacb 100644
--- a/libavcodec/wmv2.c
+++ b/libavcodec/wmv2.c
@@ -18,7 +18,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "avcodec.h"
 #include "idctdsp.h"
 #include "mpegvideo.h"
 #include "wmv2.h"
@@ -36,92 +35,3 @@ av_cold void ff_wmv2_common_init(MpegEncContext *s)
     s->idsp.idct_add = w->wdsp.idct_add;
     s->idsp.idct     = NULL;
 }
-
-void ff_mspel_motion(MpegEncContext *s, uint8_t *dest_y,
-                     uint8_t *dest_cb, uint8_t *dest_cr,
-                     uint8_t *const *ref_picture,
-                     const op_pixels_func (*pix_op)[4],
-                     int motion_x, int motion_y, int h)
-{
-    WMV2Context *const w = s->private_ctx;
-    const uint8_t *ptr;
-    int dxy, mx, my, src_x, src_y, v_edge_pos;
-    ptrdiff_t offset, linesize, uvlinesize;
-    int emu = 0;
-
-    dxy   = ((motion_y & 1) << 1) | (motion_x & 1);
-    dxy   = 2 * dxy + w->hshift;
-    src_x = s->mb_x * 16 + (motion_x >> 1);
-    src_y = s->mb_y * 16 + (motion_y >> 1);
-
-    /* WARNING: do no forget half pels */
-    v_edge_pos = s->v_edge_pos;
-    src_x      = av_clip(src_x, -16, s->width);
-    src_y      = av_clip(src_y, -16, s->height);
-
-    if (src_x <= -16 || src_x >= s->width)
-        dxy &= ~3;
-    if (src_y <= -16 || src_y >= s->height)
-        dxy &= ~4;
-
-    linesize   = s->linesize;
-    uvlinesize = s->uvlinesize;
-    ptr        = ref_picture[0] + (src_y * linesize) + src_x;
-
-    if (src_x < 1 || src_y < 1 || src_x + 17 >= s->h_edge_pos ||
-        src_y + h + 1 >= v_edge_pos) {
-        s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr - 1 - s->linesize,
-                                 s->linesize, s->linesize, 19, 19,
-                                 src_x - 1, src_y - 1,
-                                 s->h_edge_pos, s->v_edge_pos);
-        ptr = s->sc.edge_emu_buffer + 1 + s->linesize;
-        emu = 1;
-    }
-
-    w->wdsp.put_mspel_pixels_tab[dxy](dest_y,                    ptr,          
          linesize);
-    w->wdsp.put_mspel_pixels_tab[dxy](dest_y     + 8,            ptr     + 8,  
          linesize);
-    w->wdsp.put_mspel_pixels_tab[dxy](dest_y     + 8 * linesize, ptr     + 8 * 
linesize, linesize);
-    w->wdsp.put_mspel_pixels_tab[dxy](dest_y + 8 + 8 * linesize, ptr + 8 + 8 * 
linesize, linesize);
-
-    if (s->avctx->flags & AV_CODEC_FLAG_GRAY)
-        return;
-
-    dxy = 0;
-    if ((motion_x & 3) != 0)
-        dxy |= 1;
-    if ((motion_y & 3) != 0)
-        dxy |= 2;
-    mx = motion_x >> 2;
-    my = motion_y >> 2;
-
-    src_x = s->mb_x * 8 + mx;
-    src_y = s->mb_y * 8 + my;
-    src_x = av_clip(src_x, -8, s->width >> 1);
-    if (src_x == (s->width >> 1))
-        dxy &= ~1;
-    src_y = av_clip(src_y, -8, s->height >> 1);
-    if (src_y == (s->height >> 1))
-        dxy &= ~2;
-    offset = (src_y * uvlinesize) + src_x;
-    ptr    = ref_picture[1] + offset;
-    if (emu) {
-        s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
-                                 s->uvlinesize, s->uvlinesize,
-                                 9, 9,
-                                 src_x, src_y,
-                                 s->h_edge_pos >> 1, s->v_edge_pos >> 1);
-        ptr = s->sc.edge_emu_buffer;
-    }
-    pix_op[1][dxy](dest_cb, ptr, uvlinesize, h >> 1);
-
-    ptr = ref_picture[2] + offset;
-    if (emu) {
-        s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
-                                 s->uvlinesize, s->uvlinesize,
-                                 9, 9,
-                                 src_x, src_y,
-                                 s->h_edge_pos >> 1, s->v_edge_pos >> 1);
-        ptr = s->sc.edge_emu_buffer;
-    }
-    pix_op[1][dxy](dest_cr, ptr, uvlinesize, h >> 1);
-}
diff --git a/libavcodec/wmv2.h b/libavcodec/wmv2.h
index 409d9456ab..b2767c6ca4 100644
--- a/libavcodec/wmv2.h
+++ b/libavcodec/wmv2.h
@@ -37,13 +37,6 @@ typedef struct WMV2Context {
 
 void ff_wmv2_common_init(MpegEncContext *s);
 
-void ff_mspel_motion(MpegEncContext *s,
-                     uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
-                     uint8_t *const *ref_picture,
-                     const op_pixels_func (*pix_op)[4],
-                     int motion_x, int motion_y, int h);
-
-
 static av_always_inline int wmv2_get_cbp_table_index(int qscale, int cbp_index)
 {
     static const uint8_t map[3][3] = {
diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c
index 2421513adf..554b784a5d 100644
--- a/libavcodec/wmv2dec.c
+++ b/libavcodec/wmv2dec.c
@@ -56,6 +56,95 @@ typedef struct WMV2DecContext {
     DECLARE_ALIGNED(32, int16_t, abt_block2)[6][64];
 } WMV2DecContext;
 
+void ff_mspel_motion(MPVContext *const s, uint8_t *dest_y,
+                     uint8_t *dest_cb, uint8_t *dest_cr,
+                     uint8_t *const *ref_picture,
+                     const op_pixels_func (*pix_op)[4],
+                     int motion_x, int motion_y, int h)
+{
+    WMV2Context *const w = s->private_ctx;
+    const uint8_t *ptr;
+    int dxy, mx, my, src_x, src_y, v_edge_pos;
+    ptrdiff_t offset, linesize, uvlinesize;
+    int emu = 0;
+
+    dxy   = ((motion_y & 1) << 1) | (motion_x & 1);
+    dxy   = 2 * dxy + w->hshift;
+    src_x = s->mb_x * 16 + (motion_x >> 1);
+    src_y = s->mb_y * 16 + (motion_y >> 1);
+
+    /* WARNING: do no forget half pels */
+    v_edge_pos = s->v_edge_pos;
+    src_x      = av_clip(src_x, -16, s->width);
+    src_y      = av_clip(src_y, -16, s->height);
+
+    if (src_x <= -16 || src_x >= s->width)
+        dxy &= ~3;
+    if (src_y <= -16 || src_y >= s->height)
+        dxy &= ~4;
+
+    linesize   = s->linesize;
+    uvlinesize = s->uvlinesize;
+    ptr        = ref_picture[0] + (src_y * linesize) + src_x;
+
+    if (src_x < 1 || src_y < 1 || src_x + 17 >= s->h_edge_pos ||
+        src_y + h + 1 >= v_edge_pos) {
+        s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr - 1 - s->linesize,
+                                 s->linesize, s->linesize, 19, 19,
+                                 src_x - 1, src_y - 1,
+                                 s->h_edge_pos, s->v_edge_pos);
+        ptr = s->sc.edge_emu_buffer + 1 + s->linesize;
+        emu = 1;
+    }
+
+    w->wdsp.put_mspel_pixels_tab[dxy](dest_y,                    ptr,          
          linesize);
+    w->wdsp.put_mspel_pixels_tab[dxy](dest_y     + 8,            ptr     + 8,  
          linesize);
+    w->wdsp.put_mspel_pixels_tab[dxy](dest_y     + 8 * linesize, ptr     + 8 * 
linesize, linesize);
+    w->wdsp.put_mspel_pixels_tab[dxy](dest_y + 8 + 8 * linesize, ptr + 8 + 8 * 
linesize, linesize);
+
+    if (s->avctx->flags & AV_CODEC_FLAG_GRAY)
+        return;
+
+    dxy = 0;
+    if ((motion_x & 3) != 0)
+        dxy |= 1;
+    if ((motion_y & 3) != 0)
+        dxy |= 2;
+    mx = motion_x >> 2;
+    my = motion_y >> 2;
+
+    src_x = s->mb_x * 8 + mx;
+    src_y = s->mb_y * 8 + my;
+    src_x = av_clip(src_x, -8, s->width >> 1);
+    if (src_x == (s->width >> 1))
+        dxy &= ~1;
+    src_y = av_clip(src_y, -8, s->height >> 1);
+    if (src_y == (s->height >> 1))
+        dxy &= ~2;
+    offset = (src_y * uvlinesize) + src_x;
+    ptr    = ref_picture[1] + offset;
+    if (emu) {
+        s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
+                                 s->uvlinesize, s->uvlinesize,
+                                 9, 9,
+                                 src_x, src_y,
+                                 s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+        ptr = s->sc.edge_emu_buffer;
+    }
+    pix_op[1][dxy](dest_cb, ptr, uvlinesize, h >> 1);
+
+    ptr = ref_picture[2] + offset;
+    if (emu) {
+        s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
+                                 s->uvlinesize, s->uvlinesize,
+                                 9, 9,
+                                 src_x, src_y,
+                                 s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+        ptr = s->sc.edge_emu_buffer;
+    }
+    pix_op[1][dxy](dest_cr, ptr, uvlinesize, h >> 1);
+}
+
 static void wmv2_add_block(WMV2DecContext *w, int16_t blocks1[][64],
                            uint8_t *dst, int stride, int n)
 {
diff --git a/libavcodec/wmv2dec.h b/libavcodec/wmv2dec.h
index 1bd0d13725..d19760b6c9 100644
--- a/libavcodec/wmv2dec.h
+++ b/libavcodec/wmv2dec.h
@@ -28,4 +28,10 @@ int ff_wmv2_decode_secondary_picture_header(struct 
H263DecContext *const h);
 void ff_wmv2_add_mb(MpegEncContext *s, int16_t block[6][64],
                     uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr);
 
+void ff_mspel_motion(MPVContext *const s,
+                     uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
+                     uint8_t *const *ref_picture,
+                     const op_pixels_func (*pix_op)[4],
+                     int motion_x, int motion_y, int h);
+
 #endif
-- 
2.49.1


>From d8b8e8700d6de977a3b6d0a1c8cc6ebb4f82a32b Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 25 Jun 2025 08:44:18 +0200
Subject: [PATCH 08/14] avcodec/wmv2dsp: Move mspel motion functions out of
 WMV2DSPContext

They are only used by the decoder (which has them twice, because
the IntraX8Context contains a WMV2DSPContext whose put_mspel_pixels
functions were unused), so move them there.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 configure            |   3 +-
 libavcodec/wmv2dec.c | 137 +++++++++++++++++++++++++++++++++++++++++--
 libavcodec/wmv2dsp.c | 119 -------------------------------------
 libavcodec/wmv2dsp.h |   5 +-
 4 files changed, 133 insertions(+), 131 deletions(-)

diff --git a/configure b/configure
index 301a3e5e3e..74e0345d88 100755
--- a/configure
+++ b/configure
@@ -2963,7 +2963,6 @@ msmpeg4dec_select="h263_decoder"
 msmpeg4enc_select="h263_encoder"
 vc1dsp_select="h264chroma startcode"
 vvc_sei_select="atsc_a53 golomb"
-wmv2dsp_select="qpeldsp"
 
 # decoders / encoders
 aac_decoder_select="adts_header mpeg4audio sinewin"
@@ -3225,7 +3224,7 @@ wmav2_encoder_select="sinewin wma_freqs"
 wmavoice_decoder_select="lsp sinewin"
 wmv1_decoder_select="msmpeg4dec"
 wmv1_encoder_select="msmpeg4enc"
-wmv2_decoder_select="blockdsp error_resilience idctdsp intrax8 msmpeg4dec 
videodsp wmv2dsp"
+wmv2_decoder_select="blockdsp error_resilience idctdsp intrax8 msmpeg4dec 
qpeldsp videodsp wmv2dsp"
 wmv2_encoder_select="msmpeg4enc wmv2dsp"
 wmv3_decoder_select="vc1_decoder"
 wmv3image_decoder_select="wmv3_decoder"
diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c
index 554b784a5d..749a8608a2 100644
--- a/libavcodec/wmv2dec.c
+++ b/libavcodec/wmv2dec.c
@@ -32,6 +32,7 @@
 #include "msmpeg4.h"
 #include "msmpeg4_vc1_data.h"
 #include "msmpeg4dec.h"
+#include "qpeldsp.h"
 #include "simple_idct.h"
 #include "wmv2.h"
 #include "wmv2data.h"
@@ -41,6 +42,9 @@ typedef struct WMV2DecContext {
     MSMP4DecContext ms;
     WMV2Context common;
     IntraX8Context x8;
+
+    qpel_mc_func put_mspel_pixels_tab[8];
+
     int j_type_bit;
     int j_type;
     int abt_flag;
@@ -56,20 +60,139 @@ typedef struct WMV2DecContext {
     DECLARE_ALIGNED(32, int16_t, abt_block2)[6][64];
 } WMV2DecContext;
 
+static void wmv2_mspel8_h_lowpass(uint8_t *dst, const uint8_t *src,
+                                  int dstStride, int srcStride, int h)
+{
+    const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+
+    for (int i = 0; i < h; i++) {
+        dst[0] = cm[(9 * (src[0] + src[1]) - (src[-1] + src[2]) + 8) >> 4];
+        dst[1] = cm[(9 * (src[1] + src[2]) - (src[0]  + src[3]) + 8) >> 4];
+        dst[2] = cm[(9 * (src[2] + src[3]) - (src[1]  + src[4]) + 8) >> 4];
+        dst[3] = cm[(9 * (src[3] + src[4]) - (src[2]  + src[5]) + 8) >> 4];
+        dst[4] = cm[(9 * (src[4] + src[5]) - (src[3]  + src[6]) + 8) >> 4];
+        dst[5] = cm[(9 * (src[5] + src[6]) - (src[4]  + src[7]) + 8) >> 4];
+        dst[6] = cm[(9 * (src[6] + src[7]) - (src[5]  + src[8]) + 8) >> 4];
+        dst[7] = cm[(9 * (src[7] + src[8]) - (src[6]  + src[9]) + 8) >> 4];
+        dst   += dstStride;
+        src   += srcStride;
+    }
+}
+
+static void wmv2_mspel8_v_lowpass(uint8_t *dst, const uint8_t *src,
+                                  int dstStride, int srcStride, int w)
+{
+    const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+
+    for (int i = 0; i < w; i++) {
+        const int src_1 = src[-srcStride];
+        const int src0  = src[0];
+        const int src1  = src[srcStride];
+        const int src2  = src[2 * srcStride];
+        const int src3  = src[3 * srcStride];
+        const int src4  = src[4 * srcStride];
+        const int src5  = src[5 * srcStride];
+        const int src6  = src[6 * srcStride];
+        const int src7  = src[7 * srcStride];
+        const int src8  = src[8 * srcStride];
+        const int src9  = src[9 * srcStride];
+        dst[0 * dstStride] = cm[(9 * (src0 + src1) - (src_1 + src2) + 8) >> 4];
+        dst[1 * dstStride] = cm[(9 * (src1 + src2) - (src0  + src3) + 8) >> 4];
+        dst[2 * dstStride] = cm[(9 * (src2 + src3) - (src1  + src4) + 8) >> 4];
+        dst[3 * dstStride] = cm[(9 * (src3 + src4) - (src2  + src5) + 8) >> 4];
+        dst[4 * dstStride] = cm[(9 * (src4 + src5) - (src3  + src6) + 8) >> 4];
+        dst[5 * dstStride] = cm[(9 * (src5 + src6) - (src4  + src7) + 8) >> 4];
+        dst[6 * dstStride] = cm[(9 * (src6 + src7) - (src5  + src8) + 8) >> 4];
+        dst[7 * dstStride] = cm[(9 * (src7 + src8) - (src6  + src9) + 8) >> 4];
+        src++;
+        dst++;
+    }
+}
+
+static void put_mspel8_mc10_c(uint8_t *dst, const uint8_t *src, ptrdiff_t 
stride)
+{
+    uint8_t half[64];
+
+    wmv2_mspel8_h_lowpass(half, src, 8, stride, 8);
+    ff_put_pixels8_l2_8(dst, src, half, stride, stride, 8, 8);
+}
+
+static void put_mspel8_mc20_c(uint8_t *dst, const uint8_t *src, ptrdiff_t 
stride)
+{
+    wmv2_mspel8_h_lowpass(dst, src, stride, stride, 8);
+}
+
+static void put_mspel8_mc30_c(uint8_t *dst, const uint8_t *src, ptrdiff_t 
stride)
+{
+    uint8_t half[64];
+
+    wmv2_mspel8_h_lowpass(half, src, 8, stride, 8);
+    ff_put_pixels8_l2_8(dst, src + 1, half, stride, stride, 8, 8);
+}
+
+static void put_mspel8_mc02_c(uint8_t *dst, const uint8_t *src, ptrdiff_t 
stride)
+{
+    wmv2_mspel8_v_lowpass(dst, src, stride, stride, 8);
+}
+
+static void put_mspel8_mc12_c(uint8_t *dst, const uint8_t *src, ptrdiff_t 
stride)
+{
+    uint8_t halfH[88];
+    uint8_t halfV[64];
+    uint8_t halfHV[64];
+
+    wmv2_mspel8_h_lowpass(halfH, src - stride, 8, stride, 11);
+    wmv2_mspel8_v_lowpass(halfV, src, 8, stride, 8);
+    wmv2_mspel8_v_lowpass(halfHV, halfH + 8, 8, 8, 8);
+    ff_put_pixels8_l2_8(dst, halfV, halfHV, stride, 8, 8, 8);
+}
+
+static void put_mspel8_mc32_c(uint8_t *dst, const uint8_t *src, ptrdiff_t 
stride)
+{
+    uint8_t halfH[88];
+    uint8_t halfV[64];
+    uint8_t halfHV[64];
+
+    wmv2_mspel8_h_lowpass(halfH, src - stride, 8, stride, 11);
+    wmv2_mspel8_v_lowpass(halfV, src + 1, 8, stride, 8);
+    wmv2_mspel8_v_lowpass(halfHV, halfH + 8, 8, 8, 8);
+    ff_put_pixels8_l2_8(dst, halfV, halfHV, stride, 8, 8, 8);
+}
+
+static void put_mspel8_mc22_c(uint8_t *dst, const uint8_t *src, ptrdiff_t 
stride)
+{
+    uint8_t halfH[88];
+
+    wmv2_mspel8_h_lowpass(halfH, src - stride, 8, stride, 11);
+    wmv2_mspel8_v_lowpass(dst, halfH + 8, stride, 8, 8);
+}
+
+static av_cold void wmv2_mspel_init(WMV2DecContext *w)
+{
+    w->put_mspel_pixels_tab[0] = ff_put_pixels8x8_c;
+    w->put_mspel_pixels_tab[1] = put_mspel8_mc10_c;
+    w->put_mspel_pixels_tab[2] = put_mspel8_mc20_c;
+    w->put_mspel_pixels_tab[3] = put_mspel8_mc30_c;
+    w->put_mspel_pixels_tab[4] = put_mspel8_mc02_c;
+    w->put_mspel_pixels_tab[5] = put_mspel8_mc12_c;
+    w->put_mspel_pixels_tab[6] = put_mspel8_mc22_c;
+    w->put_mspel_pixels_tab[7] = put_mspel8_mc32_c;
+}
+
 void ff_mspel_motion(MPVContext *const s, uint8_t *dest_y,
                      uint8_t *dest_cb, uint8_t *dest_cr,
                      uint8_t *const *ref_picture,
                      const op_pixels_func (*pix_op)[4],
                      int motion_x, int motion_y, int h)
 {
-    WMV2Context *const w = s->private_ctx;
+    WMV2DecContext *const w = (WMV2DecContext *) s;
     const uint8_t *ptr;
     int dxy, mx, my, src_x, src_y, v_edge_pos;
     ptrdiff_t offset, linesize, uvlinesize;
     int emu = 0;
 
     dxy   = ((motion_y & 1) << 1) | (motion_x & 1);
-    dxy   = 2 * dxy + w->hshift;
+    dxy   = 2 * dxy + w->common.hshift;
     src_x = s->mb_x * 16 + (motion_x >> 1);
     src_y = s->mb_y * 16 + (motion_y >> 1);
 
@@ -97,10 +220,10 @@ void ff_mspel_motion(MPVContext *const s, uint8_t *dest_y,
         emu = 1;
     }
 
-    w->wdsp.put_mspel_pixels_tab[dxy](dest_y,                    ptr,          
          linesize);
-    w->wdsp.put_mspel_pixels_tab[dxy](dest_y     + 8,            ptr     + 8,  
          linesize);
-    w->wdsp.put_mspel_pixels_tab[dxy](dest_y     + 8 * linesize, ptr     + 8 * 
linesize, linesize);
-    w->wdsp.put_mspel_pixels_tab[dxy](dest_y + 8 + 8 * linesize, ptr + 8 + 8 * 
linesize, linesize);
+    w->put_mspel_pixels_tab[dxy](dest_y,                    ptr,               
     linesize);
+    w->put_mspel_pixels_tab[dxy](dest_y     + 8,            ptr     + 8,       
     linesize);
+    w->put_mspel_pixels_tab[dxy](dest_y     + 8 * linesize, ptr     + 8 * 
linesize, linesize);
+    w->put_mspel_pixels_tab[dxy](dest_y + 8 + 8 * linesize, ptr + 8 + 8 * 
linesize, linesize);
 
     if (s->avctx->flags & AV_CODEC_FLAG_GRAY)
         return;
@@ -659,6 +782,8 @@ static av_cold int wmv2_decode_init(AVCodecContext *avctx)
     MpegEncContext *const s = &h->c;
     int ret;
 
+    wmv2_mspel_init(w);
+
     s->private_ctx = &w->common;
 
     if ((ret = ff_msmpeg4_decode_init(avctx)) < 0)
diff --git a/libavcodec/wmv2dsp.c b/libavcodec/wmv2dsp.c
index 4ad8a596b8..2616f133ba 100644
--- a/libavcodec/wmv2dsp.c
+++ b/libavcodec/wmv2dsp.c
@@ -21,7 +21,6 @@
 #include "libavutil/common.h"
 #include "idctdsp.h"
 #include "mathops.h"
-#include "qpeldsp.h"
 #include "wmv2dsp.h"
 
 #define W0 2048
@@ -140,130 +139,12 @@ static void wmv2_idct_put_c(uint8_t *dest, ptrdiff_t 
line_size, int16_t *block)
     }
 }
 
-static void wmv2_mspel8_h_lowpass(uint8_t *dst, const uint8_t *src,
-                                  int dstStride, int srcStride, int h)
-{
-    const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
-    int i;
-
-    for (i = 0; i < h; i++) {
-        dst[0] = cm[(9 * (src[0] + src[1]) - (src[-1] + src[2]) + 8) >> 4];
-        dst[1] = cm[(9 * (src[1] + src[2]) - (src[0]  + src[3]) + 8) >> 4];
-        dst[2] = cm[(9 * (src[2] + src[3]) - (src[1]  + src[4]) + 8) >> 4];
-        dst[3] = cm[(9 * (src[3] + src[4]) - (src[2]  + src[5]) + 8) >> 4];
-        dst[4] = cm[(9 * (src[4] + src[5]) - (src[3]  + src[6]) + 8) >> 4];
-        dst[5] = cm[(9 * (src[5] + src[6]) - (src[4]  + src[7]) + 8) >> 4];
-        dst[6] = cm[(9 * (src[6] + src[7]) - (src[5]  + src[8]) + 8) >> 4];
-        dst[7] = cm[(9 * (src[7] + src[8]) - (src[6]  + src[9]) + 8) >> 4];
-        dst   += dstStride;
-        src   += srcStride;
-    }
-}
-
-static void wmv2_mspel8_v_lowpass(uint8_t *dst, const uint8_t *src,
-                                  int dstStride, int srcStride, int w)
-{
-    const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
-    int i;
-
-    for (i = 0; i < w; i++) {
-        const int src_1 = src[-srcStride];
-        const int src0  = src[0];
-        const int src1  = src[srcStride];
-        const int src2  = src[2 * srcStride];
-        const int src3  = src[3 * srcStride];
-        const int src4  = src[4 * srcStride];
-        const int src5  = src[5 * srcStride];
-        const int src6  = src[6 * srcStride];
-        const int src7  = src[7 * srcStride];
-        const int src8  = src[8 * srcStride];
-        const int src9  = src[9 * srcStride];
-        dst[0 * dstStride] = cm[(9 * (src0 + src1) - (src_1 + src2) + 8) >> 4];
-        dst[1 * dstStride] = cm[(9 * (src1 + src2) - (src0  + src3) + 8) >> 4];
-        dst[2 * dstStride] = cm[(9 * (src2 + src3) - (src1  + src4) + 8) >> 4];
-        dst[3 * dstStride] = cm[(9 * (src3 + src4) - (src2  + src5) + 8) >> 4];
-        dst[4 * dstStride] = cm[(9 * (src4 + src5) - (src3  + src6) + 8) >> 4];
-        dst[5 * dstStride] = cm[(9 * (src5 + src6) - (src4  + src7) + 8) >> 4];
-        dst[6 * dstStride] = cm[(9 * (src6 + src7) - (src5  + src8) + 8) >> 4];
-        dst[7 * dstStride] = cm[(9 * (src7 + src8) - (src6  + src9) + 8) >> 4];
-        src++;
-        dst++;
-    }
-}
-
-static void put_mspel8_mc10_c(uint8_t *dst, const uint8_t *src, ptrdiff_t 
stride)
-{
-    uint8_t half[64];
-
-    wmv2_mspel8_h_lowpass(half, src, 8, stride, 8);
-    ff_put_pixels8_l2_8(dst, src, half, stride, stride, 8, 8);
-}
-
-static void put_mspel8_mc20_c(uint8_t *dst, const uint8_t *src, ptrdiff_t 
stride)
-{
-    wmv2_mspel8_h_lowpass(dst, src, stride, stride, 8);
-}
-
-static void put_mspel8_mc30_c(uint8_t *dst, const uint8_t *src, ptrdiff_t 
stride)
-{
-    uint8_t half[64];
-
-    wmv2_mspel8_h_lowpass(half, src, 8, stride, 8);
-    ff_put_pixels8_l2_8(dst, src + 1, half, stride, stride, 8, 8);
-}
-
-static void put_mspel8_mc02_c(uint8_t *dst, const uint8_t *src, ptrdiff_t 
stride)
-{
-    wmv2_mspel8_v_lowpass(dst, src, stride, stride, 8);
-}
-
-static void put_mspel8_mc12_c(uint8_t *dst, const uint8_t *src, ptrdiff_t 
stride)
-{
-    uint8_t halfH[88];
-    uint8_t halfV[64];
-    uint8_t halfHV[64];
-
-    wmv2_mspel8_h_lowpass(halfH, src - stride, 8, stride, 11);
-    wmv2_mspel8_v_lowpass(halfV, src, 8, stride, 8);
-    wmv2_mspel8_v_lowpass(halfHV, halfH + 8, 8, 8, 8);
-    ff_put_pixels8_l2_8(dst, halfV, halfHV, stride, 8, 8, 8);
-}
-
-static void put_mspel8_mc32_c(uint8_t *dst, const uint8_t *src, ptrdiff_t 
stride)
-{
-    uint8_t halfH[88];
-    uint8_t halfV[64];
-    uint8_t halfHV[64];
-
-    wmv2_mspel8_h_lowpass(halfH, src - stride, 8, stride, 11);
-    wmv2_mspel8_v_lowpass(halfV, src + 1, 8, stride, 8);
-    wmv2_mspel8_v_lowpass(halfHV, halfH + 8, 8, 8, 8);
-    ff_put_pixels8_l2_8(dst, halfV, halfHV, stride, 8, 8, 8);
-}
-
-static void put_mspel8_mc22_c(uint8_t *dst, const uint8_t *src, ptrdiff_t 
stride)
-{
-    uint8_t halfH[88];
-
-    wmv2_mspel8_h_lowpass(halfH, src - stride, 8, stride, 11);
-    wmv2_mspel8_v_lowpass(dst, halfH + 8, stride, 8, 8);
-}
-
 av_cold void ff_wmv2dsp_init(WMV2DSPContext *c)
 {
     c->idct_add  = wmv2_idct_add_c;
     c->idct_put  = wmv2_idct_put_c;
     c->idct_perm = FF_IDCT_PERM_NONE;
 
-    c->put_mspel_pixels_tab[0] = ff_put_pixels8x8_c;
-    c->put_mspel_pixels_tab[1] = put_mspel8_mc10_c;
-    c->put_mspel_pixels_tab[2] = put_mspel8_mc20_c;
-    c->put_mspel_pixels_tab[3] = put_mspel8_mc30_c;
-    c->put_mspel_pixels_tab[4] = put_mspel8_mc02_c;
-    c->put_mspel_pixels_tab[5] = put_mspel8_mc12_c;
-    c->put_mspel_pixels_tab[6] = put_mspel8_mc22_c;
-    c->put_mspel_pixels_tab[7] = put_mspel8_mc32_c;
-
 #if ARCH_MIPS
     ff_wmv2dsp_init_mips(c);
 #endif
diff --git a/libavcodec/wmv2dsp.h b/libavcodec/wmv2dsp.h
index 5e40b30a20..6906dc29f2 100644
--- a/libavcodec/wmv2dsp.h
+++ b/libavcodec/wmv2dsp.h
@@ -19,16 +19,13 @@
 #ifndef AVCODEC_WMV2DSP_H
 #define AVCODEC_WMV2DSP_H
 
+#include <stddef.h>
 #include <stdint.h>
 
-#include "qpeldsp.h"
-
 typedef struct WMV2DSPContext {
     void (*idct_add)(uint8_t *dest, ptrdiff_t line_size, int16_t *block);
     void (*idct_put)(uint8_t *dest, ptrdiff_t line_size, int16_t *block);
 
-    qpel_mc_func put_mspel_pixels_tab[8];
-
     int idct_perm;
 } WMV2DSPContext;
 
-- 
2.49.1


>From 0e1dc227f8d4b14e3d632a9f27f26366a6d87951 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Tue, 30 Dec 2025 11:38:59 +0100
Subject: [PATCH 09/14] avcodec/wmv2dsp: Modify IDCTDSPContext directly

This allows to remove ff_wmv2_common_init() altogether.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/Makefile                 |  4 ++--
 libavcodec/intrax8.c                | 15 +++++-------
 libavcodec/intrax8.h                |  4 ++--
 libavcodec/mips/wmv2dsp_init_mips.c |  4 +++-
 libavcodec/mips/wmv2dsp_mips.h      |  3 ++-
 libavcodec/msmpeg4.c                |  4 ++--
 libavcodec/wmv2.c                   | 37 -----------------------------
 libavcodec/wmv2.h                   |  8 +++----
 libavcodec/wmv2dec.c                |  2 +-
 libavcodec/wmv2dsp.c                |  7 ++++--
 libavcodec/wmv2dsp.h                | 14 +++--------
 11 files changed, 29 insertions(+), 73 deletions(-)
 delete mode 100644 libavcodec/wmv2.c

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 28ad85afb4..3d60347a19 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -854,8 +854,8 @@ OBJS-$(CONFIG_WMAV2_ENCODER)           += wmaenc.o wma.o 
wma_common.o aactab.o
 OBJS-$(CONFIG_WMAVOICE_DECODER)        += wmavoice.o \
                                           celp_filters.o \
                                           acelp_vectors.o acelp_filters.o
-OBJS-$(CONFIG_WMV2_DECODER)            += wmv2dec.o wmv2.o wmv2data.o
-OBJS-$(CONFIG_WMV2_ENCODER)            += wmv2enc.o wmv2.o wmv2data.o
+OBJS-$(CONFIG_WMV2_DECODER)            += wmv2dec.o wmv2data.o
+OBJS-$(CONFIG_WMV2_ENCODER)            += wmv2enc.o wmv2data.o
 OBJS-$(CONFIG_WNV1_DECODER)            += wnv1.o
 OBJS-$(CONFIG_WRAPPED_AVFRAME_DECODER) += wrapped_avframe.o
 OBJS-$(CONFIG_WRAPPED_AVFRAME_ENCODER) += wrapped_avframe.o
diff --git a/libavcodec/intrax8.c b/libavcodec/intrax8.c
index 89b70e5902..ada5fc317f 100644
--- a/libavcodec/intrax8.c
+++ b/libavcodec/intrax8.c
@@ -437,7 +437,7 @@ static void x8_ac_compensation(IntraX8Context *const w, 
const int direction,
                                const int dc_level)
 {
     int t;
-#define B(x,y)  w->block[w->idct_permutation[(x) + (y) * 8]]
+#define B(x,y)  w->block[w->idsp.idct_permutation[(x) + (y) * 8]]
 #define T(x)  ((x) * dc_level + 0x8000) >> 16;
     switch (direction) {
     case 0:
@@ -637,7 +637,7 @@ static int x8_decode_intra_mb(IntraX8Context *const w, 
const int chroma)
                                                w->frame->linesize[!!chroma]);
     }
     if (!zeros_only)
-        w->wdsp.idct_add(w->dest[chroma],
+        w->idsp.idct_add(w->dest[chroma],
                          w->frame->linesize[!!chroma],
                          w->block);
 
@@ -693,17 +693,14 @@ av_cold int ff_intrax8_common_init(AVCodecContext *avctx,
     if (!w->prediction_table)
         return AVERROR(ENOMEM);
 
-    ff_wmv2dsp_init(&w->wdsp);
-
-    ff_init_scantable_permutation(w->idct_permutation,
-                                  w->wdsp.idct_perm);
+    ff_wmv2dsp_init(&w->idsp);
 
     ff_permute_scantable(w->permutated_scantable[0], ff_wmv1_scantable[0],
-                         w->idct_permutation);
+                         w->idsp.idct_permutation);
     ff_permute_scantable(w->permutated_scantable[1], ff_wmv1_scantable[2],
-                         w->idct_permutation);
+                         w->idsp.idct_permutation);
     ff_permute_scantable(w->permutated_scantable[2], ff_wmv1_scantable[3],
-                         w->idct_permutation);
+                         w->idsp.idct_permutation);
 
     ff_intrax8dsp_init(&w->dsp);
     ff_blockdsp_init(&w->bdsp);
diff --git a/libavcodec/intrax8.h b/libavcodec/intrax8.h
index 2ec90963a8..a936299fbb 100644
--- a/libavcodec/intrax8.h
+++ b/libavcodec/intrax8.h
@@ -21,6 +21,7 @@
 
 #include "blockdsp.h"
 #include "get_bits.h"
+#include "idctdsp.h"
 #include "intrax8dsp.h"
 #include "wmv2dsp.h"
 #include "mpegpicture.h"
@@ -35,8 +36,7 @@ typedef struct IntraX8Context {
     // set by ff_intrax8_common_init
     uint8_t *prediction_table; // 2 * (mb_w * 2)
     uint8_t permutated_scantable[3][64];
-    WMV2DSPContext wdsp;
-    uint8_t idct_permutation[64];
+    IDCTDSPContext idsp;
     AVCodecContext *avctx;
     int16_t *block;
 
diff --git a/libavcodec/mips/wmv2dsp_init_mips.c 
b/libavcodec/mips/wmv2dsp_init_mips.c
index af1400731a..e48413b9a4 100644
--- a/libavcodec/mips/wmv2dsp_init_mips.c
+++ b/libavcodec/mips/wmv2dsp_init_mips.c
@@ -21,9 +21,11 @@
 #include "libavutil/mips/cpu.h"
 #include "config.h"
 #include "libavutil/attributes.h"
+#include "libavcodec/idctdsp.h"
+#include "libavcodec/wmv2dsp.h"
 #include "wmv2dsp_mips.h"
 
-av_cold void ff_wmv2dsp_init_mips(WMV2DSPContext *c)
+av_cold void ff_wmv2dsp_init_mips(IDCTDSPContext *c)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/mips/wmv2dsp_mips.h b/libavcodec/mips/wmv2dsp_mips.h
index c96b3d94c7..94fbd8f6b7 100644
--- a/libavcodec/mips/wmv2dsp_mips.h
+++ b/libavcodec/mips/wmv2dsp_mips.h
@@ -21,7 +21,8 @@
 #ifndef AVCODEC_MIPS_WMV2DSP_MIPS_H
 #define AVCODEC_MIPS_WMV2DSP_MIPS_H
 
-#include "libavcodec/wmv2dsp.h"
+#include <stddef.h>
+#include <stdint.h>
 
 void ff_wmv2_idct_add_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block);
 void ff_wmv2_idct_put_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block);
diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c
index bca8dbd524..3711c37e5c 100644
--- a/libavcodec/msmpeg4.c
+++ b/libavcodec/msmpeg4.c
@@ -44,7 +44,7 @@
 #include "mpeg4videodata.h"
 #include "msmpeg4data.h"
 #include "msmpeg4_vc1_data.h"
-#include "wmv2.h"
+#include "wmv2dsp.h"
 
 /*
  * You can also call this codec: MPEG-4 with a twist!
@@ -140,7 +140,7 @@ av_cold void ff_msmpeg4_common_init(MpegEncContext *s)
         break;
 #if CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER
     case MSMP4_WMV2:
-        ff_wmv2_common_init(s);
+        ff_wmv2dsp_init(&s->idsp);
         // fallthrough
 #endif
     case MSMP4_WMV1:
diff --git a/libavcodec/wmv2.c b/libavcodec/wmv2.c
deleted file mode 100644
index b29037cacb..0000000000
--- a/libavcodec/wmv2.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2002 The FFmpeg Project
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "idctdsp.h"
-#include "mpegvideo.h"
-#include "wmv2.h"
-
-
-av_cold void ff_wmv2_common_init(MpegEncContext *s)
-{
-    WMV2Context *const w = s->private_ctx;
-
-    ff_wmv2dsp_init(&w->wdsp);
-    s->idsp.perm_type = w->wdsp.idct_perm;
-    ff_init_scantable_permutation(s->idsp.idct_permutation,
-                                  w->wdsp.idct_perm);
-    s->idsp.idct_put = w->wdsp.idct_put;
-    s->idsp.idct_add = w->wdsp.idct_add;
-    s->idsp.idct     = NULL;
-}
diff --git a/libavcodec/wmv2.h b/libavcodec/wmv2.h
index b2767c6ca4..e97ee658ba 100644
--- a/libavcodec/wmv2.h
+++ b/libavcodec/wmv2.h
@@ -21,8 +21,9 @@
 #ifndef AVCODEC_WMV2_H
 #define AVCODEC_WMV2_H
 
-#include "mpegvideo.h"
-#include "wmv2dsp.h"
+#include <stdint.h>
+
+#include "libavutil/attributes.h"
 
 #define SKIP_TYPE_NONE 0
 #define SKIP_TYPE_MPEG 1
@@ -31,12 +32,9 @@
 
 
 typedef struct WMV2Context {
-    WMV2DSPContext wdsp;
     int hshift;
 } WMV2Context;
 
-void ff_wmv2_common_init(MpegEncContext *s);
-
 static av_always_inline int wmv2_get_cbp_table_index(int qscale, int cbp_index)
 {
     static const uint8_t map[3][3] = {
diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c
index 749a8608a2..756ab9a44d 100644
--- a/libavcodec/wmv2dec.c
+++ b/libavcodec/wmv2dec.c
@@ -277,7 +277,7 @@ static void wmv2_add_block(WMV2DecContext *w, int16_t 
blocks1[][64],
         int16_t *block1 = blocks1[n];
         switch (w->abt_type_table[n]) {
         case 0:
-            w->common.wdsp.idct_add(dst, stride, block1);
+            h->c.idsp.idct_add(dst, stride, block1);
             break;
         case 1:
             ff_simple_idct84_add(dst, stride, block1);
diff --git a/libavcodec/wmv2dsp.c b/libavcodec/wmv2dsp.c
index 2616f133ba..7ebe4b614c 100644
--- a/libavcodec/wmv2dsp.c
+++ b/libavcodec/wmv2dsp.c
@@ -139,13 +139,16 @@ static void wmv2_idct_put_c(uint8_t *dest, ptrdiff_t 
line_size, int16_t *block)
     }
 }
 
-av_cold void ff_wmv2dsp_init(WMV2DSPContext *c)
+av_cold void ff_wmv2dsp_init(IDCTDSPContext *c)
 {
     c->idct_add  = wmv2_idct_add_c;
     c->idct_put  = wmv2_idct_put_c;
-    c->idct_perm = FF_IDCT_PERM_NONE;
+    c->idct      = NULL;
+    c->perm_type = FF_IDCT_PERM_NONE;
 
 #if ARCH_MIPS
     ff_wmv2dsp_init_mips(c);
 #endif
+    ff_init_scantable_permutation(c->idct_permutation,
+                                  c->perm_type);
 }
diff --git a/libavcodec/wmv2dsp.h b/libavcodec/wmv2dsp.h
index 6906dc29f2..1402dbb96d 100644
--- a/libavcodec/wmv2dsp.h
+++ b/libavcodec/wmv2dsp.h
@@ -19,17 +19,9 @@
 #ifndef AVCODEC_WMV2DSP_H
 #define AVCODEC_WMV2DSP_H
 
-#include <stddef.h>
-#include <stdint.h>
+struct IDCTDSPContext;
 
-typedef struct WMV2DSPContext {
-    void (*idct_add)(uint8_t *dest, ptrdiff_t line_size, int16_t *block);
-    void (*idct_put)(uint8_t *dest, ptrdiff_t line_size, int16_t *block);
-
-    int idct_perm;
-} WMV2DSPContext;
-
-void ff_wmv2dsp_init(WMV2DSPContext *c);
-void ff_wmv2dsp_init_mips(WMV2DSPContext *c);
+void ff_wmv2dsp_init(struct IDCTDSPContext *c);
+void ff_wmv2dsp_init_mips(struct IDCTDSPContext *c);
 
 #endif /* AVCODEC_WMV2DSP_H */
-- 
2.49.1


>From 90910655ed5809b3915ce75997b5b12c1f3de7ba Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 25 Jun 2025 09:10:26 +0200
Subject: [PATCH 10/14] avcodec/wmv2: Remove WMV2Context

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/wmv2.h    |  5 -----
 libavcodec/wmv2dec.c | 12 +++++-------
 libavcodec/wmv2enc.c |  3 +--
 3 files changed, 6 insertions(+), 14 deletions(-)

diff --git a/libavcodec/wmv2.h b/libavcodec/wmv2.h
index e97ee658ba..aef3126867 100644
--- a/libavcodec/wmv2.h
+++ b/libavcodec/wmv2.h
@@ -30,11 +30,6 @@
 #define SKIP_TYPE_ROW  2
 #define SKIP_TYPE_COL  3
 
-
-typedef struct WMV2Context {
-    int hshift;
-} WMV2Context;
-
 static av_always_inline int wmv2_get_cbp_table_index(int qscale, int cbp_index)
 {
     static const uint8_t map[3][3] = {
diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c
index 756ab9a44d..22102ef6df 100644
--- a/libavcodec/wmv2dec.c
+++ b/libavcodec/wmv2dec.c
@@ -40,7 +40,6 @@
 
 typedef struct WMV2DecContext {
     MSMP4DecContext ms;
-    WMV2Context common;
     IntraX8Context x8;
 
     qpel_mc_func put_mspel_pixels_tab[8];
@@ -56,6 +55,7 @@ typedef struct WMV2DecContext {
     int cbp_table_index;
     int top_left_mv_flag;
     int per_mb_rl_bit;
+    int hshift;
 
     DECLARE_ALIGNED(32, int16_t, abt_block2)[6][64];
 } WMV2DecContext;
@@ -192,7 +192,7 @@ void ff_mspel_motion(MPVContext *const s, uint8_t *dest_y,
     int emu = 0;
 
     dxy   = ((motion_y & 1) << 1) | (motion_x & 1);
-    dxy   = 2 * dxy + w->common.hshift;
+    dxy   = 2 * dxy + w->hshift;
     src_x = s->mb_x * 16 + (motion_x >> 1);
     src_y = s->mb_y * 16 + (motion_y >> 1);
 
@@ -564,9 +564,9 @@ static inline void wmv2_decode_motion(WMV2DecContext *w, 
int *mx_ptr, int *my_pt
     ff_msmpeg4_decode_motion(&w->ms, mx_ptr, my_ptr);
 
     if ((((*mx_ptr) | (*my_ptr)) & 1) && h->c.mspel)
-        w->common.hshift = get_bits1(&h->gb);
+        w->hshift = get_bits1(&h->gb);
     else
-        w->common.hshift = 0;
+        w->hshift = 0;
 }
 
 static int16_t *wmv2_pred_motion(WMV2DecContext *w, int *px, int *py)
@@ -678,7 +678,7 @@ static int wmv2_decode_mb(H263DecContext *const h)
             h->c.mv[0][0][0] = 0;
             h->c.mv[0][0][1] = 0;
             h->c.mb_skipped  = 1;
-            w->common.hshift      = 0;
+            w->hshift        = 0;
             return 0;
         }
         if (get_bits_left(&h->gb) <= 0)
@@ -784,8 +784,6 @@ static av_cold int wmv2_decode_init(AVCodecContext *avctx)
 
     wmv2_mspel_init(w);
 
-    s->private_ctx = &w->common;
-
     if ((ret = ff_msmpeg4_decode_init(avctx)) < 0)
         return ret;
 
diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c
index 5b3e2ae116..4082b58179 100644
--- a/libavcodec/wmv2enc.c
+++ b/libavcodec/wmv2enc.c
@@ -35,7 +35,6 @@
 
 typedef struct WMV2EncContext {
     MSMPEG4EncContext msmpeg4;
-    WMV2Context common;
     int j_type_bit;
     int j_type;
     int abt_flag;
@@ -228,7 +227,7 @@ static av_cold int wmv2_encode_init(AVCodecContext *avctx)
 
     w->msmpeg4.m.encode_picture_header = wmv2_encode_picture_header;
     s->encode_mb                       = wmv2_encode_mb;
-    s->c.private_ctx = &w->common;
+
     ret = ff_mpv_encode_init(avctx);
     if (ret < 0)
         return ret;
-- 
2.49.1


>From 4e99ab3262578f4d5bdfbff9ef04c5706fbfd221 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 25 Jun 2025 09:16:36 +0200
Subject: [PATCH 11/14] avcodec/wmv2dec: Avoid indirection

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/wmv2dec.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c
index 22102ef6df..22b9b15e44 100644
--- a/libavcodec/wmv2dec.c
+++ b/libavcodec/wmv2dec.c
@@ -376,17 +376,17 @@ static int parse_mb_skip(WMV2DecContext *w)
     return 0;
 }
 
-static int decode_ext_header(WMV2DecContext *w)
+static av_cold int decode_ext_header(AVCodecContext *avctx, WMV2DecContext *w)
 {
     H263DecContext *const h = &w->ms.h;
     GetBitContext gb;
     int fps;
     int code;
 
-    if (h->c.avctx->extradata_size < 4)
+    if (avctx->extradata_size < 4)
         return AVERROR_INVALIDDATA;
 
-    init_get_bits(&gb, h->c.avctx->extradata, 32);
+    init_get_bits(&gb, avctx->extradata, 32);
 
     fps                 = get_bits(&gb, 5);
     w->ms.bit_rate      = get_bits(&gb, 11) * 1024;
@@ -403,8 +403,8 @@ static int decode_ext_header(WMV2DecContext *w)
 
     h->slice_height = h->c.mb_height / code;
 
-    if (h->c.avctx->debug & FF_DEBUG_PICT_INFO)
-        av_log(h->c.avctx, AV_LOG_DEBUG,
+    if (avctx->debug & FF_DEBUG_PICT_INFO)
+        av_log(avctx, AV_LOG_DEBUG,
                "fps:%d, br:%d, qpbit:%d, abt_flag:%d, j_type_bit:%d, "
                "tl_mv_flag:%d, mbrl_bit:%d, code:%d, loop_filter:%d, "
                "slices:%d\n",
@@ -790,7 +790,7 @@ static av_cold int wmv2_decode_init(AVCodecContext *avctx)
     h->decode_header = wmv2_decode_picture_header;
     h->decode_mb = wmv2_decode_mb;
 
-    decode_ext_header(w);
+    decode_ext_header(avctx, w);
 
     return ff_intrax8_common_init(avctx, &w->x8, h->block[0],
                                   s->mb_width, s->mb_height);
-- 
2.49.1


>From 500355be1d635b5c20f2d97ba3faaf73cac226e2 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 25 Jun 2025 09:39:52 +0200
Subject: [PATCH 12/14] avcodec/mpegvideo: Move permutated_intra scans to
 {H263Dec,MPVEnc}Ctx

Only used by these two.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/h263dec.c       |  5 +++++
 libavcodec/h263dec.h       |  3 +++
 libavcodec/ituh263dec.c    |  4 ++--
 libavcodec/ituh263enc.c    |  6 ++++++
 libavcodec/mpeg4videodec.c | 30 ++++++++++++++++--------------
 libavcodec/mpeg4videoenc.c |  4 ++--
 libavcodec/mpegvideo.c     |  4 ----
 libavcodec/mpegvideo.h     |  3 ---
 libavcodec/mpegvideoenc.h  |  3 +++
 libavcodec/msmpeg4.c       |  8 +++++---
 libavcodec/msmpeg4.h       |  4 +++-
 libavcodec/msmpeg4dec.c    |  7 ++++---
 libavcodec/msmpeg4enc.c    |  3 ++-
 13 files changed, 51 insertions(+), 33 deletions(-)

diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index b4c8aa38f5..23fd16b726 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -108,6 +108,11 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx)
     s->y_dc_scale_table =
     s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
 
+    ff_permute_scantable(h->permutated_intra_h_scantable, 
ff_alternate_horizontal_scan,
+                         s->idsp.idct_permutation);
+    ff_permute_scantable(h->permutated_intra_v_scantable, 
ff_alternate_vertical_scan,
+                         s->idsp.idct_permutation);
+
     ff_mpv_unquantize_init(&unquant_dsp_ctx,
                            avctx->flags & AV_CODEC_FLAG_BITEXACT, 0);
     // dct_unquantize defaults for H.263;
diff --git a/libavcodec/h263dec.h b/libavcodec/h263dec.h
index 4c25a833cf..ab647f5224 100644
--- a/libavcodec/h263dec.h
+++ b/libavcodec/h263dec.h
@@ -97,6 +97,9 @@ typedef struct H263DecContext {
 
     GetBitContext last_resync_gb;    ///< used to search for the next resync 
marker
 
+    uint8_t permutated_intra_h_scantable[64];
+    uint8_t permutated_intra_v_scantable[64];
+
     DECLARE_ALIGNED_32(int16_t, block)[6][64];
 } H263DecContext;
 
diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c
index a1472ce0a0..53ead30c48 100644
--- a/libavcodec/ituh263dec.c
+++ b/libavcodec/ituh263dec.c
@@ -542,9 +542,9 @@ static int h263_decode_block(H263DecContext *const h, 
int16_t block[64],
         rl = &ff_rl_intra_aic;
         if (h->c.ac_pred) {
             if (h->c.h263_aic_dir)
-                scan_table = h->c.permutated_intra_v_scantable; /* left */
+                scan_table = h->permutated_intra_v_scantable; /* left */
             else
-                scan_table = h->c.permutated_intra_h_scantable; /* top */
+                scan_table = h->permutated_intra_h_scantable; /* top */
         }
     } else if (h->c.mb_intra) {
         /* DC coef */
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 85008443da..56259783b0 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -38,6 +38,7 @@
 #include "codec_internal.h"
 #include "mpegvideo.h"
 #include "flvenc.h"
+#include "mpegvideodata.h"
 #include "mpegvideoenc.h"
 #include "h263.h"
 #include "h263enc.h"
@@ -824,6 +825,11 @@ av_cold void ff_h263_encode_init(MPVMainEncContext *const 
m)
 
     ff_h263dsp_init(&s->c.h263dsp);
 
+    ff_permute_scantable(s->permutated_intra_h_scantable, 
ff_alternate_horizontal_scan,
+                         s->c.idsp.idct_permutation);
+    ff_permute_scantable(s->permutated_intra_v_scantable, 
ff_alternate_vertical_scan,
+                         s->c.idsp.idct_permutation);
+
     if (s->c.codec_id == AV_CODEC_ID_MPEG4)
         return;
 
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index e4a765d5ec..3d20f7c389 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -1425,9 +1425,9 @@ static inline int mpeg4_decode_block(Mpeg4DecContext 
*ctx, int16_t *block,
         }
         if (h->c.ac_pred) {
             if (dc_pred_dir == 0)
-                scan_table = h->c.permutated_intra_v_scantable;  /* left */
+                scan_table = h->permutated_intra_v_scantable;  /* left */
             else
-                scan_table = h->c.permutated_intra_h_scantable;  /* top */
+                scan_table = h->permutated_intra_h_scantable;  /* top */
         } else {
             scan_table = h->c.intra_scantable.permutated;
         }
@@ -3232,14 +3232,14 @@ static int decode_vop_header(Mpeg4DecContext *ctx, 
GetBitContext *gb,
 
     if (h->c.alternate_scan) {
         ff_init_scantable(h->c.idsp.idct_permutation, &h->c.intra_scantable,   
ff_alternate_vertical_scan);
-        ff_permute_scantable(h->c.permutated_intra_h_scantable, 
ff_alternate_vertical_scan,
+        ff_permute_scantable(h->permutated_intra_h_scantable, 
ff_alternate_vertical_scan,
                              h->c.idsp.idct_permutation);
     } else {
         ff_init_scantable(h->c.idsp.idct_permutation, &h->c.intra_scantable,   
ff_zigzag_direct);
-        ff_permute_scantable(h->c.permutated_intra_h_scantable, 
ff_alternate_horizontal_scan,
+        ff_permute_scantable(h->permutated_intra_h_scantable, 
ff_alternate_horizontal_scan,
                              h->c.idsp.idct_permutation);
     }
-    ff_permute_scantable(h->c.permutated_intra_v_scantable, 
ff_alternate_vertical_scan,
+    ff_permute_scantable(h->permutated_intra_v_scantable, 
ff_alternate_vertical_scan,
                          h->c.idsp.idct_permutation);
 
     if (h->c.pict_type == AV_PICTURE_TYPE_S) {
@@ -3609,21 +3609,23 @@ static av_cold void permute_quant_matrix(uint16_t 
matrix[64],
 }
 
 static av_cold void switch_to_xvid_idct(AVCodecContext *const avctx,
-                                        MpegEncContext *const s)
+                                        H263DecContext *const h)
 {
     uint8_t old_permutation[64];
 
-    memcpy(old_permutation, s->idsp.idct_permutation, sizeof(old_permutation));
+    memcpy(old_permutation, h->c.idsp.idct_permutation, 
sizeof(old_permutation));
 
     avctx->idct_algo = FF_IDCT_XVID;
-    ff_mpv_idct_init(s);
-    ff_permute_scantable(s->permutated_intra_h_scantable,
-                         s->alternate_scan ? ff_alternate_vertical_scan : 
ff_alternate_horizontal_scan,
-                         s->idsp.idct_permutation);
+    ff_mpv_idct_init(&h->c);
+    ff_permute_scantable(h->permutated_intra_h_scantable,
+                         h->c.alternate_scan ? ff_alternate_vertical_scan : 
ff_alternate_horizontal_scan,
+                         h->c.idsp.idct_permutation);
+    ff_permute_scantable(h->permutated_intra_v_scantable, 
ff_alternate_vertical_scan,
+                         h->c.idsp.idct_permutation);
 
     // Normal (i.e. non-studio) MPEG-4 does not use the chroma matrices.
-    permute_quant_matrix(s->inter_matrix, s->idsp.idct_permutation, 
old_permutation);
-    permute_quant_matrix(s->intra_matrix, s->idsp.idct_permutation, 
old_permutation);
+    permute_quant_matrix(h->c.inter_matrix, h->c.idsp.idct_permutation, 
old_permutation);
+    permute_quant_matrix(h->c.intra_matrix, h->c.idsp.idct_permutation, 
old_permutation);
 }
 
 void ff_mpeg4_workaround_bugs(AVCodecContext *avctx)
@@ -3735,7 +3737,7 @@ void ff_mpeg4_workaround_bugs(AVCodecContext *avctx)
 
     if (ctx->xvid_build >= 0 &&
         avctx->idct_algo == FF_IDCT_AUTO && !h->c.studio_profile) {
-        switch_to_xvid_idct(avctx, &h->c);
+        switch_to_xvid_idct(avctx, h);
     }
 }
 
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index ced4ad24e7..a10da6af82 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -223,7 +223,7 @@ static inline int decide_ac_pred(MPVEncContext *const s, 
int16_t block[6][64],
                     ac_val1[i + 8] = level;
                 }
             }
-            st[n] = s->c.permutated_intra_h_scantable;
+            st[n] = s->permutated_intra_h_scantable;
         } else {
             const int xy = s->c.mb_x - 1 + s->c.mb_y * s->c.mb_stride;
             /* left prediction */
@@ -245,7 +245,7 @@ static inline int decide_ac_pred(MPVEncContext *const s, 
int16_t block[6][64],
                     ac_val1[i + 8] = block[n][s->c.idsp.idct_permutation[i]];
                 }
             }
-            st[n] = s->c.permutated_intra_v_scantable;
+            st[n] = s->permutated_intra_v_scantable;
         }
 
         for (i = 63; i > 0; i--)  // FIXME optimize
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 7ca2c8f701..09e5a96239 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -94,10 +94,6 @@ av_cold void ff_mpv_idct_init(MpegEncContext *s)
         ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, 
ff_zigzag_direct);
         ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, 
ff_zigzag_direct);
     }
-    ff_permute_scantable(s->permutated_intra_h_scantable, 
ff_alternate_horizontal_scan,
-                         s->idsp.idct_permutation);
-    ff_permute_scantable(s->permutated_intra_v_scantable, 
ff_alternate_vertical_scan,
-                         s->idsp.idct_permutation);
 }
 
 av_cold int ff_mpv_init_duplicate_contexts(MpegEncContext *s)
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 6aff5fbcd0..c9ec79cfad 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -79,9 +79,6 @@ typedef struct MpegEncContext {
     /* WARNING: changes above this line require updates to hardcoded
      *          offsets used in ASM. */
 
-    uint8_t permutated_intra_h_scantable[64];
-    uint8_t permutated_intra_v_scantable[64];
-
     struct AVCodecContext *avctx;
     /* The following pointer is intended for codecs sharing code
      * between decoder and encoder and in need of a common context to do so. */
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 4366e78f90..9003d017e5 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -193,6 +193,9 @@ typedef struct MPVEncContext {
 
     int intra_penalty;
 
+    uint8_t permutated_intra_h_scantable[64];
+    uint8_t permutated_intra_v_scantable[64];
+
     DECLARE_ALIGNED_32(int16_t, blocks)[2][12][64]; // for HQ mode we need to 
keep the best block
 } MPVEncContext;
 
diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c
index 3711c37e5c..8dfe0b095d 100644
--- a/libavcodec/msmpeg4.c
+++ b/libavcodec/msmpeg4.c
@@ -118,7 +118,9 @@ static av_cold void msmpeg4_common_init_static(void)
     init_h263_dc_for_msmpeg4();
 }
 
-av_cold void ff_msmpeg4_common_init(MpegEncContext *s)
+av_cold void ff_msmpeg4_common_init(MPVContext *const s,
+                                    uint8_t permutated_intra_h_scantable[64],
+                                    uint8_t permutated_intra_v_scantable[64])
 {
     static AVOnce init_static_once = AV_ONCE_INIT;
 
@@ -148,9 +150,9 @@ av_cold void ff_msmpeg4_common_init(MpegEncContext *s)
         s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
         ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable,   
ff_wmv1_scantable[1]);
         ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable,   
ff_wmv1_scantable[0]);
-        ff_permute_scantable(s->permutated_intra_h_scantable, 
ff_wmv1_scantable[2],
+        ff_permute_scantable(permutated_intra_h_scantable, 
ff_wmv1_scantable[2],
                              s->idsp.idct_permutation);
-        ff_permute_scantable(s->permutated_intra_v_scantable, 
ff_wmv1_scantable[3],
+        ff_permute_scantable(permutated_intra_v_scantable, 
ff_wmv1_scantable[3],
                              s->idsp.idct_permutation);
         break;
     }
diff --git a/libavcodec/msmpeg4.h b/libavcodec/msmpeg4.h
index b918028fe1..69299c0004 100644
--- a/libavcodec/msmpeg4.h
+++ b/libavcodec/msmpeg4.h
@@ -31,7 +31,9 @@
 
 #define DC_MAX 119
 
-void ff_msmpeg4_common_init(MpegEncContext *s);
+void ff_msmpeg4_common_init(MPVContext *const s,
+                            uint8_t permutated_intra_h_scantable[64],
+                            uint8_t permutated_intra_v_scantable[64]);
 int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n,
                                 uint8_t **coded_block_ptr);
 
diff --git a/libavcodec/msmpeg4dec.c b/libavcodec/msmpeg4dec.c
index f2ab99ecb5..23f302dee3 100644
--- a/libavcodec/msmpeg4dec.c
+++ b/libavcodec/msmpeg4dec.c
@@ -655,9 +655,9 @@ int ff_msmpeg4_decode_block(MSMP4DecContext *const ms, 
int16_t * block,
         }
         if (h->c.ac_pred) {
             if (dc_pred_dir == 0)
-                scan_table = h->c.permutated_intra_v_scantable; /* left */
+                scan_table = h->permutated_intra_v_scantable; /* left */
             else
-                scan_table = h->c.permutated_intra_h_scantable; /* top */
+                scan_table = h->permutated_intra_h_scantable; /* top */
         } else {
             scan_table = h->c.intra_scantable.permutated;
         }
@@ -849,7 +849,8 @@ av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx)
 
     h->decode_header = msmpeg4_decode_picture_header;
 
-    ff_msmpeg4_common_init(&h->c);
+    ff_msmpeg4_common_init(&h->c, h->permutated_intra_h_scantable,
+                           h->permutated_intra_v_scantable);
 
     switch (h->c.msmpeg4_version) {
     case MSMP4_V1:
diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c
index 874e0c1f2b..6141c63e1c 100644
--- a/libavcodec/msmpeg4enc.c
+++ b/libavcodec/msmpeg4enc.c
@@ -675,7 +675,8 @@ av_cold void ff_msmpeg4_encode_init(MPVMainEncContext 
*const m)
     MPVEncContext *const s = &m->s;
     static AVOnce init_static_once = AV_ONCE_INIT;
 
-    ff_msmpeg4_common_init(&s->c);
+    ff_msmpeg4_common_init(&s->c, s->permutated_intra_h_scantable,
+                           s->permutated_intra_v_scantable);
 
     if (s->c.msmpeg4_version <= MSMP4_WMV1) {
         m->encode_picture_header = msmpeg4_encode_picture_header;
-- 
2.49.1


>From fec9b330e44e1863c9141869d16d793d27b2a72e Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Tue, 30 Dec 2025 13:26:33 +0100
Subject: [PATCH 13/14] avcodec/h261: Remove H261Context

It only contains a single field, so add this directly to MPVContext
and remove private_ctx. This avoids an indirection in
ff_h261_loop_filter().

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/h261.c      |  3 +--
 libavcodec/h261.h      |  7 -------
 libavcodec/h261dec.c   | 20 ++++++++------------
 libavcodec/h261enc.c   | 32 ++++++++++++++------------------
 libavcodec/mpegvideo.h |  6 +++---
 5 files changed, 26 insertions(+), 42 deletions(-)

diff --git a/libavcodec/h261.c b/libavcodec/h261.c
index 8e0e13459a..babbd48dcb 100644
--- a/libavcodec/h261.c
+++ b/libavcodec/h261.c
@@ -60,14 +60,13 @@ static void h261_loop_filter(uint8_t *src, ptrdiff_t stride)
 
 void ff_h261_loop_filter(MpegEncContext *s)
 {
-    H261Context *const h = s->private_ctx;
     const ptrdiff_t linesize   = s->linesize;
     const ptrdiff_t uvlinesize = s->uvlinesize;
     uint8_t *dest_y      = s->dest[0];
     uint8_t *dest_cb     = s->dest[1];
     uint8_t *dest_cr     = s->dest[2];
 
-    if (!(IS_FIL(h->mtype)))
+    if (!(IS_FIL(s->mtype)))
         return;
 
     h261_loop_filter(dest_y,                    linesize);
diff --git a/libavcodec/h261.h b/libavcodec/h261.h
index fb5fc6f940..14d5b4a2fd 100644
--- a/libavcodec/h261.h
+++ b/libavcodec/h261.h
@@ -31,13 +31,6 @@
 #include "mpegutils.h"
 #include "rl.h"
 
-/**
- * H261Context
- */
-typedef struct H261Context {
-    int mtype;
-} H261Context;
-
 #define MB_TYPE_H261_FIL MB_TYPE_CODEC_SPECIFIC
 
 extern const uint8_t ff_h261_mba_code[35];
diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c
index 32d41903e7..a25595faf6 100644
--- a/libavcodec/h261dec.c
+++ b/libavcodec/h261dec.c
@@ -59,8 +59,6 @@ typedef struct H261DecContext {
 
     GetBitContext gb;
 
-    H261Context common;
-
     int current_mba;
     int mba_diff;
     int current_mv_x;
@@ -104,7 +102,6 @@ static av_cold int h261_decode_init(AVCodecContext *avctx)
      * for all frames and override it after having decoded the frame. */
     s->pict_type = AV_PICTURE_TYPE_P;
 
-    s->private_ctx = &h->common;
     // set defaults
     ret = ff_mpv_decode_init(s, avctx);
     if (ret < 0)
@@ -211,7 +208,7 @@ static int h261_decode_mb_skipped(H261DecContext *h, int 
mba1, int mba2)
         s->mv[0][0][0]                 = 0;
         s->mv[0][0][1]                 = 0;
         s->mb_skipped                  = 1;
-        h->common.mtype               &= ~MB_TYPE_H261_FIL;
+        s->mtype                      &= ~MB_TYPE_H261_FIL;
 
         if (s->cur_pic.motion_val[0]) {
             int b_stride = 2*s->mb_width + 1;
@@ -352,7 +349,6 @@ static int h261_decode_block(H261DecContext *h, int16_t 
*block, int n, int coded
 static int h261_decode_mb(H261DecContext *h)
 {
     MpegEncContext *const s = &h->s;
-    H261Context *const com = &h->common;
     int i, cbp, xy;
 
     cbp = 63;
@@ -389,23 +385,23 @@ static int h261_decode_mb(H261DecContext *h)
     h261_init_dest(s);
 
     // Read mtype
-    com->mtype = get_vlc2(&h->gb, h261_mtype_vlc, H261_MTYPE_VLC_BITS, 2);
-    if (com->mtype < 0) {
+    s->mtype = get_vlc2(&h->gb, h261_mtype_vlc, H261_MTYPE_VLC_BITS, 2);
+    if (s->mtype < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "Invalid mtype index\n");
         return SLICE_ERROR;
     }
 
     // Read mquant
-    if (IS_QUANT(com->mtype)) {
+    if (IS_QUANT(s->mtype)) {
         s->qscale = get_bits(&h->gb, 5);
         if (!s->qscale)
             s->qscale = 1;
     }
 
-    s->mb_intra = IS_INTRA4x4(com->mtype);
+    s->mb_intra = IS_INTRA4x4(s->mtype);
 
     // Read mv
-    if (IS_16X16(com->mtype)) {
+    if (IS_16X16(s->mtype)) {
         /* Motion vector data is included for all MC macroblocks. MVD is
          * obtained from the macroblock vector by subtracting the vector
          * of the preceding macroblock. For this calculation the vector
@@ -428,7 +424,7 @@ static int h261_decode_mb(H261DecContext *h)
     }
 
     // Read cbp
-    if (HAS_CBP(com->mtype))
+    if (HAS_CBP(s->mtype))
         cbp = get_vlc2(&h->gb, h261_cbp_vlc, H261_CBP_VLC_BITS, 1) + 1;
 
     if (s->mb_intra) {
@@ -452,7 +448,7 @@ static int h261_decode_mb(H261DecContext *h)
 
 intra:
     /* decode each block */
-    if (s->mb_intra || HAS_CBP(com->mtype)) {
+    if (s->mb_intra || HAS_CBP(s->mtype)) {
         s->bdsp.clear_blocks(h->block[0]);
         for (i = 0; i < 6; i++) {
             if (h261_decode_block(h, h->block[i], i, cbp & 32) < 0)
diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index c75e029d68..d13511a6f4 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -58,8 +58,6 @@ static uint8_t h261_mv_codes[64][2];
 typedef struct H261EncContext {
     MPVMainEncContext s;
 
-    H261Context common;
-
     int gob_number;
     enum {
         H261_QCIF = 0,
@@ -232,12 +230,11 @@ static void h261_encode_mb(MPVEncContext *const s, 
int16_t block[6][64],
     /* The following is only allowed because this encoder
      * does not use slice threading. */
     H261EncContext *const h = (H261EncContext *)s;
-    H261Context *const com = &h->common;
     int mvd, mv_diff_x, mv_diff_y, i, cbp;
     cbp = 63; // avoid warning
     mvd = 0;
 
-    com->mtype = 0;
+    s->c.mtype = 0;
 
     if (!s->c.mb_intra) {
         /* compute cbp */
@@ -264,34 +261,34 @@ static void h261_encode_mb(MPVEncContext *const s, 
int16_t block[6][64],
 
     /* calculate MTYPE */
     if (!s->c.mb_intra) {
-        com->mtype++;
+        s->c.mtype++;
 
         if (mvd || s->loop_filter)
-            com->mtype += 3;
+            s->c.mtype += 3;
         if (s->loop_filter)
-            com->mtype += 3;
+            s->c.mtype += 3;
         if (cbp)
-            com->mtype++;
-        av_assert1(com->mtype > 1);
+            s->c.mtype++;
+        av_assert1(s->c.mtype > 1);
     }
 
     if (s->dquant && cbp) {
-        com->mtype++;
+        s->c.mtype++;
     } else
         s->c.qscale -= s->dquant;
 
     put_bits(&s->pb,
-             ff_h261_mtype_bits[com->mtype],
-             ff_h261_mtype_code[com->mtype]);
+             ff_h261_mtype_bits[s->c.mtype],
+             ff_h261_mtype_code[s->c.mtype]);
 
-    com->mtype = ff_h261_mtype_map[com->mtype];
+    s->c.mtype = ff_h261_mtype_map[s->c.mtype];
 
-    if (IS_QUANT(com->mtype)) {
+    if (IS_QUANT(s->c.mtype)) {
         ff_set_qscale(&s->c, s->c.qscale + s->dquant);
         put_bits(&s->pb, 5, s->c.qscale);
     }
 
-    if (IS_16X16(com->mtype)) {
+    if (IS_16X16(s->c.mtype)) {
         mv_diff_x       = (motion_x >> 1) - s->c.last_mv[0][0][0];
         mv_diff_y       = (motion_y >> 1) - s->c.last_mv[0][0][1];
         s->c.last_mv[0][0][0] = (motion_x >> 1);
@@ -300,7 +297,7 @@ static void h261_encode_mb(MPVEncContext *const s, int16_t 
block[6][64],
         h261_encode_motion(&s->pb, mv_diff_y);
     }
 
-    if (HAS_CBP(com->mtype)) {
+    if (HAS_CBP(s->c.mtype)) {
         av_assert1(cbp > 0);
         put_bits(&s->pb,
                  ff_h261_cbp_tab[cbp - 1][1],
@@ -310,7 +307,7 @@ static void h261_encode_mb(MPVEncContext *const s, int16_t 
block[6][64],
         /* encode each block */
         h261_encode_block(h, block[i], i);
 
-    if (!IS_16X16(com->mtype)) {
+    if (!IS_16X16(s->c.mtype)) {
         s->c.last_mv[0][0][0] = 0;
         s->c.last_mv[0][0][1] = 0;
     }
@@ -370,7 +367,6 @@ static av_cold int h261_encode_init(AVCodecContext *avctx)
                avctx->width, avctx->height);
         return AVERROR(EINVAL);
     }
-    s->c.private_ctx = &h->common;
     h->s.encode_picture_header = h261_encode_picture_header;
     s->encode_mb               = h261_encode_mb;
 
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index c9ec79cfad..d448ac6b5a 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -80,9 +80,6 @@ typedef struct MpegEncContext {
      *          offsets used in ASM. */
 
     struct AVCodecContext *avctx;
-    /* The following pointer is intended for codecs sharing code
-     * between decoder and encoder and in need of a common context to do so. */
-    void *private_ctx;
     /* the following parameters must be initialized before encoding */
     int width, height;///< picture size. must be a multiple of 16
     enum OutputFormat out_format; ///< output format
@@ -210,6 +207,9 @@ typedef struct MpegEncContext {
     int resync_mb_x;                 ///< x position of last resync marker
     int resync_mb_y;                 ///< y position of last resync marker
 
+    /* H.261 specific */
+    int mtype;
+
     /* H.263 specific */
     int obmc;                       ///< overlapped block motion compensation
 
-- 
2.49.1


>From 607329c2a4d28272699649a40642310486c47eef Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Tue, 30 Dec 2025 14:13:41 +0100
Subject: [PATCH 14/14] avcodec/vc1_block: Simplify vc1_coded_block_pred()

Make it already apply the prediction, avoiding the pointer indirection.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/vc1_block.c | 23 +++++++----------------
 1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c
index 4fa03f287a..10cb459082 100644
--- a/libavcodec/vc1_block.c
+++ b/libavcodec/vc1_block.c
@@ -476,8 +476,7 @@ static inline int ff_vc1_pred_dc(MpegEncContext *s, int 
overlap, int pq, int n,
  * @{
  */
 
-static inline int vc1_coded_block_pred(MpegEncContext * s, int n,
-                                       uint8_t **coded_block_ptr)
+static inline int vc1_coded_block_pred(MPVContext *const s, int n, int diff)
 {
     int xy, wrap, pred, a, b, c;
 
@@ -498,9 +497,9 @@ static inline int vc1_coded_block_pred(MpegEncContext * s, 
int n,
     }
 
     /* store value */
-    *coded_block_ptr = &s->coded_block[xy];
+    s->coded_block[xy] = pred ^ diff;
 
-    return pred;
+    return pred ^ diff;
 }
 
 /**
@@ -2507,7 +2506,6 @@ static void vc1_decode_i_blocks(VC1Context *v)
     int k, j;
     MpegEncContext *s = &v->s;
     int cbp, val;
-    uint8_t *coded_val;
     int mb_pos;
 
     /* select coding mode used for VLC tables selection */
@@ -2566,11 +2564,8 @@ static void vc1_decode_i_blocks(VC1Context *v)
 
                 val = ((cbp >> (5 - k)) & 1);
 
-                if (k < 4) {
-                    int pred   = vc1_coded_block_pred(&v->s, k, &coded_val);
-                    val        = val ^ pred;
-                    *coded_val = val;
-                }
+                if (k < 4)
+                    val = vc1_coded_block_pred(&v->s, k, val);
                 cbp |= val << (5 - k);
 
                 vc1_decode_i_block(v, v->block[v->cur_blk_idx][block_map[k]], 
k, val, (k < 4) ? v->codingset : v->codingset2);
@@ -2627,7 +2622,6 @@ static int vc1_decode_i_blocks_adv(VC1Context *v)
     MpegEncContext *s = &v->s;
     GetBitContext *const gb = &v->gb;
     int cbp, val;
-    uint8_t *coded_val;
     int mb_pos;
     int mquant;
     int mqdiff;
@@ -2712,11 +2706,8 @@ static int vc1_decode_i_blocks_adv(VC1Context *v)
 
                 val = ((cbp >> (5 - k)) & 1);
 
-                if (k < 4) {
-                    int pred   = vc1_coded_block_pred(&v->s, k, &coded_val);
-                    val        = val ^ pred;
-                    *coded_val = val;
-                }
+                if (k < 4)
+                    val = vc1_coded_block_pred(&v->s, k, val);
                 cbp |= val << (5 - k);
 
                 v->a_avail = !s->first_slice_line || (k == 2 || k == 3);
-- 
2.49.1

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to