summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vp9/common/vp9_blockd.h2
-rw-r--r--vp9/encoder/vp9_bitstream.c180
-rw-r--r--vp9/encoder/vp9_encodeframe.c12
-rw-r--r--vp9/encoder/vp9_mbgraph.c4
-rw-r--r--vp9/encoder/vp9_onyx_if.c36
-rw-r--r--vp9/encoder/vp9_rdopt.c7
-rw-r--r--vp9/encoder/vp9_segmentation.c35
7 files changed, 126 insertions, 150 deletions
diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h
index 8bb5a6911..053159c0a 100644
--- a/vp9/common/vp9_blockd.h
+++ b/vp9/common/vp9_blockd.h
@@ -355,7 +355,7 @@ typedef struct macroblockd {
PARTITION_CONTEXT *above_seg_context;
PARTITION_CONTEXT *left_seg_context;
- /* 0 indicates segmentation at MB level is not enabled. Otherwise the individual bits indicate which features are active. */
+ /* 0 (disable) 1 (enable) segmentation */
unsigned char segmentation_enabled;
/* 0 (do not update) 1 (update) the macroblock segmentation map. */
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 245305479..38657450e 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -923,25 +923,20 @@ static void write_mb_modes_kf(const VP9_COMP *cpi,
const int segment_id = m->mbmi.segment_id;
int skip_coeff;
- if (xd->update_mb_segmentation_map) {
+ if (xd->update_mb_segmentation_map)
write_mb_segid(bc, &m->mbmi, xd);
- }
if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
skip_coeff = 1;
} else {
skip_coeff = m->mbmi.mb_skip_coeff;
- vp9_write(bc, skip_coeff,
- vp9_get_pred_prob(c, xd, PRED_MBSKIP));
+ vp9_write(bc, skip_coeff, vp9_get_pred_prob(c, xd, PRED_MBSKIP));
}
- if (m->mbmi.sb_type > BLOCK_SIZE_MB16X16) {
- sb_kfwrite_ymode(bc, ym,
- c->sb_kf_ymode_prob[c->kf_ymode_probs_index]);
- } else {
- kfwrite_ymode(bc, ym,
- c->kf_ymode_prob[c->kf_ymode_probs_index]);
- }
+ if (m->mbmi.sb_type > BLOCK_SIZE_MB16X16)
+ sb_kfwrite_ymode(bc, ym, c->sb_kf_ymode_prob[c->kf_ymode_probs_index]);
+ else
+ kfwrite_ymode(bc, ym, c->kf_ymode_prob[c->kf_ymode_probs_index]);
if (ym == I4X4_PRED) {
int i = 0;
@@ -1747,16 +1742,91 @@ static void segment_reference_frames(VP9_COMP *cpi) {
}
}
-void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
- unsigned long *size) {
+static void encode_segmentation(VP9_COMP *cpi, vp9_writer *w) {
int i, j;
+ VP9_COMMON *const pc = &cpi->common;
+ MACROBLOCKD *const xd = &cpi->mb.e_mbd;
+
+ vp9_write_bit(w, xd->segmentation_enabled);
+ if (!xd->segmentation_enabled)
+ return;
+
+ // Segmentation map
+ vp9_write_bit(w, xd->update_mb_segmentation_map);
+#if CONFIG_IMPLICIT_SEGMENTATION
+ vp9_write_bit(w, xd->allow_implicit_segment_update);
+#endif
+ if (xd->update_mb_segmentation_map) {
+ // Select the coding strategy (temporal or spatial)
+ vp9_choose_segmap_coding_method(cpi);
+ // Write out probabilities used to decode unpredicted macro-block segments
+ for (i = 0; i < MB_SEG_TREE_PROBS; i++) {
+ const int prob = xd->mb_segment_tree_probs[i];
+ if (prob != MAX_PROB) {
+ vp9_write_bit(w, 1);
+ vp9_write_prob(w, prob);
+ } else {
+ vp9_write_bit(w, 0);
+ }
+ }
+
+ // Write out the chosen coding method.
+ vp9_write_bit(w, pc->temporal_update);
+ if (pc->temporal_update) {
+ for (i = 0; i < PREDICTION_PROBS; i++) {
+ const int prob = pc->segment_pred_probs[i];
+ if (prob != MAX_PROB) {
+ vp9_write_bit(w, 1);
+ vp9_write_prob(w, prob);
+ } else {
+ vp9_write_bit(w, 0);
+ }
+ }
+ }
+ }
+
+ // Segmentation data
+ vp9_write_bit(w, xd->update_mb_segmentation_data);
+ // segment_reference_frames(cpi);
+ if (xd->update_mb_segmentation_data) {
+ vp9_write_bit(w, xd->mb_segment_abs_delta);
+
+ for (i = 0; i < MAX_MB_SEGMENTS; i++) {
+ for (j = 0; j < SEG_LVL_MAX; j++) {
+ const int data = vp9_get_segdata(xd, i, j);
+ const int data_max = vp9_seg_feature_data_max(j);
+
+ if (vp9_segfeature_active(xd, i, j)) {
+ vp9_write_bit(w, 1);
+
+ if (vp9_is_segfeature_signed(j)) {
+ if (data < 0) {
+ vp9_encode_unsigned_max(w, -data, data_max);
+ vp9_write_bit(w, 1);
+ } else {
+ vp9_encode_unsigned_max(w, data, data_max);
+ vp9_write_bit(w, 0);
+ }
+ } else {
+ vp9_encode_unsigned_max(w, data, data_max);
+ }
+ } else {
+ vp9_write_bit(w, 0);
+ }
+ }
+ }
+ }
+}
+
+void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
+ int i;
VP9_HEADER oh;
VP9_COMMON *const pc = &cpi->common;
vp9_writer header_bc, residual_bc;
MACROBLOCKD *const xd = &cpi->mb.e_mbd;
int extra_bytes_packed = 0;
- unsigned char *cx_data = dest;
+ uint8_t *cx_data = dest;
oh.show_frame = (int) pc->show_frame;
oh.type = (int)pc->frame_type;
@@ -1989,87 +2059,7 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
active_section = 7;
#endif
- // Signal whether or not Segmentation is enabled
- vp9_write_bit(&header_bc, (xd->segmentation_enabled) ? 1 : 0);
-
- // Indicate which features are enabled
- if (xd->segmentation_enabled) {
- // Indicate whether or not the segmentation map is being updated.
- vp9_write_bit(&header_bc, (xd->update_mb_segmentation_map) ? 1 : 0);
-#if CONFIG_IMPLICIT_SEGMENTATION
- vp9_write_bit(&header_bc, (xd->allow_implicit_segment_update) ? 1 : 0);
-#endif
-
- // If it is, then indicate the method that will be used.
- if (xd->update_mb_segmentation_map) {
- // Select the coding strategy (temporal or spatial)
- vp9_choose_segmap_coding_method(cpi);
- // Send the tree probabilities used to decode unpredicted
- // macro-block segments
- for (i = 0; i < MB_SEG_TREE_PROBS; i++) {
- const int prob = xd->mb_segment_tree_probs[i];
- if (prob != 255) {
- vp9_write_bit(&header_bc, 1);
- vp9_write_prob(&header_bc, prob);
- } else {
- vp9_write_bit(&header_bc, 0);
- }
- }
-
- // Write out the chosen coding method.
- vp9_write_bit(&header_bc, (pc->temporal_update) ? 1 : 0);
- if (pc->temporal_update) {
- for (i = 0; i < PREDICTION_PROBS; i++) {
- const int prob = pc->segment_pred_probs[i];
- if (prob != 255) {
- vp9_write_bit(&header_bc, 1);
- vp9_write_prob(&header_bc, prob);
- } else {
- vp9_write_bit(&header_bc, 0);
- }
- }
- }
- }
-
- vp9_write_bit(&header_bc, (xd->update_mb_segmentation_data) ? 1 : 0);
-
- // segment_reference_frames(cpi);
-
- if (xd->update_mb_segmentation_data) {
- vp9_write_bit(&header_bc, (xd->mb_segment_abs_delta) ? 1 : 0);
-
- // For each segments id...
- for (i = 0; i < MAX_MB_SEGMENTS; i++) {
- // For each segmentation codable feature...
- for (j = 0; j < SEG_LVL_MAX; j++) {
- const int8_t data = vp9_get_segdata(xd, i, j);
- const int data_max = vp9_seg_feature_data_max(j);
-
- // If the feature is enabled...
- if (vp9_segfeature_active(xd, i, j)) {
- vp9_write_bit(&header_bc, 1);
-
- // Is the segment data signed..
- if (vp9_is_segfeature_signed(j)) {
- // Encode the relevant feature data
- if (data < 0) {
- vp9_encode_unsigned_max(&header_bc, -data, data_max);
- vp9_write_bit(&header_bc, 1);
- } else {
- vp9_encode_unsigned_max(&header_bc, data, data_max);
- vp9_write_bit(&header_bc, 0);
- }
- } else {
- // Unsigned data element so no sign bit needed
- vp9_encode_unsigned_max(&header_bc, data, data_max);
- }
- } else {
- vp9_write_bit(&header_bc, 0);
- }
- }
- }
- }
- }
+ encode_segmentation(cpi, &header_bc);
// Encode the common prediction model status flag probability updates for
// the reference frame
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 3877391d8..06b4d6316 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -631,13 +631,11 @@ static void set_offsets(VP9_COMP *cpi,
/* segment ID */
if (xd->segmentation_enabled) {
- if (xd->update_mb_segmentation_map) {
- mbmi->segment_id = find_seg_id(cpi->segmentation_map, bsize,
- mi_row, cm->mi_rows, mi_col, cm->mi_cols);
- } else {
- mbmi->segment_id = find_seg_id(cm->last_frame_seg_map, bsize,
- mi_row, cm->mi_rows, mi_col, cm->mi_cols);
- }
+ uint8_t *map = xd->update_mb_segmentation_map ? cpi->segmentation_map
+ : cm->last_frame_seg_map;
+ mbmi->segment_id = find_seg_id(map, bsize, mi_row,
+ cm->mi_rows, mi_col, cm->mi_cols);
+
assert(mbmi->segment_id <= (MAX_MB_SEGMENTS-1));
vp9_mb_init_quantizer(cpi, x);
diff --git a/vp9/encoder/vp9_mbgraph.c b/vp9/encoder/vp9_mbgraph.c
index fe5d114ba..af62ec394 100644
--- a/vp9/encoder/vp9_mbgraph.c
+++ b/vp9/encoder/vp9_mbgraph.c
@@ -419,10 +419,10 @@ static void separate_arf_mbs(VP9_COMP *cpi) {
cpi->static_mb_pct = 0;
cpi->seg0_cnt = ncnt[0];
- vp9_enable_segmentation((VP9_PTR) cpi);
+ vp9_enable_segmentation((VP9_PTR)cpi);
} else {
cpi->static_mb_pct = 0;
- vp9_disable_segmentation((VP9_PTR) cpi);
+ vp9_disable_segmentation((VP9_PTR)cpi);
}
// Free localy allocated storage
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 53d03aa95..865cd8a38 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -280,8 +280,7 @@ static void setup_features(VP9_COMP *cpi) {
MACROBLOCKD *xd = &cpi->mb.e_mbd;
// Set up default state for MB feature flags
-
- xd->segmentation_enabled = 0; // Default segmentation disabled
+ xd->segmentation_enabled = 0;
xd->update_mb_segmentation_map = 0;
xd->update_mb_segmentation_data = 0;
@@ -383,7 +382,7 @@ static void configure_static_seg_features(VP9_COMP *cpi) {
xd->update_mb_segmentation_map = 0;
xd->update_mb_segmentation_data = 0;
#if CONFIG_IMPLICIT_SEGMENTATION
- xd->allow_implicit_segment_update = 0;
+ xd->allow_implicit_segment_update = 0;
#endif
cpi->static_mb_pct = 0;
@@ -399,7 +398,7 @@ static void configure_static_seg_features(VP9_COMP *cpi) {
xd->update_mb_segmentation_map = 0;
xd->update_mb_segmentation_data = 0;
#if CONFIG_IMPLICIT_SEGMENTATION
- xd->allow_implicit_segment_update = 0;
+ xd->allow_implicit_segment_update = 0;
#endif
cpi->static_mb_pct = 0;
@@ -428,9 +427,9 @@ static void configure_static_seg_features(VP9_COMP *cpi) {
xd->mb_segment_abs_delta = SEGMENT_DELTADATA;
}
- }
- // All other frames if segmentation has been enabled
- else if (xd->segmentation_enabled) {
+ } else if (xd->segmentation_enabled) {
+ // All other frames if segmentation has been enabled
+
// First normal frame in a valid gf or alt ref group
if (cpi->common.frames_since_golden == 0) {
// Set up segment features for normal frames in an arf group
@@ -454,10 +453,10 @@ static void configure_static_seg_features(VP9_COMP *cpi) {
vp9_enable_segfeature(xd, 1, SEG_LVL_REF_FRAME);
vp9_enable_segfeature(xd, 1, SEG_LVL_SKIP);
}
- }
- // Disable segmentation and clear down features if alt ref
- // is not active for this group
- else {
+ } else {
+ // Disable segmentation and clear down features if alt ref
+ // is not active for this group
+
vp9_disable_segmentation((VP9_PTR)cpi);
vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
@@ -467,12 +466,11 @@ static void configure_static_seg_features(VP9_COMP *cpi) {
vp9_clearall_segfeatures(xd);
}
- }
+ } else if (cpi->is_src_frame_alt_ref) {
+ // Special case where we are coding over the top of a previous
+ // alt ref frame.
+ // Segment coding disabled for compred testing
- // Special case where we are coding over the top of a previous
- // alt ref frame.
- // Segment coding disabled for compred testing
- else if (cpi->is_src_frame_alt_ref) {
// Enable ref frame features for segment 0 as well
vp9_enable_segfeature(xd, 0, SEG_LVL_REF_FRAME);
vp9_enable_segfeature(xd, 1, SEG_LVL_REF_FRAME);
@@ -490,9 +488,9 @@ static void configure_static_seg_features(VP9_COMP *cpi) {
}
// Enable data udpate
xd->update_mb_segmentation_data = 1;
- }
- // All other frames.
- else {
+ } else {
+ // All other frames.
+
// No updates.. leave things as they are.
xd->update_mb_segmentation_map = 0;
xd->update_mb_segmentation_data = 0;
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index cc142d94f..92b0cf184 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -4824,10 +4824,9 @@ void vp9_pick_mode_inter_macroblock(VP9_COMP *cpi, MACROBLOCK *x,
int64_t intra_error = 0;
unsigned char *segment_id = &mbmi->segment_id;
- if (xd->segmentation_enabled)
- x->encode_breakout = cpi->segment_encode_breakout[*segment_id];
- else
- x->encode_breakout = cpi->oxcf.encode_breakout;
+ x->encode_breakout = xd->segmentation_enabled ?
+ cpi->segment_encode_breakout[*segment_id] :
+ cpi->oxcf.encode_breakout;
// if (cpi->sf.RD)
// For now this codebase is limited to a single rd encode path
diff --git a/vp9/encoder/vp9_segmentation.c b/vp9/encoder/vp9_segmentation.c
index 7f792ae2b..69d3a9617 100644
--- a/vp9/encoder/vp9_segmentation.c
+++ b/vp9/encoder/vp9_segmentation.c
@@ -16,18 +16,15 @@
#include "vp9/common/vp9_tile_common.h"
void vp9_enable_segmentation(VP9_PTR ptr) {
- VP9_COMP *cpi = (VP9_COMP *)(ptr);
+ VP9_COMP *cpi = (VP9_COMP *)ptr;
- // Set the appropriate feature bit
cpi->mb.e_mbd.segmentation_enabled = 1;
cpi->mb.e_mbd.update_mb_segmentation_map = 1;
cpi->mb.e_mbd.update_mb_segmentation_data = 1;
}
void vp9_disable_segmentation(VP9_PTR ptr) {
- VP9_COMP *cpi = (VP9_COMP *)(ptr);
-
- // Clear the appropriate feature bit
+ VP9_COMP *cpi = (VP9_COMP *)ptr;
cpi->mb.e_mbd.segmentation_enabled = 0;
}
@@ -238,10 +235,8 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
// Set default state for the segment tree probabilities and the
// temporal coding probabilities
- vpx_memset(xd->mb_segment_tree_probs, 255,
- sizeof(xd->mb_segment_tree_probs));
- vpx_memset(cm->segment_pred_probs, 255,
- sizeof(cm->segment_pred_probs));
+ vpx_memset(xd->mb_segment_tree_probs, 255, sizeof(xd->mb_segment_tree_probs));
+ vpx_memset(cm->segment_pred_probs, 255, sizeof(cm->segment_pred_probs));
vpx_memset(no_pred_segcounts, 0, sizeof(no_pred_segcounts));
vpx_memset(t_unpred_seg_counts, 0, sizeof(t_unpred_seg_counts));
@@ -249,7 +244,6 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
// First of all generate stats regarding how well the last segment map
// predicts this one
-
for (tile_col = 0; tile_col < cm->tile_columns; tile_col++) {
vp9_get_tile_col_offsets(cm, tile_col);
mi_ptr = cm->mi + cm->cur_tile_mi_col_start;
@@ -279,27 +273,24 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
// Add in the cost of the signalling for each prediction context
for (i = 0; i < PREDICTION_PROBS; i++) {
- t_nopred_prob[i] = get_binary_prob(temporal_predictor_count[i][0],
- temporal_predictor_count[i][1]);
+ const int count0 = temporal_predictor_count[i][0];
+ const int count1 = temporal_predictor_count[i][1];
+
+ t_nopred_prob[i] = get_binary_prob(count0, count1);
// Add in the predictor signaling cost
- t_pred_cost += (temporal_predictor_count[i][0] *
- vp9_cost_zero(t_nopred_prob[i])) +
- (temporal_predictor_count[i][1] *
- vp9_cost_one(t_nopred_prob[i]));
+ t_pred_cost += count0 * vp9_cost_zero(t_nopred_prob[i]) +
+ count1 * vp9_cost_one(t_nopred_prob[i]);
}
}
// Now choose which coding method to use.
if (t_pred_cost < no_pred_cost) {
cm->temporal_update = 1;
- vpx_memcpy(xd->mb_segment_tree_probs,
- t_pred_tree, sizeof(t_pred_tree));
- vpx_memcpy(&cm->segment_pred_probs,
- t_nopred_prob, sizeof(t_nopred_prob));
+ vpx_memcpy(xd->mb_segment_tree_probs, t_pred_tree, sizeof(t_pred_tree));
+ vpx_memcpy(cm->segment_pred_probs, t_nopred_prob, sizeof(t_nopred_prob));
} else {
cm->temporal_update = 0;
- vpx_memcpy(xd->mb_segment_tree_probs,
- no_pred_tree, sizeof(no_pred_tree));
+ vpx_memcpy(xd->mb_segment_tree_probs, no_pred_tree, sizeof(no_pred_tree));
}
}