aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/rv40.c
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-10-31 22:44:12 +0100
committerAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-12-08 17:51:46 +0100
commitfcde452a47d8987208df0cdaae1dd6025d7fbf3e (patch)
tree97e47d9f31bef0c430db6bb487a24006bfa4869e /libavcodec/rv40.c
parent47a72391d0745f5e558c1eecf97525b03161e136 (diff)
downloadffmpeg-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.c20
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)