aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2002-07-13 17:30:43 +0000
committerMichael Niedermayer <michaelni@gmx.at>2002-07-13 17:30:43 +0000
commitc03a717274d8044289576a59752dadf27852571b (patch)
tree03c12e058cb03d05d513cd996c9425068692fceb /libavcodec
parente3e98d3c2330bef78a513e24ce33b037e3e59a91 (diff)
downloadffmpeg-c03a717274d8044289576a59752dadf27852571b.tar.gz
rl decoding optimization
Originally committed as revision 755 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/h263.c136
-rw-r--r--libavcodec/mpegvideo.c2
2 files changed, 84 insertions, 54 deletions
diff --git a/libavcodec/h263.c b/libavcodec/h263.c
index eff6e59fc4..d016f19725 100644
--- a/libavcodec/h263.c
+++ b/libavcodec/h263.c
@@ -1704,10 +1704,10 @@ void h263_decode_init_vlc(MpegEncContext *s)
init_vlc_rl(&rl_inter);
init_vlc_rl(&rl_intra);
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][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][0], 2, 1);
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)
static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
int n, int coded)
{
- int code, level, i, j, last, run;
+ int level, i, last, run;
int dc_pred_dir;
RLTable *rl;
+ RL_VLC_ELEM *rl_vlc;
const UINT8 *scan_table;
+ int qmul, qadd;
if (s->mb_intra) {
/* DC coef */
@@ -2935,10 +2937,11 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
return DECODING_ACDC_LOST;
}
block[0] = level;
- i = 1;
+ i = 0;
if (!coded)
goto not_coded;
rl = &rl_intra;
+ rl_vlc = rl_intra.rl_vlc[0];
if (s->ac_pred) {
if (dc_pred_dir == 0)
scan_table = ff_alternate_vertical_scan; /* left */
@@ -2947,37 +2950,52 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
} else {
scan_table = zigzag_direct;
}
+ qmul=1;
+ qadd=0;
} else {
- i = 0;
+ i = -1;
if (!coded) {
- s->block_last_index[n] = i - 1;
+ s->block_last_index[n] = i;
return 0;
}
rl = &rl_inter;
+ rl_vlc = rl_inter.rl_vlc[s->qscale];
scan_table = zigzag_direct;
+ qmul = s->qscale << 1;
+ qadd = (s->qscale - 1) | 1;
}
-
+ {
+ OPEN_READER(re, &s->gb);
for(;;) {
- code = get_vlc2(&s->gb, rl->vlc.table, TEX_VLC_BITS, 2);
- if (code < 0)
- return DECODING_AC_LOST;
- if (code == rl->n) {
+ UPDATE_CACHE(re, &s->gb);
+ GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2);
+ if (level==0) {
+ int cache;
+ cache= GET_CACHE(re, &s->gb);
/* escape */
- if (get_bits1(&s->gb) != 0) {
- if (get_bits1(&s->gb) != 0) {
+ if (cache&0x80000000) {
+ if (cache&0x40000000) {
/* third escape */
- last = get_bits1(&s->gb);
- run = get_bits(&s->gb, 6);
- if(get_bits1(&s->gb)==0){
+ SKIP_CACHE(re, &s->gb, 2);
+ last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1);
+ 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");
return DECODING_AC_LOST;
- }
- level = get_bits(&s->gb, 12);
- level = (level << 20) >> 20; /* sign extend */
- if(get_bits1(&s->gb)==0){
+ }; SKIP_CACHE(re, &s->gb, 1);
+
+ level= SHOW_SBITS(re, &s->gb, 12); SKIP_CACHE(re, &s->gb, 12);
+
+ if(SHOW_UBITS(re, &s->gb, 1)==0){
fprintf(stderr, "2. marker bit missing in 3. esc\n");
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
fprintf(stderr, "|level| overflow in 3. esc\n");
return DECODING_AC_LOST;
@@ -3002,54 +3020,66 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
}
}
#endif
+ if (level>0) level= level * qmul + qadd;
+ else level= level * qmul - qadd;
+
+ i+= run + 1;
+ if(last) i+=192;
} else {
/* second escape */
- code = get_vlc2(&s->gb, rl->vlc.table, TEX_VLC_BITS, 2);
- if (code < 0 || code >= rl->n)
- return DECODING_AC_LOST;
- run = rl->table_run[code];
- level = rl->table_level[code];
- last = code >= rl->last;
- run += rl->max_run[last][level] + 1;
- if (get_bits1(&s->gb))
- level = -level;
+#if MIN_CACHE_BITS < 20
+ LAST_SKIP_BITS(re, &s->gb, 2);
+ UPDATE_CACHE(re, &s->gb);
+#else
+ SKIP_BITS(re, &s->gb, 2);
+#endif
+ GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2);
+ i+= run + rl->max_run[run>>7][level/qmul] +1; //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 {
/* first escape */
- code = get_vlc2(&s->gb, rl->vlc.table, TEX_VLC_BITS, 2);
- if (code < 0 || code >= rl->n)
- return DECODING_AC_LOST;
- run = rl->table_run[code];
- level = rl->table_level[code];
- last = code >= rl->last;
- level += rl->max_level[last][run];
- if (get_bits1(&s->gb))
- level = -level;
+#if MIN_CACHE_BITS < 19
+ LAST_SKIP_BITS(re, &s->gb, 1);
+ UPDATE_CACHE(re, &s->gb);
+#else
+ SKIP_BITS(re, &s->gb, 1);
+#endif
+ GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2);
+ i+= run;
+ 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 {
- run = rl->table_run[code];
- level = rl->table_level[code];
- last = code >= rl->last;
- if (get_bits1(&s->gb))
- level = -level;
+ i+= run;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
}
- i += run;
- if (i >= 64)
- return DECODING_AC_LOST;
- j = scan_table[i];
- block[j] = level;
- i++;
- if (last)
+ if (i > 62){
+ i-= 192;
+ if(i&(~63)){
+ fprintf(stderr, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+ return DECODING_AC_LOST;
+ }
+
+ block[scan_table[i]] = level;
break;
+ }
+
+ block[scan_table[i]] = level;
}
+ CLOSE_READER(re, &s->gb);
+ }
not_coded:
if (s->mb_intra) {
mpeg4_pred_ac(s, block, n, dc_pred_dir);
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;
}
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 2a165766ce..71d571df85 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -1318,7 +1318,7 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
if(s->hurry_up>1) goto the_end;
/* 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[1], 1, dest_y + 8, dct_linesize);
add_dequant_dct(s, block[2], 2, dest_y + dct_offset, dct_linesize);