summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2002-09-30 16:14:14 +0000
committerMichael Niedermayer <michaelni@gmx.at>2002-09-30 16:14:14 +0000
commita02017367b4a733b7ac208ebc7d46ef6db9947ed (patch)
treee4e5b6c401253fb104936c65d7d703e9480ca2ed
parent8e1652dc9dac6cd6ccb30cac1b646f3af96c3ca9 (diff)
optimizing mpeg1_decode_block()
Originally committed as revision 985 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavcodec/mpeg12.c219
-rw-r--r--libavcodec/mpegvideo.c34
2 files changed, 175 insertions, 78 deletions
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index 41f942cdd8..b119b91fe2 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -52,7 +52,10 @@ static void mpeg1_encode_block(MpegEncContext *s,
int component);
static void mpeg1_encode_motion(MpegEncContext *s, int val);
static void mpeg1_skip_picture(MpegEncContext *s, int pict_num);
-static int mpeg1_decode_block(MpegEncContext *s,
+static inline int mpeg1_decode_block_inter(MpegEncContext *s,
+ DCTELEM *block,
+ int n);
+static inline int mpeg1_decode_block_intra(MpegEncContext *s,
DCTELEM *block,
int n);
static int mpeg2_decode_block_non_intra(MpegEncContext *s,
@@ -92,8 +95,8 @@ static void init_2d_vlc_rl(RLTable *rl)
run= 65;
level= 0;
}else if(code==rl->n+1){ //eob
- run= 192;
- level= 1;
+ run= 0;
+ level= 127;
}else{
run= rl->table_run [code] + 1;
level= rl->table_level[code];
@@ -932,30 +935,35 @@ static int mpeg_decode_mb(MpegEncContext *s,
if (s->mpeg2) {
if (s->mb_intra) {
for(i=0;i<6;i++) {
- if (cbp & (1 << (5 - i))) {
- if (mpeg2_decode_block_intra(s, block[i], i) < 0)
- return -1;
- } else {
- s->block_last_index[i] = -1;
- }
+ if (mpeg2_decode_block_intra(s, block[i], i) < 0)
+ return -1;
}
} else {
for(i=0;i<6;i++) {
- if (cbp & (1 << (5 - i))) {
+ if (cbp & 32) {
if (mpeg2_decode_block_non_intra(s, block[i], i) < 0)
return -1;
} else {
s->block_last_index[i] = -1;
}
+ cbp+=cbp;
}
}
} else {
- for(i=0;i<6;i++) {
- if (cbp & (1 << (5 - i))) {
- if (mpeg1_decode_block(s, block[i], i) < 0)
+ if (s->mb_intra) {
+ for(i=0;i<6;i++) {
+ if (mpeg1_decode_block_intra(s, block[i], i) < 0)
return -1;
- } else {
- s->block_last_index[i] = -1;
+ }
+ }else{
+ for(i=0;i<6;i++) {
+ if (cbp & 32) {
+ if (mpeg1_decode_block_inter(s, block[i], i) < 0)
+ return -1;
+ } else {
+ s->block_last_index[i] = -1;
+ }
+ cbp+=cbp;
}
}
}
@@ -1018,78 +1026,155 @@ static inline int decode_dc(MpegEncContext *s, int component)
return diff;
}
-static int mpeg1_decode_block(MpegEncContext *s,
+static inline int mpeg1_decode_block_intra(MpegEncContext *s,
DCTELEM *block,
int n)
{
int level, dc, diff, i, j, run;
- int code, component;
+ int component;
RLTable *rl = &rl_mpeg1;
UINT8 * const scantable= s->intra_scantable.permutated;
+ const UINT16 *quant_matrix= s->intra_matrix;
+ const int qscale= s->qscale;
- if (s->mb_intra) {
- /* DC coef */
- component = (n <= 3 ? 0 : n - 4 + 1);
- diff = decode_dc(s, component);
- if (diff >= 0xffff)
- return -1;
- dc = s->last_dc[component];
- dc += diff;
- s->last_dc[component] = dc;
- block[0] = dc;
- dprintf("dc=%d diff=%d\n", dc, diff);
- i = 1;
- } else {
+ /* DC coef */
+ component = (n <= 3 ? 0 : n - 4 + 1);
+ diff = decode_dc(s, component);
+ if (diff >= 0xffff)
+ return -1;
+ dc = s->last_dc[component];
+ dc += diff;
+ s->last_dc[component] = dc;
+ block[0] = dc<<3;
+ dprintf("dc=%d diff=%d\n", dc, diff);
+ i = 0;
+ {
+ OPEN_READER(re, &s->gb);
+ /* 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*qscale*quant_matrix[j])>>3;
+ 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*qscale*quant_matrix[j])>>3;
+ level= (level-1)|1;
+ level= -level;
+ }else{
+ level= (level*qscale*quant_matrix[j])>>3;
+ level= (level-1)|1;
+ }
+ }
+ if (i > 63){
+ fprintf(stderr, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+
+ block[j] = level;
+ }
+ CLOSE_READER(re, &s->gb);
+ }
+ s->block_last_index[n] = i;
+ return 0;
+}
+
+static inline int mpeg1_decode_block_inter(MpegEncContext *s,
+ DCTELEM *block,
+ int n)
+{
+ int level, i, j, run;
+ RLTable *rl = &rl_mpeg1;
+ UINT8 * const scantable= s->intra_scantable.permutated;
+ const UINT16 *quant_matrix= s->inter_matrix;
+ const int qscale= s->qscale;
+
+ {
int v;
OPEN_READER(re, &s->gb);
- i = 0;
+ 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) {
- run = 0;
- level = 1 - ((v & 1) << 1);
SKIP_BITS(re, &s->gb, 2);
- CLOSE_READER(re, &s->gb);
- goto add_coef;
+ level= (3*qscale*quant_matrix[0])>>4;
+ level= (level-1)|1;
+ if(v&1)
+ level= -level;
+ block[ scantable[0] ] = level;
+ i++;
}
CLOSE_READER(re, &s->gb);
}
-
- /* now quantify & encode AC coefs */
- for(;;) {
- code = get_vlc2(&s->gb, rl->vlc.table, TEX_VLC_BITS, 2);
- if (code < 0) {
- return -1;
- }
- if (code == 112) {
- break;
- } else if (code == 111) {
- /* escape */
- run = get_bits(&s->gb, 6);
- level = get_bits(&s->gb, 8);
- level= (level + ((-1)<<7)) ^ ((-1)<<7); //sign extension
- if (level == -128) {
- level = get_bits(&s->gb, 8) - 256;
- } else if (level == 0) {
- level = get_bits(&s->gb, 8);
+ {
+ OPEN_READER(re, &s->gb);
+ /* 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*quant_matrix[j])>>4;
+ 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*quant_matrix[j])>>4;
+ level= (level-1)|1;
+ level= -level;
+ }else{
+ level= ((level*2+1)*qscale*quant_matrix[j])>>4;
+ level= (level-1)|1;
+ }
}
- } else {
- run = rl->table_run[code];
- level = rl->table_level[code];
- if (get_bits1(&s->gb))
- level = -level;
+ if (i > 63){
+ fprintf(stderr, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+
+ block[j] = level;
}
- i += run;
- if (i >= 64)
- return -1;
- add_coef:
- dprintf("%d: run=%d level=%d\n", n, run, level);
- j = scantable[i];
- block[j] = level;
- i++;
+ CLOSE_READER(re, &s->gb);
}
- s->block_last_index[n] = i-1;
+ s->block_last_index[n] = i;
return 0;
}
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 1134774b6c..5c487a1ef2 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -1517,8 +1517,7 @@ static inline void MPV_motion(MpegEncContext *s,
static inline void put_dct(MpegEncContext *s,
DCTELEM *block, int i, UINT8 *dest, int line_size)
{
- if (!s->mpeg2)
- s->dct_unquantize(s, block, i, s->qscale);
+ s->dct_unquantize(s, block, i, s->qscale);
s->idct_put (dest, line_size, block);
}
@@ -1723,7 +1722,8 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
if(s->hurry_up>1) goto the_end;
/* add dct residue */
- if(s->encoding || !(s->mpeg2 || s->h263_msmpeg4 || (s->codec_id==CODEC_ID_MPEG4 && !s->mpeg_quant))){
+ if(s->encoding || !( s->mpeg2 || s->h263_msmpeg4 || s->codec_id==CODEC_ID_MPEG1VIDEO
+ || (s->codec_id==CODEC_ID_MPEG4 && !s->mpeg_quant))){
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[2], 2, dest_y + dct_offset, dct_linesize);
@@ -1746,14 +1746,26 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
}
} else {
/* dct only in intra block */
- put_dct(s, block[0], 0, dest_y, dct_linesize);
- put_dct(s, block[1], 1, dest_y + 8, dct_linesize);
- put_dct(s, block[2], 2, dest_y + dct_offset, dct_linesize);
- put_dct(s, block[3], 3, dest_y + dct_offset + 8, dct_linesize);
-
- if(!(s->flags&CODEC_FLAG_GRAY)){
- put_dct(s, block[4], 4, dest_cb, s->uvlinesize);
- put_dct(s, block[5], 5, dest_cr, s->uvlinesize);
+ if(s->encoding || !(s->mpeg2 || s->codec_id==CODEC_ID_MPEG1VIDEO)){
+ put_dct(s, block[0], 0, dest_y, dct_linesize);
+ put_dct(s, block[1], 1, dest_y + 8, dct_linesize);
+ put_dct(s, block[2], 2, dest_y + dct_offset, dct_linesize);
+ put_dct(s, block[3], 3, dest_y + dct_offset + 8, dct_linesize);
+
+ if(!(s->flags&CODEC_FLAG_GRAY)){
+ put_dct(s, block[4], 4, dest_cb, s->uvlinesize);
+ put_dct(s, block[5], 5, dest_cr, s->uvlinesize);
+ }
+ }else{
+ s->idct_put(dest_y , dct_linesize, block[0]);
+ s->idct_put(dest_y + 8, dct_linesize, block[1]);
+ s->idct_put(dest_y + dct_offset , dct_linesize, block[2]);
+ s->idct_put(dest_y + dct_offset + 8, dct_linesize, block[3]);
+
+ if(!(s->flags&CODEC_FLAG_GRAY)){
+ s->idct_put(dest_cb, s->uvlinesize, block[4]);
+ s->idct_put(dest_cr, s->uvlinesize, block[5]);
+ }
}
}
}