From f793074784ae79dabc4f83b61710161b3fe3288c Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt Date: Thu, 13 Jun 2024 15:05:52 +0200 Subject: [PATCH] avcodec/h261dec: Unquantize coefficients while parsing them This is beneficial for performance: When concatenating the file from the vsynth1-h261 fate-test 100 times, performance (measured by timing the codec's decode callback) improved by 9.6%. Signed-off-by: Andreas Rheinhardt --- libavcodec/h261dec.c | 11 +++++++++-- libavcodec/mpegvideo_dec.c | 11 ++++++----- libavcodec/mpegvideo_enc.c | 2 +- libavcodec/mpv_reconstruct_mb_template.c | 24 ++++++++++++------------ 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c index f1c1e1a48a..6df8588bb6 100644 --- a/libavcodec/h261dec.c +++ b/libavcodec/h261dec.c @@ -244,6 +244,7 @@ static int h261_decode_block(H261DecContext *h, int16_t *block, int n, int coded int level, i, j, run; const RLTable *rl = &ff_h261_rl_tcoeff; const uint8_t *scan_table; + const int qmul = s->qscale << 1, qadd = (s->qscale - 1) | 1; /* For the variable length encoding there are two code tables, one being * used for the first transmitted LEVEL in INTER, INTER + MC and @@ -265,7 +266,7 @@ static int h261_decode_block(H261DecContext *h, int16_t *block, int n, int coded * being coded as 1111 1111. */ if (level == 255) level = 128; - block[0] = level; + block[0] = level * s->y_dc_scale; i = 1; } else if (coded) { // Run Level Code @@ -276,7 +277,8 @@ static int h261_decode_block(H261DecContext *h, int16_t *block, int n, int coded i = 0; if (check & 0x2) { skip_bits(&s->gb, 2); - block[0] = (check & 0x1) ? -1 : 1; + block[0] = qmul + qadd; + block[0] *= (check & 0x1) ? -1 : 1; i = 1; } } else { @@ -306,10 +308,15 @@ static int h261_decode_block(H261DecContext *h, int16_t *block, int n, int coded run = SHOW_UBITS(re, &s->gb, 6) + 1; SKIP_CACHE(re, &s->gb, 6); level = SHOW_SBITS(re, &s->gb, 8); + if (level > 0) + level = level * qmul + qadd; + else if (level < 0) + level = level * qmul - qadd; SKIP_COUNTER(re, &s->gb, 6 + 8); } else if (level == 0) { break; } else { + level = level * qmul + qadd; if (SHOW_UBITS(re, &s->gb, 1)) level = -level; SKIP_COUNTER(re, &s->gb, 1); diff --git a/libavcodec/mpegvideo_dec.c b/libavcodec/mpegvideo_dec.c index 684f31947c..da88a35120 100644 --- a/libavcodec/mpegvideo_dec.c +++ b/libavcodec/mpegvideo_dec.c @@ -927,15 +927,16 @@ void ff_mpv_reconstruct_mb(MpegEncContext *s, int16_t block[12][64]) } } + av_assert2((s->out_format <= FMT_H261) == (s->out_format == FMT_H261 || s->out_format == FMT_MPEG1)); if (!s->avctx->lowres) { #if !CONFIG_SMALL - if (s->out_format == FMT_MPEG1) - mpv_reconstruct_mb_internal(s, block, 0, DEFINITELY_MPEG12); + if (s->out_format <= FMT_H261) + mpv_reconstruct_mb_internal(s, block, 0, DEFINITELY_MPEG12_H261); else - mpv_reconstruct_mb_internal(s, block, 0, NOT_MPEG12); + mpv_reconstruct_mb_internal(s, block, 0, NOT_MPEG12_H261); #else - mpv_reconstruct_mb_internal(s, block, 0, MAY_BE_MPEG12); + mpv_reconstruct_mb_internal(s, block, 0, MAY_BE_MPEG12_H261); #endif } else - mpv_reconstruct_mb_internal(s, block, 1, MAY_BE_MPEG12); + mpv_reconstruct_mb_internal(s, block, 1, MAY_BE_MPEG12_H261); } diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 125d16e694..d05a93d249 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -1101,7 +1101,7 @@ static void mpv_reconstruct_mb(MpegEncContext *s, int16_t block[12][64]) } } - mpv_reconstruct_mb_internal(s, block, 0, MAY_BE_MPEG12); + mpv_reconstruct_mb_internal(s, block, 0, MAY_BE_MPEG12_H261); } static int get_sae(const uint8_t *src, int ref, int stride) diff --git a/libavcodec/mpv_reconstruct_mb_template.c b/libavcodec/mpv_reconstruct_mb_template.c index 4b16974827..dca982ae0f 100644 --- a/libavcodec/mpv_reconstruct_mb_template.c +++ b/libavcodec/mpv_reconstruct_mb_template.c @@ -20,9 +20,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define NOT_MPEG12 0 -#define MAY_BE_MPEG12 1 -#define DEFINITELY_MPEG12 2 +#define NOT_MPEG12_H261 0 +#define MAY_BE_MPEG12_H261 1 +#define DEFINITELY_MPEG12_H261 2 /* put block[] to dest[] */ static inline void put_dct(MpegEncContext *s, @@ -56,14 +56,14 @@ static av_always_inline void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64], int lowres_flag, int is_mpeg12) { -#define IS_MPEG12(s) (is_mpeg12 == MAY_BE_MPEG12 ? ((s)->out_format == FMT_MPEG1) : is_mpeg12) +#define IS_MPEG12_H261(s) (is_mpeg12 == MAY_BE_MPEG12_H261 ? ((s)->out_format <= FMT_H261) : is_mpeg12) const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; s->cur_pic.qscale_table[mb_xy] = s->qscale; /* update DC predictors for P macroblocks */ if (!s->mb_intra) { - if (is_mpeg12 != DEFINITELY_MPEG12 && (s->h263_pred || s->h263_aic)) { + if (is_mpeg12 != DEFINITELY_MPEG12_H261 && (s->h263_pred || s->h263_aic)) { if (s->mbintra_table[mb_xy]) ff_clean_intra_table_entries(s); } else { @@ -71,7 +71,7 @@ void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64], s->last_dc[1] = s->last_dc[2] = 128 << s->intra_dc_precision; } - } else if (is_mpeg12 != DEFINITELY_MPEG12 && (s->h263_pred || s->h263_aic)) + } else if (is_mpeg12 != DEFINITELY_MPEG12_H261 && (s->h263_pred || s->h263_aic)) s->mbintra_table[mb_xy] = 1; #if IS_ENCODER @@ -110,7 +110,7 @@ void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64], /* decoding or more than one mb_type (MC was already done otherwise) */ #if !IS_ENCODER - if (HAVE_THREADS && is_mpeg12 != DEFINITELY_MPEG12 && + if (HAVE_THREADS && is_mpeg12 != DEFINITELY_MPEG12_H261 && s->avctx->active_thread_type & FF_THREAD_FRAME) { if (s->mv_dir & MV_DIR_FORWARD) { ff_thread_progress_await(&s->last_pic.ptr->progress, @@ -136,7 +136,7 @@ void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64], const op_pixels_func (*op_pix)[4]; const qpel_mc_func (*op_qpix)[16]; - if ((is_mpeg12 == DEFINITELY_MPEG12 || !s->no_rounding) || s->pict_type == AV_PICTURE_TYPE_B) { + if ((is_mpeg12 == DEFINITELY_MPEG12_H261 || !s->no_rounding) || s->pict_type == AV_PICTURE_TYPE_B) { op_pix = s->hdsp.put_pixels_tab; op_qpix = s->qdsp.put_qpel_pixels_tab; } else { @@ -162,7 +162,7 @@ void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64], } /* add dct residue */ - if (!(IS_MPEG12(s) || s->msmpeg4_version != MSMP4_UNUSED || + if (!(IS_MPEG12_H261(s) || s->msmpeg4_version != MSMP4_UNUSED || (s->codec_id == AV_CODEC_ID_MPEG4 && !s->mpeg_quant))) #endif /* !IS_ENCODER */ { @@ -187,7 +187,7 @@ void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64], } } #if !IS_ENCODER - else if (is_mpeg12 == DEFINITELY_MPEG12 || lowres_flag || (s->codec_id != AV_CODEC_ID_WMV2)) { + else if (is_mpeg12 == DEFINITELY_MPEG12_H261 || lowres_flag || (s->codec_id != AV_CODEC_ID_WMV2)) { add_dct(s, block[0], 0, dest_y , dct_linesize); add_dct(s, block[1], 1, dest_y + block_size, dct_linesize); add_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize); @@ -222,12 +222,12 @@ void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64], #if !IS_ENCODER /* Only MPEG-4 Simple Studio Profile is supported in > 8-bit mode. TODO: Integrate 10-bit properly into mpegvideo.c so that ER works properly */ - if (is_mpeg12 != DEFINITELY_MPEG12 && CONFIG_MPEG4_DECODER && + if (is_mpeg12 != DEFINITELY_MPEG12_H261 && CONFIG_MPEG4_DECODER && /* s->codec_id == AV_CODEC_ID_MPEG4 && */ s->avctx->bits_per_raw_sample > 8) { ff_mpeg4_decode_studio(s, dest_y, dest_cb, dest_cr, block_size, uvlinesize, dct_linesize, dct_offset); - } else if (!IS_MPEG12(s)) + } else if (!IS_MPEG12_H261(s)) #endif /* !IS_ENCODER */ { /* dct only in intra block */