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]
