FFmpeg/libavcodec/mpeg4videodec.h
Andreas Rheinhardt 6ce86c9c11 avcodec/mpeg4videodec: Permute quant matrices directly upon IDCT reinit
When switching to the XviD IDCT, the IDCT permutation can change.
Given that we already permute the quant matrices when parsing
them, they need to be permuted, too. Up until now this has not been
done; instead the header has been parsed again in the expectation
that the currently active quant matrix is contained in this header.

This expectation is wrong; it is for example wrong when the VOL
header is only available via extradata (such a file can be easily
created from xvid_vlc_trac7411.h263 (in the FATE suite) via the
remove_extra BSF). It could also be wrong if the XviD user data
is only available in a subsequent packet.

This commit therefore switches to permuting the relevant matrices
directly. It also stops parsing the header a second time
when switching to the XviD IDCT.

(I wonder whether ff_mpv_idct_init() should take alternate_scan
into account when initializing permutated_intra_h_scantable
as the decoder does. Does the MPEG-4 encoder use a wrong scantable
in this case?)

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-05-16 01:37:35 +02:00

120 lines
4.1 KiB
C

/*
* MPEG-4 decoder internal header.
* Copyright (c) 2000,2001 Fabrice Bellard
* Copyright (c) 2002-2010 Michael Niedermayer <michaelni@gmx.at>
*
* 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
*/
#ifndef AVCODEC_MPEG4VIDEODEC_H
#define AVCODEC_MPEG4VIDEODEC_H
#include <stdint.h>
#include "get_bits.h"
#include "mpegvideo.h"
#include "mpeg4videodsp.h"
#include "libavutil/mem_internal.h"
typedef struct Mpeg4DecContext {
MpegEncContext m;
/// number of bits to represent the fractional part of time
int time_increment_bits;
int shape;
int vol_sprite_usage;
int sprite_brightness_change;
int sprite_warping_accuracy;
int num_sprite_warping_points;
int real_sprite_warping_points;
int sprite_offset[2][2]; ///< sprite offset[isChroma][isMVY]
int sprite_delta[2][2]; ///< sprite_delta [isY][isMVY]
/// sprite trajectory points
uint16_t sprite_traj[4][2];
/// sprite shift [isChroma]
int sprite_shift[2];
// reversible vlc
int rvlc;
/// could this stream contain resync markers
int resync_marker;
/// time distance of first I -> B, used for interlaced B-frames
int t_frame;
int new_pred;
int enhancement_type;
int scalability;
int quant_precision;
/// QP above which the ac VLC should be used for intra dc
int intra_dc_threshold;
/* bug workarounds */
int divx_version;
int divx_build;
int xvid_build;
int lavc_build;
/// Divx 5.01 puts several frames in a single one, this is used to reorder them
AVBufferRef *bitstream_buffer;
int vo_type;
/// flag for having shown the warning about invalid Divx B-frames
int showed_packed_warning;
/** does the stream contain the low_delay flag,
* used to work around buggy encoders. */
int vol_control_parameters;
int cplx_estimation_trash_i;
int cplx_estimation_trash_p;
int cplx_estimation_trash_b;
int rgb;
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;
int16_t dpcm_macroblock[3][256];
} Mpeg4DecContext;
int ff_mpeg4_decode_picture_header(MpegEncContext *s);
int ff_mpeg4_parse_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb,
int header, int parse_only);
void ff_mpeg4_decode_studio(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb,
uint8_t *dest_cr, int block_size, int uvlinesize,
int dct_linesize, int dct_offset);
void ff_mpeg4_mcsel_motion(MpegEncContext *s,
uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
uint8_t *const *ref_picture);
int ff_mpeg4_decode_partitions(Mpeg4DecContext *ctx);
int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx);
int ff_mpeg4_decode_studio_slice_header(Mpeg4DecContext *ctx);
void ff_mpeg4_workaround_bugs(AVCodecContext *avctx);
void ff_mpeg4_pred_ac(MpegEncContext *s, int16_t *block, int n,
int dir);
int ff_mpeg4_frame_end(AVCodecContext *avctx, const AVPacket *pkt);
#endif