Commit c03a7172 authored by Michael Niedermayer's avatar Michael Niedermayer

rl decoding optimization

Originally committed as revision 755 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent e3e98d3c
...@@ -1704,10 +1704,10 @@ void h263_decode_init_vlc(MpegEncContext *s) ...@@ -1704,10 +1704,10 @@ void h263_decode_init_vlc(MpegEncContext *s)
init_vlc_rl(&rl_inter); init_vlc_rl(&rl_inter);
init_vlc_rl(&rl_intra); init_vlc_rl(&rl_intra);
init_vlc_rl(&rl_intra_aic); init_vlc_rl(&rl_intra_aic);
init_vlc(&dc_lum, DC_VLC_BITS, 9 /* 13 */, init_vlc(&dc_lum, DC_VLC_BITS, 10 /* 13 */,
&DCtab_lum[0][1], 2, 1, &DCtab_lum[0][1], 2, 1,
&DCtab_lum[0][0], 2, 1); &DCtab_lum[0][0], 2, 1);
init_vlc(&dc_chrom, DC_VLC_BITS, 9 /* 13 */, init_vlc(&dc_chrom, DC_VLC_BITS, 10 /* 13 */,
&DCtab_chrom[0][1], 2, 1, &DCtab_chrom[0][1], 2, 1,
&DCtab_chrom[0][0], 2, 1); &DCtab_chrom[0][0], 2, 1);
init_vlc(&sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15, init_vlc(&sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15,
...@@ -2917,10 +2917,12 @@ static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) ...@@ -2917,10 +2917,12 @@ static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
int n, int coded) int n, int coded)
{ {
int code, level, i, j, last, run; int level, i, last, run;
int dc_pred_dir; int dc_pred_dir;
RLTable *rl; RLTable *rl;
RL_VLC_ELEM *rl_vlc;
const UINT8 *scan_table; const UINT8 *scan_table;
int qmul, qadd;
if (s->mb_intra) { if (s->mb_intra) {
/* DC coef */ /* DC coef */
...@@ -2935,10 +2937,11 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, ...@@ -2935,10 +2937,11 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
return DECODING_ACDC_LOST; return DECODING_ACDC_LOST;
} }
block[0] = level; block[0] = level;
i = 1; i = 0;
if (!coded) if (!coded)
goto not_coded; goto not_coded;
rl = &rl_intra; rl = &rl_intra;
rl_vlc = rl_intra.rl_vlc[0];
if (s->ac_pred) { if (s->ac_pred) {
if (dc_pred_dir == 0) if (dc_pred_dir == 0)
scan_table = ff_alternate_vertical_scan; /* left */ scan_table = ff_alternate_vertical_scan; /* left */
...@@ -2947,37 +2950,52 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, ...@@ -2947,37 +2950,52 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
} else { } else {
scan_table = zigzag_direct; scan_table = zigzag_direct;
} }
qmul=1;
qadd=0;
} else { } else {
i = 0; i = -1;
if (!coded) { if (!coded) {
s->block_last_index[n] = i - 1; s->block_last_index[n] = i;
return 0; return 0;
} }
rl = &rl_inter; rl = &rl_inter;
rl_vlc = rl_inter.rl_vlc[s->qscale];
scan_table = zigzag_direct; scan_table = zigzag_direct;
qmul = s->qscale << 1;
qadd = (s->qscale - 1) | 1;
} }
{
OPEN_READER(re, &s->gb);
for(;;) { for(;;) {
code = get_vlc2(&s->gb, rl->vlc.table, TEX_VLC_BITS, 2); UPDATE_CACHE(re, &s->gb);
if (code < 0) GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2);
return DECODING_AC_LOST; if (level==0) {
if (code == rl->n) { int cache;
cache= GET_CACHE(re, &s->gb);
/* escape */ /* escape */
if (get_bits1(&s->gb) != 0) { if (cache&0x80000000) {
if (get_bits1(&s->gb) != 0) { if (cache&0x40000000) {
/* third escape */ /* third escape */
last = get_bits1(&s->gb); SKIP_CACHE(re, &s->gb, 2);
run = get_bits(&s->gb, 6); last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1);
if(get_bits1(&s->gb)==0){ run= SHOW_UBITS(re, &s->gb, 6); LAST_SKIP_CACHE(re, &s->gb, 6);
SKIP_COUNTER(re, &s->gb, 2+1+6);
UPDATE_CACHE(re, &s->gb);
if(SHOW_UBITS(re, &s->gb, 1)==0){
fprintf(stderr, "1. marker bit missing in 3. esc\n"); fprintf(stderr, "1. marker bit missing in 3. esc\n");
return DECODING_AC_LOST; return DECODING_AC_LOST;
} }; SKIP_CACHE(re, &s->gb, 1);
level = get_bits(&s->gb, 12);
level = (level << 20) >> 20; /* sign extend */ level= SHOW_SBITS(re, &s->gb, 12); SKIP_CACHE(re, &s->gb, 12);
if(get_bits1(&s->gb)==0){
if(SHOW_UBITS(re, &s->gb, 1)==0){
fprintf(stderr, "2. marker bit missing in 3. esc\n"); fprintf(stderr, "2. marker bit missing in 3. esc\n");
return DECODING_AC_LOST; return DECODING_AC_LOST;
} }; LAST_SKIP_CACHE(re, &s->gb, 1);
SKIP_COUNTER(re, &s->gb, 1+12+1);
if(level>512 || level<-512){ //FIXME check that QP=1 is ok with this too if(level>512 || level<-512){ //FIXME check that QP=1 is ok with this too
fprintf(stderr, "|level| overflow in 3. esc\n"); fprintf(stderr, "|level| overflow in 3. esc\n");
return DECODING_AC_LOST; return DECODING_AC_LOST;
...@@ -3002,54 +3020,66 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, ...@@ -3002,54 +3020,66 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
} }
} }
#endif #endif
if (level>0) level= level * qmul + qadd;
else level= level * qmul - qadd;
i+= run + 1;
if(last) i+=192;
} else { } else {
/* second escape */ /* second escape */
code = get_vlc2(&s->gb, rl->vlc.table, TEX_VLC_BITS, 2); #if MIN_CACHE_BITS < 20
if (code < 0 || code >= rl->n) LAST_SKIP_BITS(re, &s->gb, 2);
return DECODING_AC_LOST; UPDATE_CACHE(re, &s->gb);
run = rl->table_run[code]; #else
level = rl->table_level[code]; SKIP_BITS(re, &s->gb, 2);
last = code >= rl->last; #endif
run += rl->max_run[last][level] + 1; GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2);
if (get_bits1(&s->gb)) i+= run + rl->max_run[run>>7][level/qmul] +1; //FIXME opt indexing
level = -level; level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
LAST_SKIP_BITS(re, &s->gb, 1);
} }
} else { } else {
/* first escape */ /* first escape */
code = get_vlc2(&s->gb, rl->vlc.table, TEX_VLC_BITS, 2); #if MIN_CACHE_BITS < 19
if (code < 0 || code >= rl->n) LAST_SKIP_BITS(re, &s->gb, 1);
return DECODING_AC_LOST; UPDATE_CACHE(re, &s->gb);
run = rl->table_run[code]; #else
level = rl->table_level[code]; SKIP_BITS(re, &s->gb, 1);
last = code >= rl->last; #endif
level += rl->max_level[last][run]; GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2);
if (get_bits1(&s->gb)) i+= run;
level = -level; level = level + rl->max_level[run>>7][(run-1)&63] * qmul;//FIXME opt indexing
level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
LAST_SKIP_BITS(re, &s->gb, 1);
} }
} else { } else {
run = rl->table_run[code]; i+= run;
level = rl->table_level[code]; level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
last = code >= rl->last; LAST_SKIP_BITS(re, &s->gb, 1);
if (get_bits1(&s->gb))
level = -level;
} }
i += run; if (i > 62){
if (i >= 64) i-= 192;
return DECODING_AC_LOST; if(i&(~63)){
j = scan_table[i]; fprintf(stderr, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
block[j] = level; return DECODING_AC_LOST;
i++; }
if (last)
block[scan_table[i]] = level;
break; break;
}
block[scan_table[i]] = level;
} }
CLOSE_READER(re, &s->gb);
}
not_coded: not_coded:
if (s->mb_intra) { if (s->mb_intra) {
mpeg4_pred_ac(s, block, n, dc_pred_dir); mpeg4_pred_ac(s, block, n, dc_pred_dir);
if (s->ac_pred) { if (s->ac_pred) {
i = 64; /* XXX: not optimal */ i = 63; /* XXX: not optimal */
} }
} }
s->block_last_index[n] = i - 1; s->block_last_index[n] = i;
return 0; return 0;
} }
......
...@@ -1318,7 +1318,7 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) ...@@ -1318,7 +1318,7 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
if(s->hurry_up>1) goto the_end; if(s->hurry_up>1) goto the_end;
/* add dct residue */ /* add dct residue */
if(!s->mpeg2 && (s->encoding || (!s->h263_msmpeg4))){ if(s->encoding || !(s->mpeg2 || s->h263_msmpeg4 || s->codec_id==CODEC_ID_MPEG4)){
add_dequant_dct(s, block[0], 0, dest_y, dct_linesize); add_dequant_dct(s, block[0], 0, dest_y, dct_linesize);
add_dequant_dct(s, block[1], 1, dest_y + 8, dct_linesize); add_dequant_dct(s, block[1], 1, dest_y + 8, dct_linesize);
add_dequant_dct(s, block[2], 2, dest_y + dct_offset, dct_linesize); add_dequant_dct(s, block[2], 2, dest_y + dct_offset, dct_linesize);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment