Mercurial > libavcodec.hg
changeset 2202:8079b177ff5c libavcodec
optional non spec compliant optimizations for mpeg1
author | michael |
---|---|
date | Thu, 02 Sep 2004 15:46:03 +0000 |
parents | ccff80bb955f |
children | edf4787f3baf |
files | mpeg12.c |
diffstat | 1 files changed, 89 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/mpeg12.c Thu Sep 02 15:30:46 2004 +0000 +++ b/mpeg12.c Thu Sep 02 15:46:03 2004 +0000 @@ -64,6 +64,7 @@ static inline int mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n); +static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n); static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, DCTELEM *block, int n); @@ -1382,14 +1383,25 @@ } } } else { - for(i=0;i<6;i++) { - if (cbp & 32) { - if (mpeg1_decode_block_inter(s, s->pblocks[i], i) < 0) - return -1; - } else { - s->block_last_index[i] = -1; + if(s->flags2 & CODEC_FLAG2_FAST){ + for(i=0;i<6;i++) { + if (cbp & 32) { + mpeg1_fast_decode_block_inter(s, s->pblocks[i], i); + } else { + s->block_last_index[i] = -1; + } + cbp+=cbp; } - cbp+=cbp; + }else{ + for(i=0;i<6;i++) { + if (cbp & 32) { + if (mpeg1_decode_block_inter(s, s->pblocks[i], i) < 0) + return -1; + } else { + s->block_last_index[i] = -1; + } + cbp+=cbp; + } } } }else{ @@ -1604,6 +1616,76 @@ return 0; } +static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n) +{ + int level, i, j, run; + RLTable *rl = &rl_mpeg1; + uint8_t * const scantable= s->intra_scantable.permutated; + const int qscale= s->qscale; + + { + int v; + OPEN_READER(re, &s->gb); + i = -1; + /* special case for the first coef. no need to add a second vlc table */ + UPDATE_CACHE(re, &s->gb); + v= SHOW_UBITS(re, &s->gb, 2); + if (v & 2) { + LAST_SKIP_BITS(re, &s->gb, 2); + level= (3*qscale)>>4; + level= (level-1)|1; + if(v&1) + level= -level; + block[0] = level; + i++; + } + + /* now quantify & encode AC coefs */ + for(;;) { + UPDATE_CACHE(re, &s->gb); + GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2); + + if(level == 127){ + break; + } else if(level != 0) { + i += run; + j = scantable[i]; + level= ((level*2+1)*qscale)>>1; + level= (level-1)|1; + level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); + LAST_SKIP_BITS(re, &s->gb, 1); + } else { + /* escape */ + run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6); + UPDATE_CACHE(re, &s->gb); + level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8); + if (level == -128) { + level = SHOW_UBITS(re, &s->gb, 8) - 256; LAST_SKIP_BITS(re, &s->gb, 8); + } else if (level == 0) { + level = SHOW_UBITS(re, &s->gb, 8) ; LAST_SKIP_BITS(re, &s->gb, 8); + } + i += run; + j = scantable[i]; + if(level<0){ + level= -level; + level= ((level*2+1)*qscale)>>1; + level= (level-1)|1; + level= -level; + }else{ + level= ((level*2+1)*qscale)>>1; + level= (level-1)|1; + } + } + + block[j] = level; + } + CLOSE_READER(re, &s->gb); + } + s->block_last_index[n] = i; + return 0; +} + + static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, DCTELEM *block, int n)