Using treed_read/treed_write functions for segment ids.
authorDmitry Kovalev <dkovalev@google.com>
Tue, 30 Apr 2013 21:06:49 +0000 (14:06 -0700)
committerDmitry Kovalev <dkovalev@google.com>
Tue, 30 Apr 2013 21:06:49 +0000 (14:06 -0700)
Changing the order of probabilities inside mb_segment_tree_probs in order
to use treed_read/treed_write function instead of custom code.

Change-Id: I843487d5057913b9358db73da270893eefecc6c8

vp9/common/vp9_seg_common.c
vp9/common/vp9_seg_common.h
vp9/decoder/vp9_decodemv.c
vp9/encoder/vp9_bitstream.c
vp9/encoder/vp9_segmentation.c

index 9ed3e2d..02b7053 100644 (file)
@@ -107,4 +107,10 @@ void vp9_implicit_segment_map_update(VP9_COMMON * cm) {
 }
 #endif
 
+const vp9_tree_index vp9_segment_tree[14] = {
+  2,  4,  6,  8, 10, 12,
+  0, -1, -2, -3, -4, -5, -6, -7
+};
+
+
 // TBD? Functions to read and write segment data with range / validity checking
index 4550dd1..53d22a3 100644 (file)
@@ -59,5 +59,8 @@ int vp9_check_segref(const MACROBLOCKD *xd,
 void vp9_implicit_segment_map_update(VP9_COMMON * cm);
 #endif
 
+
+extern const vp9_tree_index vp9_segment_tree[14];
+
 #endif  // VP9_COMMON_VP9_SEG_COMMON_H_
 
index c51d0b2..3edd523 100644 (file)
@@ -74,23 +74,7 @@ static MB_PREDICTION_MODE read_uv_mode(vp9_reader *r, const vp9_prob *p) {
 }
 
 static int read_mb_segid(vp9_reader *r, MACROBLOCKD *xd) {
-  const vp9_prob *const p = xd->mb_segment_tree_probs;
-  int ret_val;
-
-  if (vp9_read(r, p[0])) {
-    if (vp9_read(r, p[4])) {
-      ret_val = 6 + vp9_read(r, p[6]);
-    } else {
-      ret_val = 4 + vp9_read(r, p[5]);
-    }
-  } else {
-    if (vp9_read(r, p[1])) {
-      ret_val = 2 + vp9_read(r, p[3]);
-    } else {
-      ret_val = vp9_read(r, p[2]);
-    }
-  }
-  return ret_val;
+  return treed_read(r, vp9_segment_tree, xd->mb_segment_tree_probs);
 }
 
 static void set_segment_id(VP9_COMMON *cm, MB_MODE_INFO *mbmi,
index b57ddbe..086774b 100644 (file)
@@ -529,60 +529,9 @@ static void write_nmv(VP9_COMP *cpi, vp9_writer *bc,
 // It should only be called if a segment map update is indicated.
 static void write_mb_segid(vp9_writer *bc,
                            const MB_MODE_INFO *mi, const MACROBLOCKD *xd) {
-  // Encode the MB segment id.
-  int seg_id = mi->segment_id;
-
-  if (xd->segmentation_enabled && xd->update_mb_segmentation_map) {
-    switch (seg_id) {
-      case 0:
-        vp9_write(bc, 0, xd->mb_segment_tree_probs[0]);
-        vp9_write(bc, 0, xd->mb_segment_tree_probs[1]);
-        vp9_write(bc, 0, xd->mb_segment_tree_probs[2]);
-        break;
-      case 1:
-        vp9_write(bc, 0, xd->mb_segment_tree_probs[0]);
-        vp9_write(bc, 0, xd->mb_segment_tree_probs[1]);
-        vp9_write(bc, 1, xd->mb_segment_tree_probs[2]);
-        break;
-      case 2:
-        vp9_write(bc, 0, xd->mb_segment_tree_probs[0]);
-        vp9_write(bc, 1, xd->mb_segment_tree_probs[1]);
-        vp9_write(bc, 0, xd->mb_segment_tree_probs[3]);
-        break;
-      case 3:
-        vp9_write(bc, 0, xd->mb_segment_tree_probs[0]);
-        vp9_write(bc, 1, xd->mb_segment_tree_probs[1]);
-        vp9_write(bc, 1, xd->mb_segment_tree_probs[3]);
-        break;
-      case 4:
-        vp9_write(bc, 1, xd->mb_segment_tree_probs[0]);
-        vp9_write(bc, 0, xd->mb_segment_tree_probs[4]);
-        vp9_write(bc, 0, xd->mb_segment_tree_probs[5]);
-        break;
-      case 5:
-        vp9_write(bc, 1, xd->mb_segment_tree_probs[0]);
-        vp9_write(bc, 0, xd->mb_segment_tree_probs[4]);
-        vp9_write(bc, 1, xd->mb_segment_tree_probs[5]);
-        break;
-      case 6:
-        vp9_write(bc, 1, xd->mb_segment_tree_probs[0]);
-        vp9_write(bc, 1, xd->mb_segment_tree_probs[4]);
-        vp9_write(bc, 0, xd->mb_segment_tree_probs[6]);
-        break;
-      case 7:
-        vp9_write(bc, 1, xd->mb_segment_tree_probs[0]);
-        vp9_write(bc, 1, xd->mb_segment_tree_probs[4]);
-        vp9_write(bc, 1, xd->mb_segment_tree_probs[6]);
-        break;
-
-        // TRAP.. This should not happen
-      default:
-        vp9_write(bc, 0, xd->mb_segment_tree_probs[0]);
-        vp9_write(bc, 0, xd->mb_segment_tree_probs[1]);
-        vp9_write(bc, 0, xd->mb_segment_tree_probs[2]);
-        break;
-    }
-  }
+  if (xd->segmentation_enabled && xd->update_mb_segmentation_map)
+    treed_write(bc, vp9_segment_tree, xd->mb_segment_tree_probs,
+                mi->segment_id, 3);
 }
 
 // This function encodes the reference frame
index 7f792ae..3146653 100644 (file)
@@ -60,61 +60,57 @@ void vp9_set_segment_data(VP9_PTR ptr,
 }
 
 // Based on set of segment counts calculate a probability tree
-static void calc_segtree_probs(MACROBLOCKD *xd,
-                               int *segcounts,
+static void calc_segtree_probs(MACROBLOCKD *xd, int *segcounts,
                                vp9_prob *segment_tree_probs) {
   // Work out probabilities of each segment
-  segment_tree_probs[0] =
-    get_binary_prob(segcounts[0] + segcounts[1] + segcounts[2] + segcounts[3],
-                    segcounts[4] + segcounts[5] + segcounts[6] + segcounts[7]);
-  segment_tree_probs[1] =
-    get_binary_prob(segcounts[0] + segcounts[1], segcounts[2] + segcounts[3]);
-  segment_tree_probs[2] = get_binary_prob(segcounts[0], segcounts[1]);
-  segment_tree_probs[3] = get_binary_prob(segcounts[2], segcounts[3]);
-  segment_tree_probs[4] =
-    get_binary_prob(segcounts[4] + segcounts[5], segcounts[6] + segcounts[7]);
+  const int c01 = segcounts[0] + segcounts[1];
+  const int c23 = segcounts[2] + segcounts[3];
+  const int c45 = segcounts[4] + segcounts[5];
+  const int c67 = segcounts[6] + segcounts[7];
+
+  segment_tree_probs[0] = get_binary_prob(c01 + c23, c45 + c67);
+  segment_tree_probs[1] = get_binary_prob(c01, c23);
+  segment_tree_probs[2] = get_binary_prob(c45, c67);
+  segment_tree_probs[3] = get_binary_prob(segcounts[0], segcounts[1]);
+  segment_tree_probs[4] = get_binary_prob(segcounts[2], segcounts[3]);
   segment_tree_probs[5] = get_binary_prob(segcounts[4], segcounts[5]);
   segment_tree_probs[6] = get_binary_prob(segcounts[6], segcounts[7]);
 }
 
 // Based on set of segment counts and probabilities calculate a cost estimate
-static int cost_segmap(MACROBLOCKD *xd,
-                       int *segcounts,
-                       vp9_prob *probs) {
-  int cost;
-  int count1, count2;
+static int cost_segmap(MACROBLOCKD *xd, int *segcounts, vp9_prob *probs) {
+  const int c01 = segcounts[0] + segcounts[1];
+  const int c23 = segcounts[2] + segcounts[3];
+  const int c45 = segcounts[4] + segcounts[5];
+  const int c67 = segcounts[6] + segcounts[7];
+  const int c0123 = c01 + c23;
+  const int c4567 = c45 + c67;
 
   // Cost the top node of the tree
-  count1 = segcounts[0] + segcounts[1] + segcounts[2] + segcounts[3];
-  count2 = segcounts[3] + segcounts[4] + segcounts[5] + segcounts[6];
-  cost = count1 * vp9_cost_zero(probs[0]) +
-         count2 * vp9_cost_one(probs[0]);
+  int cost = c0123 * vp9_cost_zero(probs[0]) +
+             c4567 * vp9_cost_one(probs[0]);
 
   // Cost subsequent levels
-  if (count1 > 0) {
-    count1 = segcounts[0] + segcounts[1];
-    count2 = segcounts[2] + segcounts[3];
-    cost += count1 * vp9_cost_zero(probs[1]) +
-            count2 * vp9_cost_one(probs[1]);
-
-    if (count1 > 0)
-      cost += segcounts[0] * vp9_cost_zero(probs[2]) +
-              segcounts[1] * vp9_cost_one(probs[2]);
-    if (count2 > 0)
-      cost += segcounts[2] * vp9_cost_zero(probs[3]) +
-              segcounts[3] * vp9_cost_one(probs[3]);
+  if (c0123 > 0) {
+    cost += c01 * vp9_cost_zero(probs[1]) +
+            c23 * vp9_cost_one(probs[1]);
+
+    if (c01 > 0)
+      cost += segcounts[0] * vp9_cost_zero(probs[3]) +
+              segcounts[1] * vp9_cost_one(probs[3]);
+    if (c23 > 0)
+      cost += segcounts[2] * vp9_cost_zero(probs[4]) +
+              segcounts[3] * vp9_cost_one(probs[4]);
   }
 
-  if (count2 > 0) {
-    count1 = segcounts[4] + segcounts[5];
-    count2 = segcounts[6] + segcounts[7];
-    cost += count1 * vp9_cost_zero(probs[4]) +
-            count2 * vp9_cost_one(probs[4]);
+  if (c4567 > 0) {
+    cost += c45 * vp9_cost_zero(probs[2]) +
+            c67 * vp9_cost_one(probs[2]);
 
-    if (count1 > 0)
+    if (c45 > 0)
       cost += segcounts[4] * vp9_cost_zero(probs[5]) +
               segcounts[5] * vp9_cost_one(probs[5]);
-    if (count2 > 0)
+    if (c67 > 0)
       cost += segcounts[6] * vp9_cost_zero(probs[6]) +
               segcounts[7] * vp9_cost_one(probs[6]);
   }