mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-24 13:56:33 +02:00
rl decoding optimization
Originally committed as revision 755 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
e3e98d3c23
commit
c03a717274
@ -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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
} 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,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#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])
|
|||||||
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user