summaryrefslogtreecommitdiff
path: root/libavcodec/mpeg12.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2004-09-02 15:46:03 +0000
committerMichael Niedermayer <michaelni@gmx.at>2004-09-02 15:46:03 +0000
commit628b210f407ded9252defa21268846872381eb8b (patch)
treeabe75695c6d3981f24ea4fc51f789f4774059191 /libavcodec/mpeg12.c
parent6fc5b059b84d93feb4749eb01318b2349b7e795b (diff)
optional non spec compliant optimizations for mpeg1
Originally committed as revision 3430 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/mpeg12.c')
-rw-r--r--libavcodec/mpeg12.c96
1 files changed, 89 insertions, 7 deletions
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index c31efad402..04c559c710 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -64,6 +64,7 @@ static inline int mpeg1_decode_block_inter(MpegEncContext *s,
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 @@ static int mpeg_decode_mb(MpegEncContext *s,
}
}
} 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;
+ }
+ }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;
}
- cbp+=cbp;
}
}
}else{
@@ -1604,6 +1616,76 @@ static inline int mpeg1_decode_block_inter(MpegEncContext *s,
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)