From 7d7e5b513131b5c752a00fe58a70fbda3b6f035f Mon Sep 17 00:00:00 2001 From: Paul Wilkins Date: Sat, 27 Apr 2013 23:49:49 +0100 Subject: [PATCH] Further Implicit Segmentation Changes Trial use of a combination of reference frame, prediction block size and mv to define segmentation. Change-Id: Ie8946a0446dbad777fdcf7626f89e5af0994db50 --- vp9/common/vp9_seg_common.c | 64 ++++++++++++++++++++++++++++++++++++++++++--- vp9/encoder/vp9_onyx_if.c | 28 +++++++++++++------- 2 files changed, 79 insertions(+), 13 deletions(-) diff --git a/vp9/common/vp9_seg_common.c b/vp9/common/vp9_seg_common.c index 02b7053..e5511a1 100644 --- a/vp9/common/vp9_seg_common.c +++ b/vp9/common/vp9_seg_common.c @@ -89,7 +89,7 @@ int vp9_check_segref(const MACROBLOCKD *xd, int segment_id, #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,9 +97,66 @@ void vp9_implicit_segment_map_update(VP9_COMMON * cm) { 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; @@ -107,6 +164,7 @@ 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 diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 3d8003c..24e85c0 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -487,12 +487,14 @@ static void configure_static_seg_features(VP9_COMP *cpi) { } #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 @@ static void configure_implicit_segmentation(VP9_COMP *cpi) { // 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 @@ void vp9_set_speed_features(VP9_COMP *cpi) { #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 @@ void vp9_set_speed_features(VP9_COMP *cpi) { #if CONFIG_IMPLICIT_SEGMENTATION sf->static_segmentation = 0; #else - sf->static_segmentation = 1; + sf->static_segmentation = 0; #endif #endif sf->splitmode_breakout = 1; @@ -2944,13 +2952,13 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, 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 -- 2.7.4