Commit c77aff12 authored by Paul Wilkins's avatar Paul Wilkins
Browse files

Simplify Segment Coding

Remove top node optimization.
The improvement this gives is not sufficient to justify
the extra complexity.

Change-Id: I2bb4a12a50ffd52cacfa4a3e8acbb2e522066905
parent 27bb4777
......@@ -399,7 +399,6 @@ typedef struct macroblockd {
// Probability Tree used to code Segment number
vp9_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS];
vp9_prob mb_segment_mispred_tree_probs[MAX_MB_SEGMENTS];
// Segment features
signed char segment_feature_data[MAX_MB_SEGMENTS][SEG_LVL_MAX];
......
......@@ -79,21 +79,6 @@ static int read_mb_segid(vp9_reader *r, MACROBLOCKD *xd) {
: vp9_read(r, p[1]);
}
// This function reads the current macro block's segnent id from the bitstream
// It should only be called if a segment map update is indicated.
static int read_mb_segid_except(vp9_reader *r,
VP9_COMMON *cm, MACROBLOCKD *xd,
int mb_row, int mb_col) {
const BLOCK_SIZE_TYPE sb_type = xd->mode_info_context->mbmi.sb_type;
const int pred_seg_id = vp9_get_pred_mb_segid(cm, sb_type, mb_row, mb_col);
const vp9_prob *const p = xd->mb_segment_tree_probs;
const vp9_prob prob = xd->mb_segment_mispred_tree_probs[pred_seg_id];
return vp9_read(r, prob)
? 2 + (pred_seg_id < 2 ? vp9_read(r, p[2]) : (pred_seg_id == 2))
: (pred_seg_id >= 2 ? vp9_read(r, p[1]) : (pred_seg_id == 0));
}
static void set_segment_id(VP9_COMMON *cm, MB_MODE_INFO *mbmi,
int mb_row, int mb_col, int segment_id) {
const int mb_index = mb_row * cm->mb_cols + mb_col;
......@@ -551,7 +536,7 @@ static int read_mb_segment_id(VP9D_COMP *pbi, int mb_row, int mb_col,
// then use the predicted value, otherwise decode it explicitly
segment_id = pred_flag ? vp9_get_pred_mb_segid(cm, mbmi->sb_type,
mb_row, mb_col)
: read_mb_segid_except(r, cm, xd, mb_row, mb_col);
: read_mb_segid(r, xd);
} else {
segment_id = read_mb_segid(r, xd); // Normal unpredicted coding mode
}
......
......@@ -1113,19 +1113,6 @@ static void setup_segmentation(VP9_COMMON *pc, MACROBLOCKD *xd, vp9_reader *r) {
pc->temporal_update = vp9_read_bit(r);
if (pc->temporal_update) {
const vp9_prob *p = xd->mb_segment_tree_probs;
vp9_prob *mispred_p = xd->mb_segment_mispred_tree_probs;
const int c0 = p[0] * p[1];
const int c1 = p[0] * (256 - p[1]);
const int c2 = (256 - p[0]) * p[2];
const int c3 = (256 - p[0]) * (256 - p[2]);
mispred_p[0] = get_binary_prob(c1, c2 + c3);
mispred_p[1] = get_binary_prob(c0, c2 + c3);
mispred_p[2] = get_binary_prob(c0 + c1, c3);
mispred_p[3] = get_binary_prob(c0 + c1, c2);
for (i = 0; i < PREDICTION_PROBS; i++)
pc->segment_pred_probs[i] = vp9_read_bit(r) ? vp9_read_prob(r)
: MAX_PROB;
......
......@@ -560,28 +560,6 @@ static void write_mb_segid(vp9_writer *bc,
}
}
static void write_mb_segid_except(VP9_COMMON *cm,
vp9_writer *bc,
const MB_MODE_INFO *mi,
const MACROBLOCKD *xd,
int mb_row, int mb_col) {
// Encode the MB segment id.
const int seg_id = mi->segment_id;
const BLOCK_SIZE_TYPE sb_type = xd->mode_info_context->mbmi.sb_type;
const int pred_seg_id = vp9_get_pred_mb_segid(cm, sb_type, mb_row, mb_col);
const vp9_prob *p = xd->mb_segment_tree_probs;
const vp9_prob p1 = xd->mb_segment_mispred_tree_probs[pred_seg_id];
if (xd->segmentation_enabled && xd->update_mb_segmentation_map) {
vp9_write(bc, seg_id >= 2, p1);
if (pred_seg_id >= 2 && seg_id < 2) {
vp9_write(bc, seg_id == 1, p[1]);
} else if (pred_seg_id < 2 && seg_id >= 2) {
vp9_write(bc, seg_id == 3, p[2]);
}
}
}
// This function encodes the reference frame
static void encode_ref_frame(vp9_writer *const bc,
VP9_COMMON *const cm,
......@@ -725,7 +703,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
// If the mb segment id wasn't predicted code explicitly
if (!prediction_flag)
write_mb_segid_except(pc, bc, mi, &cpi->mb.e_mbd, mb_row, mb_col);
write_mb_segid(bc, mi, &cpi->mb.e_mbd);
} else {
// Normal unpredicted coding
write_mb_segid(bc, mi, &cpi->mb.e_mbd);
......
......@@ -103,8 +103,7 @@ static int cost_segmap(MACROBLOCKD *xd,
// Based on set of segment counts calculate a probability tree
static void calc_segtree_probs_pred(MACROBLOCKD *xd,
int (*segcounts)[MAX_MB_SEGMENTS],
vp9_prob *segment_tree_probs,
vp9_prob *mod_probs) {
vp9_prob *segment_tree_probs) {
int count[4];
assert(!segcounts[0][0] && !segcounts[1][1] &&
......@@ -121,24 +120,12 @@ static void calc_segtree_probs_pred(MACROBLOCKD *xd,
count[2] + count[3]);
segment_tree_probs[1] = get_binary_prob(count[0], count[1]);
segment_tree_probs[2] = get_binary_prob(count[2], count[3]);
// now work out modified counts that the decoder would have
count[0] = segment_tree_probs[0] * segment_tree_probs[1];
count[1] = segment_tree_probs[0] * (256 - segment_tree_probs[1]);
count[2] = (256 - segment_tree_probs[0]) * segment_tree_probs[2];
count[3] = (256 - segment_tree_probs[0]) * (256 - segment_tree_probs[2]);
// Work out modified probabilties depending on what segment was predicted
mod_probs[0] = get_binary_prob(count[1], count[2] + count[3]);
mod_probs[1] = get_binary_prob(count[0], count[2] + count[3]);
mod_probs[2] = get_binary_prob(count[0] + count[1], count[3]);
mod_probs[3] = get_binary_prob(count[0] + count[1], count[2]);
}
// Based on set of segment counts and probabilities calculate a cost estimate
static int cost_segmap_pred(MACROBLOCKD *xd,
int (*segcounts)[MAX_MB_SEGMENTS],
vp9_prob *probs, vp9_prob *mod_probs) {
vp9_prob *probs) {
int pred_seg, cost = 0;
for (pred_seg = 0; pred_seg < MAX_MB_SEGMENTS; pred_seg++) {
......@@ -147,8 +134,8 @@ static int cost_segmap_pred(MACROBLOCKD *xd,
// Cost the top node of the tree
count1 = segcounts[pred_seg][0] + segcounts[pred_seg][1];
count2 = segcounts[pred_seg][2] + segcounts[pred_seg][3];
cost += count1 * vp9_cost_zero(mod_probs[pred_seg]) +
count2 * vp9_cost_one(mod_probs[pred_seg]);
cost += count1 * vp9_cost_zero(probs[0]) +
count2 * vp9_cost_one(probs[0]);
// Now add the cost of each individual segment branch
if (pred_seg >= 2 && count1) {
......@@ -217,7 +204,6 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
vp9_prob no_pred_tree[MB_FEATURE_TREE_PROBS];
vp9_prob t_pred_tree[MB_FEATURE_TREE_PROBS];
vp9_prob t_pred_tree_mod[MAX_MB_SEGMENTS];
vp9_prob t_nopred_prob[PREDICTION_PROBS];
const int mis = cm->mode_info_stride;
......@@ -332,10 +318,8 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
if (cm->frame_type != KEY_FRAME) {
// Work out probability tree for coding those segments not
// predicted using the temporal method and the cost.
calc_segtree_probs_pred(xd, t_unpred_seg_counts, t_pred_tree,
t_pred_tree_mod);
t_pred_cost = cost_segmap_pred(xd, t_unpred_seg_counts, t_pred_tree,
t_pred_tree_mod);
calc_segtree_probs_pred(xd, t_unpred_seg_counts, t_pred_tree);
t_pred_cost = cost_segmap_pred(xd, t_unpred_seg_counts, t_pred_tree);
// Add in the cost of the signalling for each prediction context
for (i = 0; i < PREDICTION_PROBS; i++) {
......@@ -355,8 +339,6 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
cm->temporal_update = 1;
vpx_memcpy(xd->mb_segment_tree_probs,
t_pred_tree, sizeof(t_pred_tree));
vpx_memcpy(xd->mb_segment_mispred_tree_probs,
t_pred_tree_mod, sizeof(t_pred_tree_mod));
vpx_memcpy(&cm->segment_pred_probs,
t_nopred_prob, sizeof(t_nopred_prob));
} else {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment