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

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 <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt 2024-06-13 15:05:52 +02:00
parent 1745d12d67
commit f793074784
4 changed files with 28 additions and 20 deletions

View File

@ -244,6 +244,7 @@ static int h261_decode_block(H261DecContext *h, int16_t *block, int n, int coded
int level, i, j, run; int level, i, j, run;
const RLTable *rl = &ff_h261_rl_tcoeff; const RLTable *rl = &ff_h261_rl_tcoeff;
const uint8_t *scan_table; 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 /* For the variable length encoding there are two code tables, one being
* used for the first transmitted LEVEL in INTER, INTER + MC and * 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. */ * being coded as 1111 1111. */
if (level == 255) if (level == 255)
level = 128; level = 128;
block[0] = level; block[0] = level * s->y_dc_scale;
i = 1; i = 1;
} else if (coded) { } else if (coded) {
// Run Level Code // Run Level Code
@ -276,7 +277,8 @@ static int h261_decode_block(H261DecContext *h, int16_t *block, int n, int coded
i = 0; i = 0;
if (check & 0x2) { if (check & 0x2) {
skip_bits(&s->gb, 2); skip_bits(&s->gb, 2);
block[0] = (check & 0x1) ? -1 : 1; block[0] = qmul + qadd;
block[0] *= (check & 0x1) ? -1 : 1;
i = 1; i = 1;
} }
} else { } 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; run = SHOW_UBITS(re, &s->gb, 6) + 1;
SKIP_CACHE(re, &s->gb, 6); SKIP_CACHE(re, &s->gb, 6);
level = SHOW_SBITS(re, &s->gb, 8); 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); SKIP_COUNTER(re, &s->gb, 6 + 8);
} else if (level == 0) { } else if (level == 0) {
break; break;
} else { } else {
level = level * qmul + qadd;
if (SHOW_UBITS(re, &s->gb, 1)) if (SHOW_UBITS(re, &s->gb, 1))
level = -level; level = -level;
SKIP_COUNTER(re, &s->gb, 1); SKIP_COUNTER(re, &s->gb, 1);

View File

@ -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 (!s->avctx->lowres) {
#if !CONFIG_SMALL #if !CONFIG_SMALL
if (s->out_format == FMT_MPEG1) if (s->out_format <= FMT_H261)
mpv_reconstruct_mb_internal(s, block, 0, DEFINITELY_MPEG12); mpv_reconstruct_mb_internal(s, block, 0, DEFINITELY_MPEG12_H261);
else else
mpv_reconstruct_mb_internal(s, block, 0, NOT_MPEG12); mpv_reconstruct_mb_internal(s, block, 0, NOT_MPEG12_H261);
#else #else
mpv_reconstruct_mb_internal(s, block, 0, MAY_BE_MPEG12); mpv_reconstruct_mb_internal(s, block, 0, MAY_BE_MPEG12_H261);
#endif #endif
} else } else
mpv_reconstruct_mb_internal(s, block, 1, MAY_BE_MPEG12); mpv_reconstruct_mb_internal(s, block, 1, MAY_BE_MPEG12_H261);
} }

View File

@ -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) static int get_sae(const uint8_t *src, int ref, int stride)

View File

@ -20,9 +20,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#define NOT_MPEG12 0 #define NOT_MPEG12_H261 0
#define MAY_BE_MPEG12 1 #define MAY_BE_MPEG12_H261 1
#define DEFINITELY_MPEG12 2 #define DEFINITELY_MPEG12_H261 2
/* put block[] to dest[] */ /* put block[] to dest[] */
static inline void put_dct(MpegEncContext *s, 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], void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64],
int lowres_flag, int is_mpeg12) 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; const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
s->cur_pic.qscale_table[mb_xy] = s->qscale; s->cur_pic.qscale_table[mb_xy] = s->qscale;
/* update DC predictors for P macroblocks */ /* update DC predictors for P macroblocks */
if (!s->mb_intra) { 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]) if (s->mbintra_table[mb_xy])
ff_clean_intra_table_entries(s); ff_clean_intra_table_entries(s);
} else { } else {
@ -71,7 +71,7 @@ void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64],
s->last_dc[1] = s->last_dc[1] =
s->last_dc[2] = 128 << s->intra_dc_precision; 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; s->mbintra_table[mb_xy] = 1;
#if IS_ENCODER #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) */ /* decoding or more than one mb_type (MC was already done otherwise) */
#if !IS_ENCODER #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) { s->avctx->active_thread_type & FF_THREAD_FRAME) {
if (s->mv_dir & MV_DIR_FORWARD) { if (s->mv_dir & MV_DIR_FORWARD) {
ff_thread_progress_await(&s->last_pic.ptr->progress, 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 op_pixels_func (*op_pix)[4];
const qpel_mc_func (*op_qpix)[16]; 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_pix = s->hdsp.put_pixels_tab;
op_qpix = s->qdsp.put_qpel_pixels_tab; op_qpix = s->qdsp.put_qpel_pixels_tab;
} else { } else {
@ -162,7 +162,7 @@ void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64],
} }
/* add dct residue */ /* 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))) (s->codec_id == AV_CODEC_ID_MPEG4 && !s->mpeg_quant)))
#endif /* !IS_ENCODER */ #endif /* !IS_ENCODER */
{ {
@ -187,7 +187,7 @@ void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64],
} }
} }
#if !IS_ENCODER #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[0], 0, dest_y , dct_linesize);
add_dct(s, block[1], 1, dest_y + block_size, 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); 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 #if !IS_ENCODER
/* Only MPEG-4 Simple Studio Profile is supported in > 8-bit mode. /* 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 */ 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->codec_id == AV_CODEC_ID_MPEG4 && */
s->avctx->bits_per_raw_sample > 8) { s->avctx->bits_per_raw_sample > 8) {
ff_mpeg4_decode_studio(s, dest_y, dest_cb, dest_cr, block_size, ff_mpeg4_decode_studio(s, dest_y, dest_cb, dest_cr, block_size,
uvlinesize, dct_linesize, dct_offset); uvlinesize, dct_linesize, dct_offset);
} else if (!IS_MPEG12(s)) } else if (!IS_MPEG12_H261(s))
#endif /* !IS_ENCODER */ #endif /* !IS_ENCODER */
{ {
/* dct only in intra block */ /* dct only in intra block */