changeset 714:fd0e997616fe libavcodec

optimizing mpeg2 decode block stuff
author michaelni
date Tue, 01 Oct 2002 23:11:40 +0000
parents e74a563eb643
children 8b3ccabfce4a
files mpeg12.c
diffstat 1 files changed, 117 insertions(+), 114 deletions(-) [+]
line wrap: on
line diff
--- a/mpeg12.c	Tue Oct 01 19:29:10 2002 +0000
+++ b/mpeg12.c	Tue Oct 01 23:11:40 2002 +0000
@@ -58,10 +58,10 @@
 static inline int mpeg1_decode_block_intra(MpegEncContext *s, 
                               DCTELEM *block, 
                               int n);
-static int mpeg2_decode_block_non_intra(MpegEncContext *s, 
+static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, 
                                         DCTELEM *block, 
                                         int n);
-static int mpeg2_decode_block_intra(MpegEncContext *s, 
+static inline int mpeg2_decode_block_intra(MpegEncContext *s, 
                                     DCTELEM *block, 
                                     int n);
 static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred);
@@ -1117,18 +1117,15 @@
         UPDATE_CACHE(re, &s->gb);
         v= SHOW_UBITS(re, &s->gb, 2);
         if (v & 2) {
-            SKIP_BITS(re, &s->gb, 2);
+            LAST_SKIP_BITS(re, &s->gb, 2);
             level= (3*qscale*quant_matrix[0])>>4;
             level= (level-1)|1;
             if(v&1)
                 level= -level;
-            block[ scantable[0] ] = level;
+            block[0] = level;
             i++;
         }
-        CLOSE_READER(re, &s->gb);
-    }
-    {
-        OPEN_READER(re, &s->gb);    
+
         /* now quantify & encode AC coefs */
         for(;;) {
             UPDATE_CACHE(re, &s->gb);
@@ -1180,110 +1177,114 @@
 
 /* Also does unquantization here, since I will never support mpeg2
    encoding */
-static int mpeg2_decode_block_non_intra(MpegEncContext *s, 
-                                        DCTELEM *block, 
-                                        int n)
+static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, 
+                               DCTELEM *block, 
+                               int n)
 {
     int level, i, j, run;
-    int code;
     RLTable *rl = &rl_mpeg1;
-    const UINT8 *scan_table;
-    const UINT16 *matrix;
+    UINT8 * scantable;
+    const UINT16 *quant_matrix;
+    const int qscale= s->qscale;
     int mismatch;
 
     if (s->alternate_scan)
-        scan_table = s->intra_v_scantable.permutated;
+        scantable = s->intra_v_scantable.permutated;
     else
-        scan_table = s->intra_scantable.permutated;
+        scantable = s->intra_scantable.permutated;
     mismatch = 1;
 
     {
         int v;
         OPEN_READER(re, &s->gb);
-        i = 0;
+        i = -1;
         if (n < 4)
-            matrix = s->inter_matrix;
+            quant_matrix = s->inter_matrix;
         else
-            matrix = s->chroma_inter_matrix;
+            quant_matrix = s->chroma_inter_matrix;
 
         /* 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 = 5 - (v << 1);
-            SKIP_BITS(re, &s->gb, 2);
-            CLOSE_READER(re, &s->gb);
-            goto add_coef;
+            LAST_SKIP_BITS(re, &s->gb, 2);
+            level= (3*qscale*quant_matrix[0])>>5;
+            if(v&1)
+                level= -level;
+            block[0] = level;
+            mismatch ^= 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*quant_matrix[j])>>5;
+                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*quant_matrix[j])>>5;
+                    level= -level;
+                }else{
+                    level= ((level*2+1)*qscale*quant_matrix[j])>>5;
+                }
+            }
+            if (i > 63){
+                fprintf(stderr, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+                return -1;
+            }
+            
+            mismatch ^= level;
+            block[j] = level;
         }
         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){
-            fprintf(stderr, "invalid ac code at %d %d\n", s->mb_x, s->mb_y);
-            return -1;
-        }
-        if (code == 112) {
-            break;
-        } else if (code == 111) {
-            /* escape */
-            run = get_bits(&s->gb, 6);
-            level = get_bits(&s->gb, 12);
-            level= (level + ((-1)<<11)) ^ ((-1)<<11); //sign extension
-        } else {
-            run = rl->table_run[code];
-            level = rl->table_level[code];
-            if (get_bits1(&s->gb))
-                level = -level;
-        }
-        i += run;
-        if (i >= 64){
-            fprintf(stderr, "run too long at %d %d\n", s->mb_x, s->mb_y);
-            return -1;
-        }
-    add_coef:
-	j = scan_table[i];
-        dprintf("%d: run=%d level=%d\n", n, run, level);
-        /* XXX: optimize */
-        if (level > 0) {
-            level = ((level * 2 + 1) * s->qscale * matrix[j]) >> 5;
-        } else {
-            level = ((-level * 2 + 1) * s->qscale * matrix[j]) >> 5;
-            level = -level;
-        }
-        /* XXX: is it really necessary to saturate since the encoder
-           knows whats going on ? */
-        mismatch ^= level;
-        block[j] = level;
-        i++;
-    }
     block[63] ^= (mismatch & 1);
+    
     s->block_last_index[n] = i;
-
     return 0;
 }
 
-static int mpeg2_decode_block_intra(MpegEncContext *s, 
-                                    DCTELEM *block, 
-                                    int n)
+static inline int mpeg2_decode_block_intra(MpegEncContext *s, 
+                               DCTELEM *block, 
+                               int n)
 {
     int level, dc, diff, i, j, run;
-    int code, component;
+    int component;
     RLTable *rl;
-    const UINT8 *scan_table;
-    const UINT16 *matrix;
+    UINT8 * scantable;
+    const UINT16 *quant_matrix;
+    const int qscale= s->qscale;
     int mismatch;
 
     if (s->alternate_scan)
-        scan_table = s->intra_v_scantable.permutated;
+        scantable = s->intra_v_scantable.permutated;
     else
-        scan_table = s->intra_scantable.permutated;
+        scantable = s->intra_scantable.permutated;
 
     /* DC coef */
-    component = (n <= 3 ? 0 : n - 4 + 1);
+    if (n < 4){
+        quant_matrix = s->intra_matrix;
+        component = 0; 
+    }else{
+        quant_matrix = s->chroma_intra_matrix;
+        component = n - 3;
+    }
     diff = decode_dc(s, component);
     if (diff >= 0xffff)
         return -1;
@@ -1293,51 +1294,53 @@
     block[0] = dc << (3 - s->intra_dc_precision);
     dprintf("dc=%d\n", block[0]);
     mismatch = block[0] ^ 1;
-    i = 1;
+    i = 0;
     if (s->intra_vlc_format)
         rl = &rl_mpeg2;
     else
         rl = &rl_mpeg1;
-    if (n < 4) 
-        matrix = s->intra_matrix;
-    else
-        matrix = s->chroma_intra_matrix;
 
-    /* now quantify & encode AC coefs */
-    for(;;) {
-        code = get_vlc2(&s->gb, rl->vlc.table, TEX_VLC_BITS, 2);
-        if (code < 0){
-            fprintf(stderr, "invalid ac code at %d %d\n", s->mb_x, s->mb_y);
-            return -1;
+    {
+        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])>>4;
+                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*qscale*quant_matrix[j])>>4;
+                    level= -level;
+                }else{
+                    level= (level*qscale*quant_matrix[j])>>4;
+                }
+            }
+            if (i > 63){
+                fprintf(stderr, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+                return -1;
+            }
+            
+            mismatch^= level;
+            block[j] = level;
         }
-        if (code == 112) {
-            break;
-        } else if (code == 111) {
-            /* escape */
-            run = get_bits(&s->gb, 6);
-            level = get_bits(&s->gb, 12);
-            level= (level + ((-1)<<11)) ^ ((-1)<<11); //sign extension
-        } else {
-            run = rl->table_run[code];
-            level = rl->table_level[code];
-            if (get_bits1(&s->gb))
-                level = -level;
-        }
-        i += run;
-        if (i >= 64){
-            fprintf(stderr, "run too long at %d %d\n", s->mb_x, s->mb_y);
-            return -1;
-        }
-	j = scan_table[i];
-        dprintf("%d: run=%d level=%d\n", n, run, level);
-        level = (level * s->qscale * matrix[j]) / 16;
-        /* XXX: is it really necessary to saturate since the encoder
-           knows whats going on ? */
-        mismatch ^= level;
-        block[j] = level;
-        i++;
+        CLOSE_READER(re, &s->gb);
     }
-    block[63] ^= (mismatch & 1);
+    block[63]^= mismatch&1;
+    
     s->block_last_index[n] = i;
     return 0;
 }