1
mirror of https://git.videolan.org/git/ffmpeg.git synced 2024-09-06 08:08:58 +02:00

optional non spec compliant optimizations for mpeg1

Originally committed as revision 3430 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Michael Niedermayer 2004-09-02 15:46:03 +00:00
parent 6fc5b059b8
commit 628b210f40

View File

@ -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)