From 6394ef28d719f74f2757f8aad245e43e5401c9e6 Mon Sep 17 00:00:00 2001 From: Paul Wilkins <paulwilkins@google.com> Date: Tue, 15 Nov 2011 15:22:26 +0000 Subject: [PATCH] Further clean up of Segmentation experiment code Changed name and sense of segment_flag to "seg_id_predicted" Added some additional comments and retested. I also did some experimentation with a spatial prediction option using a similar strategy to the temporal mode implemented. This helps in some cases where temporal prediction is bad but I suspect there is more overlap here with work on a larger scale block structure and spatial correlation will likely be better handled through that mechanism. Next check in will remove #ifdefs and legacy mode code. Change-Id: I3b382b65ed2a57bd7775ac0f3a01a9508a209cbc --- vp8/common/blockd.h | 8 +++++--- vp8/decoder/decodemv.c | 18 +++++++++++------- vp8/encoder/bitstream.c | 22 ++++++++++++---------- vp8/encoder/segmentation.c | 21 ++++++++++----------- 4 files changed, 38 insertions(+), 31 deletions(-) diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h index c477d2d6d9..9e23f4d7da 100644 --- a/vp8/common/blockd.h +++ b/vp8/common/blockd.h @@ -181,13 +181,15 @@ typedef struct MB_PREDICTION_MODE mode, uv_mode; MV_REFERENCE_FRAME ref_frame; int_mv mv; -#if CONFIG_SEGMENTATION - unsigned char segment_flag; -#endif unsigned char partitioning; unsigned char mb_skip_coeff; /* does this mb has coefficients at all, 1=no coefficients, 0=need decode tokens */ unsigned char need_to_clamp_mvs; unsigned char segment_id; /* Which set of segmentation parameters should be used for this MB */ +#if CONFIG_SEGMENTATION + // Flag used when temporal prediction of segment map is enabled. + // 1 means it is predicted 0 that it must be coded explicitly + unsigned char seg_id_predicted; +#endif } MB_MODE_INFO; diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c index 416865cae5..d75469f876 100644 --- a/vp8/decoder/decodemv.c +++ b/vp8/decoder/decodemv.c @@ -459,30 +459,34 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, if (xd->update_mb_segmentation_map) { #if CONFIG_SEGMENTATION + // Is temporal coding of the segment id for this mb enabled. if (xd->temporal_update) { + // Work out a context for decoding seg_id_predicted. pred_context = 0; - if (mb_col != 0) - pred_context += (mi-1)->mbmi.segment_flag; + pred_context += (mi-1)->mbmi.seg_id_predicted; if (mb_row != 0) pred_context += - (mi-pbi->common.mb_cols)->mbmi.segment_flag; + (mi-pbi->common.mb_cols)->mbmi.seg_id_predicted; + + mbmi->seg_id_predicted = + vp8_read(bc, + xd->mb_segment_pred_probs[pred_context]); - if (vp8_read(bc, - xd->mb_segment_pred_probs[pred_context]) == 0) + if ( mbmi->seg_id_predicted ) { mbmi->segment_id = pbi->segmentation_map[index]; - mbmi->segment_flag = 0; } + // If the segment id was not predicted decode it explicitly else { vp8_read_mb_segid(bc, &mi->mbmi, xd); - mbmi->segment_flag = 1; pbi->segmentation_map[index] = mbmi->segment_id; } } + // Normal unpredicted coding mode else { vp8_read_mb_segid(bc, &mi->mbmi, xd); diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index eda40f375e..cea5a6ce4d 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -1041,26 +1041,28 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) if (cpi->mb.e_mbd.update_mb_segmentation_map) { #if CONFIG_SEGMENTATION + // Is temporal coding of the segment map enabled if (xd->temporal_update) { + // Look at whether neighbours were successfully predicted + // to create a context for the seg_id_predicted flag. pred_context = 0; if (mb_col != 0) - pred_context += (m-1)->mbmi.segment_flag; + pred_context += (m-1)->mbmi.seg_id_predicted; if (mb_row != 0) - pred_context += (m-pc->mb_cols)->mbmi.segment_flag; + pred_context += (m-pc->mb_cols)->mbmi.seg_id_predicted; - if (m->mbmi.segment_flag == 0) - { - vp8_write(w,0,xd->mb_segment_pred_probs[pred_context]); - } - else - { - vp8_write(w,1,xd->mb_segment_pred_probs[pred_context]); + // Code the prediction flag for this mb + vp8_write( w, m->mbmi.seg_id_predicted, + xd->mb_segment_pred_probs[pred_context]); + + // If the mbs segment id was not predicted code explicitly + if (!m->mbmi.seg_id_predicted) write_mb_segid(w, mi, &cpi->mb.e_mbd); - } } else { + // Normal undpredicted coding write_mb_segid(w, mi, &cpi->mb.e_mbd); } index++; diff --git a/vp8/encoder/segmentation.c b/vp8/encoder/segmentation.c index 2eb0ce408c..2dc96c61b2 100644 --- a/vp8/encoder/segmentation.c +++ b/vp8/encoder/segmentation.c @@ -226,25 +226,26 @@ void choose_segmap_coding_method( VP8_COMP *cpi ) pred_context = 0; if (mb_col != 0) pred_context += - (xd->mode_info_context-1)->mbmi.segment_flag; + (xd->mode_info_context-1)->mbmi.seg_id_predicted; if (mb_row != 0) + { pred_context += - (xd->mode_info_context-cm->mb_cols)->mbmi.segment_flag; + (xd->mode_info_context-cm->mb_cols)-> + mbmi.seg_id_predicted; + } // Test to see if the last frame segment id at the same - // locationcorrectly predicts the segment_id for this MB. + // location correctly predicts the segment_id for this MB. // Update the prediction flag and count as appropriate; if ( segment_id == cpi->last_segmentation_map[segmap_index] ) { - //xd->mode_info_context->mbmi.segment_predicted = 1; - xd->mode_info_context->mbmi.segment_flag = 0; - temporal_predictor_count[pred_context][0]++; + xd->mode_info_context->mbmi.seg_id_predicted = 1; + temporal_predictor_count[pred_context][1]++; } else { - //xd->mode_info_context->mbmi.segment_predicted = 0; - xd->mode_info_context->mbmi.segment_flag = 1; - temporal_predictor_count[pred_context][1]++; + xd->mode_info_context->mbmi.seg_id_predicted = 0; + temporal_predictor_count[pred_context][0]++; // Update the "undpredicted" segment count t_unpred_seg_counts[segment_id]++; @@ -317,8 +318,6 @@ void choose_segmap_coding_method( VP8_COMP *cpi ) xd->temporal_update = 0; vpx_memcpy( xd->mb_segment_tree_probs, no_pred_tree, sizeof(no_pred_tree) ); - //vpx_memcpy( &xd->mb_segment_pred_probs, - // t_nopred_prob, sizeof(t_nopred_prob) ); } } #endif -- GitLab