From b5364d4f3b606bcdbd4280067de99a95fd2f0b7e Mon Sep 17 00:00:00 2001 From: Dmitry Kovalev Date: Tue, 30 Apr 2013 14:06:49 -0700 Subject: [PATCH] Using treed_read/treed_write functions for segment ids. 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 | 6 +++ vp9/common/vp9_seg_common.h | 3 ++ vp9/decoder/vp9_decodemv.c | 18 +-------- vp9/encoder/vp9_bitstream.c | 57 ++------------------------ vp9/encoder/vp9_segmentation.c | 74 ++++++++++++++++------------------ 5 files changed, 48 insertions(+), 110 deletions(-) diff --git a/vp9/common/vp9_seg_common.c b/vp9/common/vp9_seg_common.c index 9ed3e2d5b..02b7053fe 100644 --- a/vp9/common/vp9_seg_common.c +++ b/vp9/common/vp9_seg_common.c @@ -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 diff --git a/vp9/common/vp9_seg_common.h b/vp9/common/vp9_seg_common.h index 4550dd143..53d22a385 100644 --- a/vp9/common/vp9_seg_common.h +++ b/vp9/common/vp9_seg_common.h @@ -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_ diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c index c51d0b243..3edd5238d 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -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, diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index b57ddbe2f..086774b19 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -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 diff --git a/vp9/encoder/vp9_segmentation.c b/vp9/encoder/vp9_segmentation.c index 7f792ae2b..31466530e 100644 --- a/vp9/encoder/vp9_segmentation.c +++ b/vp9/encoder/vp9_segmentation.c @@ -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]); } -- 2.40.0