* [FFmpeg-devel] [PATCH] avcodec/mpegvideo: Move permutated_intra scans to {H263Dec,MPVEnc}Ctx (PR #21320)
@ 2025-12-30 13:38 mkver via ffmpeg-devel
0 siblings, 0 replies; only message in thread
From: mkver via ffmpeg-devel @ 2025-12-30 13:38 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: mkver
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 <andreas.rheinhardt@outlook.com>
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 <andreas.rheinhardt@outlook.com>
---
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 <andreas.rheinhardt@outlook.com>
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 <andreas.rheinhardt@outlook.com>
---
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 <andreas.rheinhardt@outlook.com>
Date: Wed, 25 Jun 2025 07:08:41 +0200
Subject: [PATCH 03/14] avcodec/msmpeg4: Avoid branch
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
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 <andreas.rheinhardt@outlook.com>
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 <andreas.rheinhardt@outlook.com>
---
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 <andreas.rheinhardt@outlook.com>
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 <andreas.rheinhardt@outlook.com>
---
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 <andreas.rheinhardt@outlook.com>
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 <andreas.rheinhardt@outlook.com>
---
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 <andreas.rheinhardt@outlook.com>
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 <andreas.rheinhardt@outlook.com>
---
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 <andreas.rheinhardt@outlook.com>
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 <andreas.rheinhardt@outlook.com>
---
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 <andreas.rheinhardt@outlook.com>
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 <andreas.rheinhardt@outlook.com>
---
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 <andreas.rheinhardt@outlook.com>
Date: Wed, 25 Jun 2025 09:10:26 +0200
Subject: [PATCH 10/14] avcodec/wmv2: Remove WMV2Context
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
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 <andreas.rheinhardt@outlook.com>
Date: Wed, 25 Jun 2025 09:16:36 +0200
Subject: [PATCH 11/14] avcodec/wmv2dec: Avoid indirection
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
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 <andreas.rheinhardt@outlook.com>
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 <andreas.rheinhardt@outlook.com>
---
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 <andreas.rheinhardt@outlook.com>
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 <andreas.rheinhardt@outlook.com>
---
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 <andreas.rheinhardt@outlook.com>
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 <andreas.rheinhardt@outlook.com>
---
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 -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2025-12-30 13:40 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-30 13:38 [FFmpeg-devel] [PATCH] avcodec/mpegvideo: Move permutated_intra scans to {H263Dec,MPVEnc}Ctx (PR #21320) mkver via ffmpeg-devel
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