ref: 18e07420a27fadd37a2d864bdec539123a8dbcec
parent: 418564e7d0b4e70611f41b81d9c09f72d2697cfc
parent: 7d7e5b513131b5c752a00fe58a70fbda3b6f035f
author: Paul Wilkins <paulwilkins@google.com>
date: Wed May 15 23:03:44 EDT 2013
Merge "Further Implicit Segmentation Changes" into experimental
--- a/vp9/common/vp9_seg_common.c
+++ b/vp9/common/vp9_seg_common.c
@@ -89,7 +89,7 @@
#if CONFIG_IMPLICIT_SEGMENTATION
// This function defines an implicit segmentation for the next frame based
// on predcition and transform decisions in the current frame.
-// For test purposes at the moment only TX size is used.
+// For test purposes at the moment it uses ref frame and prediction size
void vp9_implicit_segment_map_update(VP9_COMMON * cm) {
int row, col;
MODE_INFO *mi, *mi_ptr = cm->mi;
@@ -97,15 +97,73 @@
for (row = 0; row < cm->mb_rows; row++) {
mi = mi_ptr;
- // Experimental use of tx size to define implicit segmentation
+
for (col = 0; col < cm->mb_cols; ++col, ++mi) {
- map_ptr[col] = 1 + mi->mbmi.txfm_size;
+ // Inter prediction
+ if (mi->mbmi.ref_frame != INTRA_FRAME) {
+ // Zero motion and prediction block size >= 16
+ if ((mi->mbmi.sb_type >= BLOCK_SIZE_MB16X16) &&
+ (mi->mbmi.mv[0].as_int == 0))
+ map_ptr[col] = 1;
+ else if (mi->mbmi.sb_type >= BLOCK_SIZE_SB32X32)
+ map_ptr[col] = 2;
+ else if (mi->mbmi.sb_type >= BLOCK_SIZE_MB16X16)
+ map_ptr[col] = 3;
+ else
+ map_ptr[col] = 6;
+
+ // Intra prediction
+ } else {
+ if (mi->mbmi.sb_type >= BLOCK_SIZE_SB32X32)
+ map_ptr[col] = 4;
+ else if (mi->mbmi.sb_type >= BLOCK_SIZE_MB16X16)
+ map_ptr[col] = 5;
+ else
+ map_ptr[col] = 7;
+ }
}
mi_ptr += cm->mode_info_stride;
map_ptr += cm->mb_cols;
}
}
+
+// This function defines an implicit segmentation for the next frame based
+// on predcition and transform decisions in the current frame.
+// For test purposes at the moment only TX size is used.
+void vp9_implicit_segment_map_update_tx(VP9_COMMON * cm) {
+ int row, col;
+ MODE_INFO *mi, *mi_ptr = cm->mi;
+ unsigned char * map_ptr = cm->last_frame_seg_map;
+
+ for (row = 0; row < cm->mb_rows; row++) {
+ mi = mi_ptr;
+ for (col = 0; col < cm->mb_cols; ++col, ++mi) {
+ // Intra modes
+ if (mi->mbmi.ref_frame == INTRA_FRAME) {
+ if (mi->mbmi.txfm_size == TX_4X4)
+ map_ptr[col] = 7;
+ else if (mi->mbmi.txfm_size <= TX_16X16)
+ map_ptr[col] = 5;
+ else
+ map_ptr[col] = 4;
+ } else {
+ // Inter Modes
+ if (mi->mbmi.txfm_size == TX_4X4)
+ map_ptr[col] = 6;
+ else if (mi->mbmi.txfm_size == TX_8X8)
+ map_ptr[col] = 3;
+ else if (mi->mbmi.txfm_size == TX_16X16)
+ map_ptr[col] = 2;
+ else
+ map_ptr[col] = 1;
+ }
+ }
+ mi_ptr += cm->mode_info_stride;
+ map_ptr += cm->mb_cols;
+ }
+}
#endif
+
const vp9_tree_index vp9_segment_tree[14] = {
2, 4, 6, 8, 10, 12,
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -487,12 +487,14 @@
}
#if CONFIG_IMPLICIT_SEGMENTATION
-static void configure_implicit_segmentation(VP9_COMP *cpi) {
+static double implict_seg_q_modifiers[MAX_MB_SEGMENTS] =
+ {1.0, 0.95, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
+static void configure_implicit_segmentation(VP9_COMP *cpi, int frame_qindex) {
VP9_COMMON *cm = &cpi->common;
MACROBLOCKD *xd = &cpi->mb.e_mbd;
int i;
int qi_delta;
- double q_target = cpi->active_worst_quality * 1.10;
+ double q_baseline = vp9_convert_qindex_to_q(frame_qindex);
// Set the flags to allow implicit segment update but disallow explicit update
xd->segmentation_enabled = 1;
@@ -507,13 +509,19 @@
// Clear down the segment features.
vp9_clearall_segfeatures(xd);
+ xd->update_mb_segmentation_data = 0;
+
+ // Update the segment data if it is an arf or non overlay gf.
+ } else if (cpi->refresh_alt_ref_frame ||
+ (cpi->refresh_golden_frame && !cpi->is_src_frame_alt_ref)) {
xd->update_mb_segmentation_data = 1;
// Enable use of q deltas on segments 1 and up
+ // Segment 0 is treated as a neutral segment with no changes
for (i = 1; i < MAX_MB_SEGMENTS; ++i) {
- qi_delta = compute_qdelta(cpi, cpi->active_worst_quality, q_target);
+ qi_delta = compute_qdelta(cpi, q_baseline,
+ implict_seg_q_modifiers[i] * q_baseline);
vp9_set_segdata(xd, i, SEG_LVL_ALT_Q, qi_delta);
- q_target *= 0.95;
vp9_enable_segfeature(xd, i, SEG_LVL_ALT_Q);
}
@@ -728,7 +736,7 @@
#if CONFIG_IMPLICIT_SEGMENTATION
sf->static_segmentation = 0;
#else
- sf->static_segmentation = 1;
+ sf->static_segmentation = 0;
#endif
#endif
sf->splitmode_breakout = 0;
@@ -747,7 +755,7 @@
#if CONFIG_IMPLICIT_SEGMENTATION
sf->static_segmentation = 0;
#else
- sf->static_segmentation = 1;
+ sf->static_segmentation = 0;
#endif
#endif
sf->splitmode_breakout = 1;
@@ -2945,13 +2953,13 @@
cpi->common.frame_context_idx = cpi->refresh_alt_ref_frame;
vp9_setup_inter_frame(cpi);
}
+ }
#if CONFIG_IMPLICIT_SEGMENTATION
- if (!cm->error_resilient_mode && !cpi->sf.static_segmentation) {
- configure_implicit_segmentation(cpi);
- }
-#endif
+ if (!cm->error_resilient_mode && !cpi->sf.static_segmentation) {
+ configure_implicit_segmentation(cpi, q);
}
+#endif
// transform / motion compensation build reconstruction frame
#if CONFIG_MODELCOEFPROB
--
⑨