1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-08-04 22:03:09 +02:00

avcodec/mpegvideo: Only keep the actually used unquantize funcs

For all encoders and all decoders except MPEG-4 the unquantize
functions to use don't change at all and therefore needn't be
kept in the context. So discard them after setting them;
for MPEG-4, the functions get assigned on a per-frame basis.

Decoders not using any unquantize functions (H.261, MPEG-1/2)
as well as decoders that only call ff_mpv_reconstruct_mb()
through error resilience (RV30/40, the VC-1 family) don't have
the remaining pointers set at all.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt
2025-03-19 15:24:57 +01:00
parent 917652d7c8
commit e5a33c898a
15 changed files with 99 additions and 61 deletions

View File

@ -46,12 +46,12 @@ void ff_dct_unquantize_h263_inter_neon(MpegEncContext *s, int16_t *block,
void ff_dct_unquantize_h263_intra_neon(MpegEncContext *s, int16_t *block,
int n, int qscale);
av_cold void ff_mpv_common_init_arm(MpegEncContext *s)
av_cold void ff_mpv_unquantize_init_arm(MPVUnquantDSPContext *s, int bitexact)
{
int cpu_flags = av_get_cpu_flags();
if (have_armv5te(cpu_flags))
ff_mpv_common_init_armv5te(s);
ff_mpv_unquantize_init_armv5te(s);
if (have_neon(cpu_flags)) {
s->dct_unquantize_h263_intra = ff_dct_unquantize_h263_intra_neon;

View File

@ -19,8 +19,8 @@
#ifndef AVCODEC_ARM_MPEGVIDEO_ARM_H
#define AVCODEC_ARM_MPEGVIDEO_ARM_H
#include "libavcodec/mpegvideo.h"
#include "libavcodec/mpegvideo_unquantize.h"
void ff_mpv_common_init_armv5te(MpegEncContext *s);
void ff_mpv_unquantize_init_armv5te(MPVUnquantDSPContext *s);
#endif /* AVCODEC_ARM_MPEGVIDEO_ARM_H */

View File

@ -95,7 +95,7 @@ static void dct_unquantize_h263_inter_armv5te(MpegEncContext *s,
ff_dct_unquantize_h263_armv5te(block, qmul, qadd, nCoeffs + 1);
}
av_cold void ff_mpv_common_init_armv5te(MpegEncContext *s)
av_cold void ff_mpv_unquantize_init_armv5te(MPVUnquantDSPContext *s)
{
s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_armv5te;
s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_armv5te;

View File

@ -44,6 +44,7 @@
#include "mpegvideo.h"
#include "mpegvideodata.h"
#include "mpegvideodec.h"
#include "mpegvideo_unquantize.h"
#include "msmpeg4dec.h"
#include "thread.h"
#include "wmv2dec.h"
@ -90,6 +91,7 @@ static enum AVPixelFormat h263_get_format(AVCodecContext *avctx)
av_cold int ff_h263_decode_init(AVCodecContext *avctx)
{
MpegEncContext *s = avctx->priv_data;
MPVUnquantDSPContext unquant_dsp_ctx;
int ret;
s->out_format = FMT_H263;
@ -105,10 +107,12 @@ 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_mpv_unquantize_init(&unquant_dsp_ctx,
avctx->flags & AV_CODEC_FLAG_BITEXACT, 0);
// dct_unquantize defaults for H.263;
// they might change on a per-frame basis for MPEG-4.
s->dct_unquantize_intra = s->dct_unquantize_h263_intra;
s->dct_unquantize_inter = s->dct_unquantize_h263_inter;
s->dct_unquantize_intra = unquant_dsp_ctx.dct_unquantize_h263_intra;
s->dct_unquantize_inter = unquant_dsp_ctx.dct_unquantize_h263_inter;
/* select sub codec */
switch (avctx->codec->id) {
@ -117,9 +121,6 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx)
avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
break;
case AV_CODEC_ID_MPEG4:
// dct_unquantize_inter is only used with MPEG-2 quantizers,
// so we can already set dct_unquantize_inter here once and for all.
s->dct_unquantize_inter = s->dct_unquantize_mpeg2_inter;
break;
case AV_CODEC_ID_MSMPEG4V1:
s->h263_pred = 1;
@ -508,11 +509,6 @@ retry:
goto retry;
if (s->studio_profile != (s->idsp.idct == NULL))
ff_mpv_idct_init(s);
if (s->mpeg_quant) {
s->dct_unquantize_intra = s->dct_unquantize_mpeg2_intra;
} else {
s->dct_unquantize_intra = s->dct_unquantize_h263_intra;
}
}
/* After H.263 & MPEG-4 header decode we have the height, width,

View File

@ -24,7 +24,8 @@
#include "h263dsp_mips.h"
#include "mpegvideo_mips.h"
av_cold void ff_mpv_common_init_mips(MpegEncContext *s)
av_cold void ff_mpv_unquantize_init_mips(MPVUnquantDSPContext *s,
int bitexact, int q_scale_type)
{
int cpu_flags = av_get_cpu_flags();
@ -34,15 +35,15 @@ av_cold void ff_mpv_common_init_mips(MpegEncContext *s)
s->dct_unquantize_mpeg1_intra = ff_dct_unquantize_mpeg1_intra_mmi;
s->dct_unquantize_mpeg1_inter = ff_dct_unquantize_mpeg1_inter_mmi;
if (!(s->avctx->flags & AV_CODEC_FLAG_BITEXACT))
if (!s->q_scale_type)
if (!bitexact)
if (!q_scale_type)
s->dct_unquantize_mpeg2_intra = ff_dct_unquantize_mpeg2_intra_mmi;
}
if (have_msa(cpu_flags)) {
s->dct_unquantize_h263_intra = ff_dct_unquantize_h263_intra_msa;
s->dct_unquantize_h263_inter = ff_dct_unquantize_h263_inter_msa;
if (!s->q_scale_type)
if (!q_scale_type)
s->dct_unquantize_mpeg2_inter = ff_dct_unquantize_mpeg2_inter_msa;
}
}

View File

@ -35,6 +35,7 @@
#include "mpegvideo.h"
#include "mpegvideodata.h"
#include "mpegvideodec.h"
#include "mpegvideo_unquantize.h"
#include "mpeg4video.h"
#include "mpeg4videodata.h"
#include "mpeg4videodec.h"
@ -3390,6 +3391,9 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb,
}
}
s->dct_unquantize_intra = s->mpeg_quant ? ctx->dct_unquantize_mpeg2_intra
: ctx->dct_unquantize_h263_intra;
end:
/* detect buggy encoders which don't set the low_delay flag
* (divx4/xvid/opendivx). Note we cannot detect divx5 without B-frames
@ -3862,6 +3866,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
static AVOnce init_static_once = AV_ONCE_INIT;
Mpeg4DecContext *ctx = avctx->priv_data;
MpegEncContext *s = &ctx->m;
MPVUnquantDSPContext unquant_dsp_ctx;
int ret;
ctx->divx_version =
@ -3872,6 +3877,15 @@ static av_cold int decode_init(AVCodecContext *avctx)
if ((ret = ff_h263_decode_init(avctx)) < 0)
return ret;
ff_mpv_unquantize_init(&unquant_dsp_ctx,
avctx->flags & AV_CODEC_FLAG_BITEXACT, 0);
ctx->dct_unquantize_h263_intra = unquant_dsp_ctx.dct_unquantize_h263_intra;
ctx->dct_unquantize_mpeg2_intra = unquant_dsp_ctx.dct_unquantize_mpeg2_intra;
// dct_unquantize_inter is only used with MPEG-2 quantizers,
// so we can already set dct_unquantize_inter here once and for all.
s->dct_unquantize_inter = unquant_dsp_ctx.dct_unquantize_mpeg2_inter;
s->h263_pred = 1;
s->low_delay = 0; /* default, might be overridden in the vol header during header parsing */
s->decode_mb = mpeg4_decode_mb;

View File

@ -88,6 +88,11 @@ typedef struct Mpeg4DecContext {
Mpeg4VideoDSPContext mdsp;
void (*dct_unquantize_mpeg2_intra)(MpegEncContext *s,
int16_t *block, int n, int qscale);
void (*dct_unquantize_h263_intra)(MpegEncContext *s,
int16_t *block, int n, int qscale);
DECLARE_ALIGNED(8, int32_t, block32)[12][64];
// 0 = DCT, 1 = DPCM top to bottom scan, -1 = DPCM bottom to top scan
int dpcm_direction;

View File

@ -112,8 +112,6 @@ av_cold void ff_mpv_idct_init(MpegEncContext *s)
s->idsp.idct_permutation);
ff_permute_scantable(s->permutated_intra_v_scantable, ff_alternate_vertical_scan,
s->idsp.idct_permutation);
ff_mpv_unquantize_init(s);
}
static av_cold int init_duplicate_context(MpegEncContext *s)

View File

@ -326,18 +326,6 @@ typedef struct MpegEncContext {
#define SLICE_END -2 ///<end marker found
#define SLICE_NOEND -3 ///<no end marker or error found but mb count exceeded
void (*dct_unquantize_mpeg1_intra)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_mpeg1_inter)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_mpeg2_intra)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_mpeg2_inter)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_h263_intra)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_h263_inter)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_intra)(struct MpegEncContext *s, // unquantizer to use (MPEG-4 can use both)
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_inter)(struct MpegEncContext *s, // unquantizer to use (MPEG-4 can use both)

View File

@ -60,6 +60,7 @@
#include "mjpegenc_common.h"
#include "mathops.h"
#include "mpegutils.h"
#include "mpegvideo_unquantize.h"
#include "mjpegenc.h"
#include "speedhqenc.h"
#include "msmpeg4enc.h"
@ -309,6 +310,25 @@ av_cold void ff_dct_encode_init(MPVEncContext *const s)
s->dct_quantize = dct_quantize_trellis_c;
}
static av_cold void init_unquantize(MpegEncContext *const s, AVCodecContext *avctx)
{
MPVUnquantDSPContext unquant_dsp_ctx;
ff_mpv_unquantize_init(&unquant_dsp_ctx,
avctx->flags & AV_CODEC_FLAG_BITEXACT, s->q_scale_type);
if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
s->dct_unquantize_intra = unquant_dsp_ctx.dct_unquantize_mpeg2_intra;
s->dct_unquantize_inter = unquant_dsp_ctx.dct_unquantize_mpeg2_inter;
} else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) {
s->dct_unquantize_intra = unquant_dsp_ctx.dct_unquantize_h263_intra;
s->dct_unquantize_inter = unquant_dsp_ctx.dct_unquantize_h263_inter;
} else {
s->dct_unquantize_intra = unquant_dsp_ctx.dct_unquantize_mpeg1_intra;
s->dct_unquantize_inter = unquant_dsp_ctx.dct_unquantize_mpeg1_inter;
}
}
static av_cold int me_cmp_init(MPVMainEncContext *const m, AVCodecContext *avctx)
{
MPVEncContext *const s = &m->s;
@ -1012,6 +1032,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
* to the slice contexts, so we initialize various fields of it
* before calling ff_mpv_common_init(). */
ff_mpv_idct_init(&s->c);
init_unquantize(&s->c, avctx);
ff_fdctdsp_init(&s->fdsp, avctx);
ff_mpegvideoencdsp_init(&s->mpvencdsp, avctx);
ff_pixblockdsp_init(&s->pdsp, avctx);
@ -1030,17 +1051,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
ff_dct_encode_init(s);
if (s->c.mpeg_quant || s->c.codec_id == AV_CODEC_ID_MPEG2VIDEO) {
s->c.dct_unquantize_intra = s->c.dct_unquantize_mpeg2_intra;
s->c.dct_unquantize_inter = s->c.dct_unquantize_mpeg2_inter;
} else if (s->c.out_format == FMT_H263 || s->c.out_format == FMT_H261) {
s->c.dct_unquantize_intra = s->c.dct_unquantize_h263_intra;
s->c.dct_unquantize_inter = s->c.dct_unquantize_h263_inter;
} else {
s->c.dct_unquantize_intra = s->c.dct_unquantize_mpeg1_intra;
s->c.dct_unquantize_inter = s->c.dct_unquantize_mpeg1_inter;
}
if (CONFIG_H263_ENCODER && s->c.out_format == FMT_H263) {
ff_h263_encode_init(m);
#if CONFIG_MSMPEG4ENC

View File

@ -246,28 +246,29 @@ static void dct_unquantize_h263_inter_c(MpegEncContext *s,
}
}
av_cold void ff_mpv_unquantize_init(MpegEncContext *s)
av_cold void ff_mpv_unquantize_init(MPVUnquantDSPContext *s,
int bitexact, int q_scale_type)
{
s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_c;
s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_c;
s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_c;
s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_c;
s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_c;
if (s->avctx->flags & AV_CODEC_FLAG_BITEXACT)
if (bitexact)
s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_bitexact;
s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_c;
#if HAVE_INTRINSICS_NEON
ff_mpv_common_init_neon(s);
ff_mpv_unquantize_init_neon(s, bitexact);
#endif
#if ARCH_ARM
ff_mpv_common_init_arm(s);
ff_mpv_unquantize_init_arm(s, bitexact);
#elif ARCH_PPC
ff_mpv_common_init_ppc(s);
ff_mpv_unquantize_init_ppc(s, bitexact);
#elif ARCH_X86
ff_mpv_common_init_x86(s);
ff_mpv_unquantize_init_x86(s, bitexact);
#elif ARCH_MIPS
ff_mpv_common_init_mips(s);
ff_mpv_unquantize_init_mips(s, bitexact, q_scale_type);
#endif
}

View File

@ -25,13 +25,38 @@
#ifndef AVCODEC_MPEGVIDEO_UNQUANTIZE_H
#define AVCODEC_MPEGVIDEO_UNQUANTIZE_H
#include <stdint.h>
#include "config.h"
typedef struct MpegEncContext MpegEncContext;
void ff_mpv_unquantize_init(MpegEncContext *s);
void ff_mpv_common_init_arm(MpegEncContext *s);
void ff_mpv_common_init_neon(MpegEncContext *s);
void ff_mpv_common_init_ppc(MpegEncContext *s);
void ff_mpv_common_init_x86(MpegEncContext *s);
void ff_mpv_common_init_mips(MpegEncContext *s);
typedef struct MPVUnquantDSPContext {
void (*dct_unquantize_mpeg1_intra)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_mpeg1_inter)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_mpeg2_intra)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_mpeg2_inter)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_h263_intra)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_h263_inter)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
} MPVUnquantDSPContext;
#if !ARCH_MIPS
#define ff_mpv_unquantize_init(s, bitexact, q_scale_type) ff_mpv_unquantize_init(s, bitexact)
#endif
void ff_mpv_unquantize_init(MPVUnquantDSPContext *s,
int bitexact, int q_scale_type);
void ff_mpv_unquantize_init_arm (MPVUnquantDSPContext *s, int bitexact);
void ff_mpv_unquantize_init_neon(MPVUnquantDSPContext *s, int bitexact);
void ff_mpv_unquantize_init_ppc (MPVUnquantDSPContext *s, int bitexact);
void ff_mpv_unquantize_init_x86 (MPVUnquantDSPContext *s, int bitexact);
void ff_mpv_unquantize_init_mips(MPVUnquantDSPContext *s, int bitexact,
int q_scale_type);
#endif /* AVCODEC_MPEGVIDEO_UNQUANTIZE_H */

View File

@ -125,7 +125,7 @@ static void dct_unquantize_h263_intra_neon(MpegEncContext *s, int16_t *block,
}
av_cold void ff_mpv_common_init_neon(MpegEncContext *s)
av_cold void ff_mpv_unquantize_init_neon(MPVUnquantDSPContext *s, int bitexact)
{
int cpu_flags = av_get_cpu_flags();

View File

@ -103,7 +103,7 @@ static void dct_unquantize_h263_altivec(MpegEncContext *s,
#endif /* HAVE_ALTIVEC */
av_cold void ff_mpv_common_init_ppc(MpegEncContext *s)
av_cold void ff_mpv_unquantize_init_ppc(MPVUnquantDSPContext *s, int bitexact)
{
#if HAVE_ALTIVEC
if (!PPC_ALTIVEC(av_get_cpu_flags()))

View File

@ -450,7 +450,7 @@ __asm__ volatile(
#endif /* HAVE_MMX_INLINE */
av_cold void ff_mpv_common_init_x86(MpegEncContext *s)
av_cold void ff_mpv_unquantize_init_x86(MPVUnquantDSPContext *s, int bitexact)
{
#if HAVE_MMX_INLINE
int cpu_flags = av_get_cpu_flags();
@ -460,7 +460,7 @@ av_cold void ff_mpv_common_init_x86(MpegEncContext *s)
s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_mmx;
s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_mmx;
s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_mmx;
if (!(s->avctx->flags & AV_CODEC_FLAG_BITEXACT))
if (!bitexact)
s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_mmx;
s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_mmx;
}