[FFmpeg-devel] [PATCH 3/9] avcodecc/asvdec: Avoid reversing input data twice
Andreas Rheinhardt
andreas.rheinhardt at gmail.com
Sat Oct 17 21:17:36 EEST 2020
Andreas Rheinhardt:
> Up until now the ASV2 decoder used an ordinary big-endian bitreader to
> read data actually destined for a little-endian bitreader; this is done
> by reversing the whole input packet bitwise, using the big-endian
> bigreader and reversing (and shifting) the result again. This commit
> stops this and instead uses a little-endian bitreader directly.
>
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
> ---
> libavcodec/asvdec.c | 77 ++++++++++++++++++++++++++-------------------
> 1 file changed, 44 insertions(+), 33 deletions(-)
>
> diff --git a/libavcodec/asvdec.c b/libavcodec/asvdec.c
> index 6198188fc5..78e53b6402 100644
> --- a/libavcodec/asvdec.c
> +++ b/libavcodec/asvdec.c
> @@ -31,7 +31,6 @@
> #include "blockdsp.h"
> #include "idctdsp.h"
> #include "internal.h"
> -#include "mathops.h"
> #include "mpeg12data.h"
>
> #define CCP_VLC_BITS 5
> @@ -56,27 +55,24 @@ static av_cold void init_vlcs(ASV1Context *a)
> INIT_VLC_STATIC(&ccp_vlc, CCP_VLC_BITS, 17,
> &ff_asv_ccp_tab[0][1], 2, 1,
> &ff_asv_ccp_tab[0][0], 2, 1, 32);
> - INIT_VLC_STATIC(&dc_ccp_vlc, DC_CCP_VLC_BITS, 8,
> - &ff_asv_dc_ccp_tab[0][1], 2, 1,
> - &ff_asv_dc_ccp_tab[0][0], 2, 1, 16);
> - INIT_VLC_STATIC(&ac_ccp_vlc, AC_CCP_VLC_BITS, 16,
> - &ff_asv_ac_ccp_tab[0][1], 2, 1,
> - &ff_asv_ac_ccp_tab[0][0], 2, 1, 64);
> + INIT_CUSTOM_VLC_STATIC(&dc_ccp_vlc, DC_CCP_VLC_BITS, 8,
> + &ff_asv_dc_ccp_tab[0][1], 2, 1,
> + &ff_asv_dc_ccp_tab[0][0], 2, 1,
> + INIT_VLC_OUTPUT_LE, 16);
> + INIT_CUSTOM_VLC_STATIC(&ac_ccp_vlc, AC_CCP_VLC_BITS, 16,
> + &ff_asv_ac_ccp_tab[0][1], 2, 1,
> + &ff_asv_ac_ccp_tab[0][0], 2, 1,
> + INIT_VLC_OUTPUT_LE, 64);
> INIT_VLC_STATIC(&level_vlc, ASV1_LEVEL_VLC_BITS, 7,
> &ff_asv_level_tab[0][1], 2, 1,
> &ff_asv_level_tab[0][0], 2, 1, 16);
> - INIT_VLC_STATIC(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63,
> - &ff_asv2_level_tab[0][1], 2, 1,
> - &ff_asv2_level_tab[0][0], 2, 1, 1024);
> + INIT_CUSTOM_VLC_STATIC(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63,
> + &ff_asv2_level_tab[0][1], 2, 1,
> + &ff_asv2_level_tab[0][0], 2, 1,
> + INIT_VLC_OUTPUT_LE, 1024);
> }
> }
>
> -// FIXME write a reversed bitstream reader to avoid the double reverse
> -static inline int asv2_get_bits(GetBitContext *gb, int n)
> -{
> - return ff_reverse[get_bits(gb, n) << (8 - n)];
> -}
> -
> static inline int asv1_get_level(GetBitContext *gb)
> {
> int code = get_vlc2(gb, level_vlc.table, ASV1_LEVEL_VLC_BITS, 1);
> @@ -87,12 +83,31 @@ static inline int asv1_get_level(GetBitContext *gb)
> return code - 3;
> }
>
> +// get_vlc2() is big-endian in this file
> +static inline int asv2_get_vlc2(GetBitContext *gb, VLC_TYPE (*table)[2], int bits)
> +{
> + unsigned int index;
> + int code, n;
> +
> + OPEN_READER(re, gb);
> + UPDATE_CACHE_LE(re, gb);
> +
> + index = SHOW_UBITS_LE(re, gb, bits);
> + code = table[index][0];
> + n = table[index][1];
> + LAST_SKIP_BITS(re, gb, n);
> +
> + CLOSE_READER(re, gb);
> +
> + return code;
> +}
> +
> static inline int asv2_get_level(GetBitContext *gb)
> {
> - int code = get_vlc2(gb, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS, 1);
> + int code = asv2_get_vlc2(gb, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS);
>
> if (code == 31)
> - return (int8_t) asv2_get_bits(gb, 8);
> + return (int8_t) get_bits_le(gb, 8);
> else
> return code - 31;
> }
> @@ -132,11 +147,11 @@ static inline int asv2_decode_block(ASV1Context *a, int16_t block[64])
> {
> int i, count, ccp;
>
> - count = asv2_get_bits(&a->gb, 4);
> + count = get_bits_le(&a->gb, 4);
>
> - block[0] = 8 * asv2_get_bits(&a->gb, 8);
> + block[0] = 8 * get_bits_le(&a->gb, 8);
>
> - ccp = get_vlc2(&a->gb, dc_ccp_vlc.table, DC_CCP_VLC_BITS, 1);
> + ccp = asv2_get_vlc2(&a->gb, dc_ccp_vlc.table, DC_CCP_VLC_BITS);
> if (ccp) {
> if (ccp & 4)
> block[a->scantable.permutated[1]] = (asv2_get_level(&a->gb) * a->intra_matrix[1]) >> 4;
> @@ -147,7 +162,7 @@ static inline int asv2_decode_block(ASV1Context *a, int16_t block[64])
> }
>
> for (i = 1; i < count + 1; i++) {
> - const int ccp = get_vlc2(&a->gb, ac_ccp_vlc.table, AC_CCP_VLC_BITS, 1);
> + const int ccp = asv2_get_vlc2(&a->gb, ac_ccp_vlc.table, AC_CCP_VLC_BITS);
>
> if (ccp) {
> if (ccp & 8)
> @@ -221,21 +236,18 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
> p->pict_type = AV_PICTURE_TYPE_I;
> p->key_frame = 1;
>
> - av_fast_padded_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size,
> - buf_size);
> - if (!a->bitstream_buffer)
> - return AVERROR(ENOMEM);
> -
> if (avctx->codec_id == AV_CODEC_ID_ASV1) {
> + av_fast_padded_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size,
> + buf_size);
> + if (!a->bitstream_buffer)
> + return AVERROR(ENOMEM);
> +
> a->bbdsp.bswap_buf((uint32_t *) a->bitstream_buffer,
> (const uint32_t *) buf, buf_size / 4);
> + ret = init_get_bits8(&a->gb, a->bitstream_buffer, buf_size);
> } else {
> - int i;
> - for (i = 0; i < buf_size; i++)
> - a->bitstream_buffer[i] = ff_reverse[buf[i]];
> + ret = init_get_bits8_le(&a->gb, buf, buf_size);
> }
> -
> - ret = init_get_bits8(&a->gb, a->bitstream_buffer, buf_size);
> if (ret < 0)
> return ret;
>
> @@ -342,7 +354,6 @@ AVCodec ff_asv2_decoder = {
> .id = AV_CODEC_ID_ASV2,
> .priv_data_size = sizeof(ASV1Context),
> .init = decode_init,
> - .close = decode_end,
> .decode = decode_frame,
> .capabilities = AV_CODEC_CAP_DR1,
> };
>
Will apply this patch and the rest of this patchset tomorrow unless
there are objections.
- Andreas
More information about the ffmpeg-devel
mailing list