changeset 549:218eb765c987 libavcodec

rl decoding optimization
author michaelni
date Sat, 13 Jul 2002 17:30:43 +0000
parents 3f05be811b5a
children b746a7d75ce6
files h263.c mpegvideo.c
diffstat 2 files changed, 84 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/h263.c	Sat Jul 13 16:29:11 2002 +0000
+++ b/h263.c	Sat Jul 13 17:30:43 2002 +0000
@@ -1704,10 +1704,10 @@
         init_vlc_rl(&rl_inter);
         init_vlc_rl(&rl_intra);
         init_vlc_rl(&rl_intra_aic);
-        init_vlc(&dc_lum, DC_VLC_BITS, 9 /* 13 */,
+        init_vlc(&dc_lum, DC_VLC_BITS, 10 /* 13 */,
                  &DCtab_lum[0][1], 2, 1,
                  &DCtab_lum[0][0], 2, 1);
-        init_vlc(&dc_chrom, DC_VLC_BITS, 9 /* 13 */,
+        init_vlc(&dc_chrom, DC_VLC_BITS, 10 /* 13 */,
                  &DCtab_chrom[0][1], 2, 1,
                  &DCtab_chrom[0][0], 2, 1);
         init_vlc(&sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15,
@@ -2917,10 +2917,12 @@
 static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
                               int n, int coded)
 {
-    int code, level, i, j, last, run;
+    int level, i, last, run;
     int dc_pred_dir;
     RLTable *rl;
+    RL_VLC_ELEM *rl_vlc;
     const UINT8 *scan_table;
+    int qmul, qadd;
 
     if (s->mb_intra) {
 	/* DC coef */
@@ -2935,10 +2937,11 @@
                 return DECODING_ACDC_LOST;
         }
         block[0] = level;
-        i = 1;
+        i = 0;
         if (!coded) 
             goto not_coded;
         rl = &rl_intra;
+        rl_vlc = rl_intra.rl_vlc[0];
         if (s->ac_pred) {
             if (dc_pred_dir == 0) 
                 scan_table = ff_alternate_vertical_scan; /* left */
@@ -2947,37 +2950,52 @@
         } else {
             scan_table = zigzag_direct;
         }
+        qmul=1;
+        qadd=0;
     } else {
-	i = 0;
+        i = -1;
         if (!coded) {
-            s->block_last_index[n] = i - 1;
+            s->block_last_index[n] = i;
             return 0;
         }
         rl = &rl_inter;
+        rl_vlc = rl_inter.rl_vlc[s->qscale];
         scan_table = zigzag_direct;
+        qmul = s->qscale << 1;
+        qadd = (s->qscale - 1) | 1;
     }
-
+  {
+    OPEN_READER(re, &s->gb);
     for(;;) {
-        code = get_vlc2(&s->gb, rl->vlc.table, TEX_VLC_BITS, 2);
-        if (code < 0)
-            return DECODING_AC_LOST;
-        if (code == rl->n) {
+        UPDATE_CACHE(re, &s->gb);
+        GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2);
+        if (level==0) {
+            int cache;
+            cache= GET_CACHE(re, &s->gb);
             /* escape */
-            if (get_bits1(&s->gb) != 0) {
-                if (get_bits1(&s->gb) != 0) {
+            if (cache&0x80000000) {
+                if (cache&0x40000000) {
                     /* third escape */
-                    last = get_bits1(&s->gb);
-                    run = get_bits(&s->gb, 6);
-                    if(get_bits1(&s->gb)==0){
+                    SKIP_CACHE(re, &s->gb, 2);
+                    last=  SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1);
+                    run=   SHOW_UBITS(re, &s->gb, 6); LAST_SKIP_CACHE(re, &s->gb, 6);
+                    SKIP_COUNTER(re, &s->gb, 2+1+6);
+                    UPDATE_CACHE(re, &s->gb);
+
+                    if(SHOW_UBITS(re, &s->gb, 1)==0){
                         fprintf(stderr, "1. marker bit missing in 3. esc\n");
                         return DECODING_AC_LOST;
-                    }
-                    level = get_bits(&s->gb, 12);
-                    level = (level << 20) >> 20; /* sign extend */
-                    if(get_bits1(&s->gb)==0){
+                    }; SKIP_CACHE(re, &s->gb, 1);
+                    
+                    level= SHOW_SBITS(re, &s->gb, 12); SKIP_CACHE(re, &s->gb, 12);
+ 
+                    if(SHOW_UBITS(re, &s->gb, 1)==0){
                         fprintf(stderr, "2. marker bit missing in 3. esc\n");
                         return DECODING_AC_LOST;
-                    }
+                    }; LAST_SKIP_CACHE(re, &s->gb, 1);
+                    
+                    SKIP_COUNTER(re, &s->gb, 1+12+1);
+                    
                     if(level>512 || level<-512){ //FIXME check that QP=1 is ok with this too
                         fprintf(stderr, "|level| overflow in 3. esc\n");
                         return DECODING_AC_LOST;
@@ -3002,54 +3020,66 @@
                         }
                     }
 #endif
+		    if (level>0) level= level * qmul + qadd;
+                    else         level= level * qmul - qadd;
+
+                    i+= run + 1;
+                    if(last) i+=192;
                 } else {
                     /* second escape */
-                    code = get_vlc2(&s->gb, rl->vlc.table, TEX_VLC_BITS, 2);
-                    if (code < 0 || code >= rl->n)
-                        return DECODING_AC_LOST;
-                    run = rl->table_run[code];
-                    level = rl->table_level[code];
-                    last = code >= rl->last;
-                    run += rl->max_run[last][level] + 1;
-                    if (get_bits1(&s->gb))
-                        level = -level;
+#if MIN_CACHE_BITS < 20
+                    LAST_SKIP_BITS(re, &s->gb, 2);
+                    UPDATE_CACHE(re, &s->gb);
+#else
+                    SKIP_BITS(re, &s->gb, 2);
+#endif
+                    GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2);
+                    i+= run + rl->max_run[run>>7][level/qmul] +1; //FIXME opt indexing
+                    level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+                    LAST_SKIP_BITS(re, &s->gb, 1);
                 }
             } else {
                 /* first escape */
-                code = get_vlc2(&s->gb, rl->vlc.table, TEX_VLC_BITS, 2);
-                if (code < 0 || code >= rl->n)
-                    return DECODING_AC_LOST;
-                run = rl->table_run[code];
-                level = rl->table_level[code];
-                last = code >= rl->last;
-                level += rl->max_level[last][run];
-                if (get_bits1(&s->gb))
-                    level = -level;
+#if MIN_CACHE_BITS < 19
+                LAST_SKIP_BITS(re, &s->gb, 1);
+                UPDATE_CACHE(re, &s->gb);
+#else
+                SKIP_BITS(re, &s->gb, 1);
+#endif
+                GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2);
+                i+= run;
+                level = level + rl->max_level[run>>7][(run-1)&63] * qmul;//FIXME opt indexing
+                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+                LAST_SKIP_BITS(re, &s->gb, 1);
             }
         } else {
-            run = rl->table_run[code];
-            level = rl->table_level[code];
-            last = code >= rl->last;
-            if (get_bits1(&s->gb))
-                level = -level;
+            i+= run;
+            level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+            LAST_SKIP_BITS(re, &s->gb, 1);
         }
-        i += run;
-        if (i >= 64)
-            return DECODING_AC_LOST;
-	j = scan_table[i];
-        block[j] = level;
-        i++;
-        if (last)
+        if (i > 62){
+            i-= 192;
+            if(i&(~63)){
+                fprintf(stderr, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+                return DECODING_AC_LOST;
+            }
+
+            block[scan_table[i]] = level;
             break;
+        }
+
+        block[scan_table[i]] = level;
     }
+    CLOSE_READER(re, &s->gb);
+  }
  not_coded:
     if (s->mb_intra) {
         mpeg4_pred_ac(s, block, n, dc_pred_dir);
         if (s->ac_pred) {
-            i = 64; /* XXX: not optimal */
+            i = 63; /* XXX: not optimal */
         }
     }
-    s->block_last_index[n] = i - 1;
+    s->block_last_index[n] = i;
     return 0;
 }
 
--- a/mpegvideo.c	Sat Jul 13 16:29:11 2002 +0000
+++ b/mpegvideo.c	Sat Jul 13 17:30:43 2002 +0000
@@ -1318,7 +1318,7 @@
             if(s->hurry_up>1) goto the_end;
 
             /* add dct residue */
-            if(!s->mpeg2 && (s->encoding || (!s->h263_msmpeg4))){
+            if(s->encoding || !(s->mpeg2 || s->h263_msmpeg4 || s->codec_id==CODEC_ID_MPEG4)){
                 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);