VP8: unroll MB mode decoding tree
authorJason Garrett-Glaser <darkshikari@gmail.com>
Tue, 3 Aug 2010 10:24:28 +0000 (10:24 +0000)
committerJason Garrett-Glaser <darkshikari@gmail.com>
Tue, 3 Aug 2010 10:24:28 +0000 (10:24 +0000)
~50% faster MB mode decoding, plus eliminate a costly switch.

Originally committed as revision 24679 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/vp8.c
libavcodec/vp8data.h

index aa9a69c8240d4bee96a77771f5350884edfd2ea9..af18b0d24103dc2ceea2d33f3b4c8a9f57aa9612 100644 (file)
@@ -745,7 +745,6 @@ void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, uint8_
     } else if (vp56_rac_get_prob_branchy(c, s->prob->intra)) {
         VP56mv near[2], best;
         uint8_t cnt[4] = { 0 };
-        uint8_t p[4];
 
         // inter MB, 16.2
         if (vp56_rac_get_prob_branchy(c, s->prob->last))
@@ -757,30 +756,30 @@ void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, uint8_
 
         // motion vectors, 16.3
         find_near_mvs(s, mb, mb_x, mb_y, near, &best, cnt);
-        p[0] = vp8_mode_contexts[cnt[0]][0];
-        p[1] = vp8_mode_contexts[cnt[1]][1];
-        p[2] = vp8_mode_contexts[cnt[2]][2];
-        p[3] = vp8_mode_contexts[cnt[3]][3];
-        mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_mvinter, p);
-        switch (mb->mode) {
-        case VP8_MVMODE_SPLIT:
-            clamp_mv(s, &mb->mv, &mb->mv, mb_x, mb_y);
-            mb->mv = mb->bmv[decode_splitmvs(s, c, mb) - 1];
-            break;
-        case VP8_MVMODE_ZERO:
+        if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[0]][0])) {
+            if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[1]][1])) {
+                if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[2]][2])) {
+                    if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[3]][3])) {
+                        mb->mode = VP8_MVMODE_SPLIT;
+                        clamp_mv(s, &mb->mv, &mb->mv, mb_x, mb_y);
+                        mb->mv = mb->bmv[decode_splitmvs(s, c, mb) - 1];
+                    } else {
+                        mb->mode = VP8_MVMODE_NEW;
+                        clamp_mv(s, &mb->mv, &mb->mv, mb_x, mb_y);
+                        mb->mv.y += + read_mv_component(c, s->prob->mvc[0]);
+                        mb->mv.x += + read_mv_component(c, s->prob->mvc[1]);
+                    }
+                } else {
+                    mb->mode = VP8_MVMODE_NEAR;
+                    clamp_mv(s, &mb->mv, &near[1], mb_x, mb_y);
+                }
+            } else {
+                mb->mode = VP8_MVMODE_NEAREST;
+                clamp_mv(s, &mb->mv, &near[0], mb_x, mb_y);
+            }
+        } else {
+            mb->mode = VP8_MVMODE_ZERO;
             AV_ZERO32(&mb->mv);
-            break;
-        case VP8_MVMODE_NEAREST:
-            clamp_mv(s, &mb->mv, &near[0], mb_x, mb_y);
-            break;
-        case VP8_MVMODE_NEAR:
-            clamp_mv(s, &mb->mv, &near[1], mb_x, mb_y);
-            break;
-        case VP8_MVMODE_NEW:
-            clamp_mv(s, &mb->mv, &mb->mv, mb_x, mb_y);
-            mb->mv.y += + read_mv_component(c, s->prob->mvc[0]);
-            mb->mv.x += + read_mv_component(c, s->prob->mvc[1]);
-            break;
         }
         if (mb->mode != VP8_MVMODE_SPLIT) {
             mb->partitioning = VP8_SPLITMVMODE_NONE;
index 28cc0b340307c71d7c2db3e35b32de4e6c61fafa..d3a47fcc65db2032c0080707db8d3fbc6ddb6ef3 100644 (file)
@@ -103,13 +103,6 @@ static const int vp8_mode_contexts[6][4] = {
     { 234, 188, 128,  28 },
 };
 
-static const int8_t vp8_pred16x16_tree_mvinter[4][2] = {
-    { -VP8_MVMODE_ZERO,      1 },           // '0'
-     { -VP8_MVMODE_NEAREST,  2 },           // '10'
-      { -VP8_MVMODE_NEAR,    3 },           // '110'
-       { -VP8_MVMODE_NEW, -VP8_MVMODE_SPLIT } // '1110', '1111'
-};
-
 static const uint8_t vp8_mbsplits[5][16] = {
     {  0,  0,  0,  0,  0,  0,  0,  0,
        1,  1,  1,  1,  1,  1,  1,  1  },