diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2004-09-02 15:30:46 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2004-09-02 15:30:46 +0000 |
commit | 6fc5b059b84d93feb4749eb01318b2349b7e795b (patch) | |
tree | 402e6b54f1dad928b7b020bf7b868e06438c4ef1 /libavcodec | |
parent | bf0669aa8712842af354c99d572503f0fc66baaa (diff) | |
download | ffmpeg-6fc5b059b84d93feb4749eb01318b2349b7e795b.tar.gz |
optional non spec compliant optimizations
Originally committed as revision 3429 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/avcodec.h | 2 | ||||
-rw-r--r-- | libavcodec/mpeg12.c | 93 |
2 files changed, 84 insertions, 11 deletions
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index e2da0f85a2..76bc946f3a 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -283,6 +283,8 @@ extern int motion_estimation_method; #define CODEC_FLAG_INTERLACED_ME 0x20000000 ///< interlaced motion estimation #define CODEC_FLAG_SVCD_SCAN_OFFSET 0x40000000 ///< will reserve space for SVCD scan offset user data #define CODEC_FLAG_CLOSED_GOP 0x80000000 +#define CODEC_FLAG2_FAST 0x00000001 ///< allow non spec compliant speedup tricks + /* Unsupported options : * Syntax Arithmetic coding (SAC) * Reference Picture Selection diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 1c8a6e2bfa..c31efad402 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -70,6 +70,7 @@ static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, static inline int mpeg2_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n); +static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, DCTELEM *block, int n); static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred); static void exchange_uv(MpegEncContext *s); @@ -1358,16 +1359,27 @@ static int mpeg_decode_mb(MpegEncContext *s, #endif if (s->codec_id == CODEC_ID_MPEG2VIDEO) { - cbp<<= 12-mb_block_count; - - for(i=0;i<mb_block_count;i++) { - if ( cbp & (1<<11) ) { - if (mpeg2_decode_block_non_intra(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) { + mpeg2_fast_decode_block_non_intra(s, s->pblocks[i], i); + } else { + s->block_last_index[i] = -1; + } + cbp+=cbp; + } + }else{ + cbp<<= 12-mb_block_count; + + for(i=0;i<mb_block_count;i++) { + if ( cbp & (1<<11) ) { + if (mpeg2_decode_block_non_intra(s, s->pblocks[i], i) < 0) + return -1; + } else { + s->block_last_index[i] = -1; + } + cbp+=cbp; } - cbp+=cbp; } } else { for(i=0;i<6;i++) { @@ -1592,8 +1604,6 @@ static inline int mpeg1_decode_block_inter(MpegEncContext *s, return 0; } -/* Also does unquantization here, since I will never support mpeg2 - encoding */ static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, DCTELEM *block, int n) @@ -1673,6 +1683,67 @@ static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, return 0; } +static inline int mpeg2_fast_decode_block_non_intra(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)>>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 ^ 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, 12); SKIP_BITS(re, &s->gb, 12); + + i += run; + j = scantable[i]; + if(level<0){ + level= ((-level*2+1)*qscale)>>1; + level= -level; + }else{ + level= ((level*2+1)*qscale)>>1; + } + } + + block[j] = level; + } + CLOSE_READER(re, &s->gb); + s->block_last_index[n] = i; + return 0; +} + + static inline int mpeg2_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n) |