Message ID | 20201013091017.1899676-3-andreas.rheinhardt@gmail.com |
---|---|
State | Accepted |
Commit | cdf7619705611983724e98dee2c5659449fd0e30 |
Headers | show |
Series | [FFmpeg-devel,1/9] avcodec/asvdec: Reduce the size of some VLCs | expand |
Context | Check | Description |
---|---|---|
andriy/x86_make | success | Make finished |
andriy/x86_make_fate | success | Make fate finished |
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@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
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, };
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@gmail.com> --- libavcodec/asvdec.c | 77 ++++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 33 deletions(-)