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

avcodec/mpegvideo_enc: Use func ptr for encoding macroblocks

It gets rid of a switch (with accompanying CONFIG_*_ENCODER checks);
for MJPEG, it even lets one perform the check for whether one is
really encoding or only recording the macroblock once during init.

Furthermore, the switch actually contained lots of dead code --
it is compiled three times (for different pixel formats: 420, 422, 444),
yet most encoders only support 420. The approach used here automatically
fixes this.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt
2025-03-04 19:09:24 +01:00
parent 2f73a197a1
commit 5affd0221e
18 changed files with 45 additions and 114 deletions

View File

@ -228,7 +228,7 @@ static void h261_encode_block(H261EncContext *h, int16_t *block, int n)
put_bits(&s->pb, 2, 0x2); // EOB
}
void ff_h261_encode_mb(MpegEncContext *s, int16_t block[6][64],
static void h261_encode_mb(MpegEncContext *const s, int16_t block[6][64],
int motion_x, int motion_y)
{
/* The following is only allowed because this encoder
@ -374,6 +374,7 @@ static av_cold int h261_encode_init(AVCodecContext *avctx)
}
s->private_ctx = &h->common;
h->s.encode_picture_header = h261_encode_picture_header;
s->encode_mb = h261_encode_mb;
s->min_qcoeff = -127;
s->max_qcoeff = 127;

View File

@ -31,7 +31,5 @@
#include "mpegvideo.h"
void ff_h261_reorder_mb_index(MpegEncContext *s);
void ff_h261_encode_mb(MpegEncContext *s, int16_t block[6][64],
int motion_x, int motion_y);
#endif

View File

@ -28,9 +28,6 @@ const uint8_t (*ff_h263_get_mv_penalty(void))[MAX_DMV*2+1];
void ff_h263_encode_init(MPVMainEncContext *m);
void ff_h263_encode_gob_header(MpegEncContext * s, int mb_line);
void ff_h263_encode_mb(MpegEncContext *s,
int16_t block[6][64],
int motion_x, int motion_y);
void ff_h263_encode_mba(MpegEncContext *s);
void ff_clean_h263_qscales(MpegEncContext *s);

View File

@ -608,8 +608,8 @@ static int h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr)
return pred_dc;
}
void ff_h263_encode_mb(MpegEncContext * s,
int16_t block[6][64],
static void h263_encode_mb(MpegEncContext *const s,
int16_t block[][64],
int motion_x, int motion_y)
{
int cbpc, cbpy, i, cbp, pred_x, pred_y;
@ -875,6 +875,8 @@ av_cold void ff_h263_encode_init(MPVMainEncContext *const m)
// H.263, H.263+; will be overwritten for MSMPEG-4 later
if (!m->encode_picture_header)
m->encode_picture_header = h263_encode_picture_header;
if (!s->encode_mb)
s->encode_mb = h263_encode_mb;
ff_h263dsp_init(&s->h263dsp);
}

View File

@ -463,10 +463,10 @@ static void encode_block(MpegEncContext *s, int16_t *block, int n)
put_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]);
}
void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64])
static void mjpeg_record_mb(MpegEncContext *const s, int16_t block[][64],
int unused_x, int unused_y)
{
int i;
if (s->mjpeg_ctx->huffman == HUFFMAN_TABLE_OPTIMAL) {
if (s->chroma_format == CHROMA_444) {
record_block(s, block[0], 0);
record_block(s, block[2], 2);
@ -495,7 +495,12 @@ void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64])
record_block(s, block[7], 7);
}
}
} else {
}
static void mjpeg_encode_mb(MpegEncContext *const s, int16_t block[][64],
int unused_x, int unused_y)
{
int i;
if (s->chroma_format == CHROMA_444) {
encode_block(s, block[0], 0);
encode_block(s, block[2], 2);
@ -527,7 +532,6 @@ void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64])
s->i_tex_bits += get_bits_diff(s);
}
}
static av_cold int mjpeg_encode_init(AVCodecContext *avctx)
{
@ -538,6 +542,8 @@ static av_cold int mjpeg_encode_init(AVCodecContext *avctx)
s->mjpeg_ctx = m;
m2->mpeg.encode_picture_header = mjpeg_amv_encode_picture_header;
// May be overridden below
s->encode_mb = mjpeg_encode_mb;
if (s->mpv_flags & FF_MPV_FLAG_QP_RD) {
// Used to produce garbage with MJPEG.
@ -598,8 +604,11 @@ static av_cold int mjpeg_encode_init(AVCodecContext *avctx)
if (s->slice_context_count > 1)
m->huffman = HUFFMAN_TABLE_DEFAULT;
if (m->huffman == HUFFMAN_TABLE_OPTIMAL)
if (m->huffman == HUFFMAN_TABLE_OPTIMAL) {
// If we are here, we have only one slice_context. So no loop necessary.
s->encode_mb = mjpeg_record_mb;
return alloc_huffman(m2);
}
return 0;
}

View File

@ -94,7 +94,6 @@ static inline void put_marker(PutBitContext *p, enum JpegMarker code)
typedef struct MpegEncContext MpegEncContext;
void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64]);
int ff_mjpeg_encode_stuffing(MpegEncContext *s);
#endif /* AVCODEC_MJPEGENC_H */

View File

@ -929,7 +929,7 @@ static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s,
}
}
void ff_mpeg1_encode_mb(MpegEncContext *s, int16_t block[8][64],
static void mpeg12_encode_mb(MpegEncContext *s, int16_t block[][64],
int motion_x, int motion_y)
{
if (!s->mb_intra)
@ -1111,6 +1111,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
}
m->encode_picture_header = mpeg1_encode_picture_header;
s->encode_mb = mpeg12_encode_mb;
s->me.mv_penalty = mv_penalty;
m->fcode_tab = fcode_tab + MAX_MV;

View File

@ -27,8 +27,6 @@
#include "mpegvideo.h"
#include "mpegvideodata.h"
void ff_mpeg1_encode_mb(MpegEncContext *s, int16_t block[8][64],
int motion_x, int motion_y);
void ff_mpeg1_encode_slice_header(MpegEncContext *s);
// Must not be called before intra_dc_precision has been sanitized in ff_mpv_encode_init()

View File

@ -499,7 +499,7 @@ static inline int get_b_cbp(MpegEncContext *s, int16_t block[6][64],
// FIXME this is duplicated to h263.c
static const int dquant_code[5] = { 1, 0, 9, 2, 3 };
void ff_mpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64],
static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64],
int motion_x, int motion_y)
{
int cbpc, cbpy, pred_x, pred_y;
@ -1301,6 +1301,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
}
m->encode_picture_header = mpeg4_encode_picture_header;
s->encode_mb = mpeg4_encode_mb;
ff_qpeldsp_init(&s->qdsp);
if ((ret = ff_mpv_encode_init(avctx)) < 0)

View File

@ -29,9 +29,6 @@
typedef struct MpegEncContext MpegEncContext;
void ff_mpeg4_encode_mb(MpegEncContext *s,
int16_t block[6][64],
int motion_x, int motion_y);
void ff_set_mpeg4_time(MpegEncContext *s);
void ff_mpeg4_encode_video_packet_header(MpegEncContext *s);

View File

@ -438,7 +438,11 @@ typedef struct MpegEncContext {
int16_t (*block)[64]; ///< points to one of the following blocks
int16_t (*blocks)[12][64]; // for HQ mode we need to keep the best block
union {
int (*decode_mb)(struct MpegEncContext *s, int16_t block[12][64]); // used by some codecs to avoid a switch()
void (*encode_mb)(struct MpegEncContext *s, int16_t block[][64],
int motion_x, int motion_y);
};
#define SLICE_OK 0
#define SLICE_ERROR -1

View File

@ -71,7 +71,6 @@
#include "mpeg4videoenc.h"
#include "internal.h"
#include "bytestream.h"
#include "wmv2enc.h"
#include "rv10enc.h"
#include "packet_internal.h"
#include "libavutil/refstruct.h"
@ -2562,52 +2561,7 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
}
}
/* huffman encode */
switch(s->codec_id){ //FIXME funct ptr could be slightly faster
case AV_CODEC_ID_MPEG1VIDEO:
case AV_CODEC_ID_MPEG2VIDEO:
if (CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER)
ff_mpeg1_encode_mb(s, s->block, motion_x, motion_y);
break;
case AV_CODEC_ID_MPEG4:
if (CONFIG_MPEG4_ENCODER)
ff_mpeg4_encode_mb(s, s->block, motion_x, motion_y);
break;
case AV_CODEC_ID_MSMPEG4V2:
case AV_CODEC_ID_MSMPEG4V3:
case AV_CODEC_ID_WMV1:
if (CONFIG_MSMPEG4ENC)
ff_msmpeg4_encode_mb(s, s->block, motion_x, motion_y);
break;
case AV_CODEC_ID_WMV2:
if (CONFIG_WMV2_ENCODER)
ff_wmv2_encode_mb(s, s->block, motion_x, motion_y);
break;
case AV_CODEC_ID_H261:
if (CONFIG_H261_ENCODER)
ff_h261_encode_mb(s, s->block, motion_x, motion_y);
break;
case AV_CODEC_ID_H263:
case AV_CODEC_ID_H263P:
case AV_CODEC_ID_FLV1:
case AV_CODEC_ID_RV10:
case AV_CODEC_ID_RV20:
if (CONFIG_H263_ENCODER)
ff_h263_encode_mb(s, s->block, motion_x, motion_y);
break;
#if CONFIG_MJPEG_ENCODER || CONFIG_AMV_ENCODER
case AV_CODEC_ID_MJPEG:
case AV_CODEC_ID_AMV:
ff_mjpeg_encode_mb(s, s->block);
break;
#endif
case AV_CODEC_ID_SPEEDHQ:
if (CONFIG_SPEEDHQ_ENCODER)
ff_speedhq_encode_mb(s, s->block);
break;
default:
av_assert1(0);
}
s->encode_mb(s, s->block, motion_x, motion_y);
}
static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)

View File

@ -370,8 +370,8 @@ static void msmpeg4v2_encode_motion(MpegEncContext * s, int val)
}
}
void ff_msmpeg4_encode_mb(MpegEncContext * s,
int16_t block[6][64],
static void msmpeg4_encode_mb(MpegEncContext *const s,
int16_t block[][64],
int motion_x, int motion_y)
{
int cbp, coded_cbp, i;
@ -670,8 +670,10 @@ av_cold void ff_msmpeg4_encode_init(MPVMainEncContext *const m)
ff_msmpeg4_common_init(s);
if (s->msmpeg4_version <= MSMP4_WMV1)
if (s->msmpeg4_version <= MSMP4_WMV1) {
m->encode_picture_header = msmpeg4_encode_picture_header;
s->encode_mb = msmpeg4_encode_mb;
}
if (s->msmpeg4_version >= MSMP4_WMV1) {
s->min_qcoeff = -255;

View File

@ -35,8 +35,6 @@ typedef struct MSMPEG4EncContext {
void ff_msmpeg4_encode_init(MPVMainEncContext *m);
void ff_msmpeg4_encode_ext_header(MpegEncContext *s);
void ff_msmpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64],
int motion_x, int motion_y);
void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n);
void ff_msmpeg4_handle_slices(MpegEncContext *s);
void ff_msmpeg4_encode_motion(MpegEncContext * s, int mx, int my);

View File

@ -207,7 +207,8 @@ static void encode_block(MpegEncContext *s, int16_t *block, int n)
put_bits_le(&s->pb, 4, 6);
}
void ff_speedhq_encode_mb(MpegEncContext *s, int16_t block[12][64])
static void speedhq_encode_mb(MpegEncContext *const s, int16_t block[12][64],
int unused_x, int unused_y)
{
int i;
for(i=0;i<6;i++) {
@ -263,6 +264,7 @@ static av_cold int speedhq_encode_init(AVCodecContext *avctx)
}
m->encode_picture_header = speedhq_encode_picture_header;
s->encode_mb = speedhq_encode_mb;
s->min_qcoeff = -2048;
s->max_qcoeff = 2047;

View File

@ -33,8 +33,6 @@
#include "mpegvideo.h"
void ff_speedhq_encode_mb(MpegEncContext *s, int16_t block[12][64]);
void ff_speedhq_end_slice(MpegEncContext *s);
static inline int ff_speedhq_mb_rows_in_slice(int slice_num, int mb_height)

View File

@ -29,7 +29,6 @@
#include "msmpeg4data.h"
#include "msmpeg4_vc1_data.h"
#include "wmv2.h"
#include "wmv2enc.h"
#define WMV2_EXTRADATA_SIZE 4
@ -147,7 +146,7 @@ static int wmv2_encode_picture_header(MPVMainEncContext *const m)
/* Nearly identical to wmv1 but that is just because we do not use the
* useless M$ crap features. It is duplicated here in case someone wants
* to add support for these crap features. */
void ff_wmv2_encode_mb(MpegEncContext *s, int16_t block[6][64],
static void wmv2_encode_mb(MpegEncContext *const s, int16_t block[][64],
int motion_x, int motion_y)
{
WMV2EncContext *const w = (WMV2EncContext *) s;
@ -224,6 +223,7 @@ static av_cold int wmv2_encode_init(AVCodecContext *avctx)
int ret;
w->msmpeg4.m.encode_picture_header = wmv2_encode_picture_header;
s->encode_mb = wmv2_encode_mb;
s->private_ctx = &w->common;
ret = ff_mpv_encode_init(avctx);
if (ret < 0)

View File

@ -1,30 +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
*/
#ifndef AVCODEC_WMV2ENC_H
#define AVCODEC_WMV2ENC_H
#include "mpegvideo.h"
void ff_wmv2_encode_mb(MpegEncContext * s, int16_t block[6][64],
int motion_x, int motion_y);
#endif