diff --git a/vp9/common/vp9_seg_common.c b/vp9/common/vp9_seg_common.c index 9ed3e2d5b908657b663700feff756264ba620ef1..02b7053fecb2ef2a85e9e26c5973ff004062eb7c 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 4550dd143a9b4e7b2fb51d4efa2b848176f07eed..53d22a3854aef51d60332e8699201dfb7e7d148b 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 55c67374abd2dee2ed937d813882b23f2f5db682..a290c55377618121794639ac637552d11d897d2d 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -76,23 +76,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 f8e273364f8a2b37befed37aee5d9edf90badee6..5811b1d0060709ca37837164908dfbca12554e0e 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -512,60 +512,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 e04980ce1189e641850267ad7c475313c8061180..86af268bfd20487fd8b152a79009f9c446996d68 100644 --- a/vp9/encoder/vp9_segmentation.c +++ b/vp9/encoder/vp9_segmentation.c @@ -57,61 +57,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]); }