diff options
author | Andreas Rheinhardt <andreas.rheinhardt@gmail.com> | 2020-10-31 22:44:12 +0100 |
---|---|---|
committer | Andreas Rheinhardt <andreas.rheinhardt@gmail.com> | 2020-12-08 17:51:46 +0100 |
commit | fcde452a47d8987208df0cdaae1dd6025d7fbf3e (patch) | |
tree | 97e47d9f31bef0c430db6bb487a24006bfa4869e /libavcodec/rv40.c | |
parent | 47a72391d0745f5e558c1eecf97525b03161e136 (diff) | |
download | ffmpeg-fcde452a47d8987208df0cdaae1dd6025d7fbf3e.tar.gz |
avcodec/rv40: Make better use of VLC symbols table
RealVideo 4.0 has a VLC that encodes two intra types per code; each
intra type is in the range 0..8 (inclusive) and up until now the VLC
used symbols in the range 0..80; one type was encoded as the remainder
when dividing the symbol by 9 whereas the other type was encoded as
symbol / 9. This is suboptimal; a better way would be to use the high
and low nibble to encode each symbol. But an even better way is to use
16bit symbols so that the two intra types can be directly written as
a 16bit value.
This commit implements this; in order to avoid huge tables the symbols
are stored as uint8_t with high and low nibbles encoding one type each;
they are only unpacked to uint16_t during initialization.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
Diffstat (limited to 'libavcodec/rv40.c')
-rw-r--r-- | libavcodec/rv40.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c index 4ecee930ff..6f9f2c5665 100644 --- a/libavcodec/rv40.c +++ b/libavcodec/rv40.c @@ -24,6 +24,8 @@ * RV40 decoder */ +#include "config.h" + #include "libavutil/imgutils.h" #include "avcodec.h" @@ -71,12 +73,21 @@ static av_cold void rv40_init_tables(void) aic_mode1_vlc_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); } for(i = 0; i < AIC_MODE2_NUM; i++){ + uint16_t syms[AIC_MODE2_SIZE]; + + for (int j = 0; j < AIC_MODE2_SIZE; j++) { + int first = aic_mode2_vlc_syms[i][j] >> 4; + int second = aic_mode2_vlc_syms[i][j] & 0xF; + if (HAVE_BIGENDIAN) + syms[j] = (first << 8) | second; + else + syms[j] = first | (second << 8); + } aic_mode2_vlc[i].table = &aic_mode2_table[mode2_offs[i]]; aic_mode2_vlc[i].table_allocated = mode2_offs[i + 1] - mode2_offs[i]; ff_init_vlc_from_lengths(&aic_mode2_vlc[i], AIC_MODE2_BITS, AIC_MODE2_SIZE, aic_mode2_vlc_bits[i], 1, - aic_mode2_vlc_syms[i], 1, 1, - 0, INIT_VLC_USE_NEW_STATIC, NULL); + syms, 2, 2, 0, INIT_VLC_USE_NEW_STATIC, NULL); } for(i = 0; i < NUM_PTYPE_VLCS; i++){ ptype_vlc[i].table = &ptype_table[i << PTYPE_VLC_BITS]; @@ -195,9 +206,8 @@ static int rv40_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int8_t if(pattern == rv40_aic_table_index[k]) break; if(j < 3 && k < MODE2_PATTERNS_NUM){ //pattern is found, decoding 2 coefficients - v = get_vlc2(gb, aic_mode2_vlc[k].table, AIC_MODE2_BITS, 2); - *ptr++ = v/9; - *ptr++ = v%9; + AV_WN16(ptr, get_vlc2(gb, aic_mode2_vlc[k].table, AIC_MODE2_BITS, 2)); + ptr += 2; j++; }else{ if(B != -1 && C != -1) |