From 56904be19de4894c40e3e6325cc7631f61ac88c5 Mon Sep 17 00:00:00 2001 From: Paul Wilkins Date: Sat, 28 Jan 2012 10:24:43 +0000 Subject: [PATCH] Use common prediction interface for segment coding. This does not change any functionality just modifies the code to use the common prediction module interface for coding the segment data. Change-Id: Ifd43e9153573365619774a4f5572215e44fb5aa3 --- vp8/decoder/decodemv.c | 114 ++++++++++++++++++++++--------------- vp8/decoder/decodframe.c | 3 + vp8/encoder/bitstream.c | 26 +++++---- vp8/encoder/segmentation.c | 39 +++++-------- 4 files changed, 99 insertions(+), 83 deletions(-) diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c index 3e3b8616b..bee47ef3e 100644 --- a/vp8/decoder/decodemv.c +++ b/vp8/decoder/decodemv.c @@ -17,6 +17,7 @@ //#if CONFIG_SEGFEATURES #include "vp8/common/seg_common.h" +#include "vp8/common/pred_common.h" #if CONFIG_DEBUG #include @@ -437,6 +438,67 @@ static void mb_mode_mv_init(VP8D_COMP *pbi) } } +// This function either reads the segment id for the current macroblock from +// the bitstream or if the value is temporally predicted asserts the predicted +// value +static void read_mb_segment_id ( VP8D_COMP *pbi, + int mb_row, int mb_col ) +{ + vp8_reader *const bc = & pbi->bc; + VP8_COMMON *const cm = & pbi->common; + MACROBLOCKD *const xd = & pbi->mb; + MODE_INFO *mi = xd->mode_info_context; + MB_MODE_INFO *mbmi = &mi->mbmi; + int index = mb_row * pbi->common.mb_cols + mb_col; + + if (xd->segmentation_enabled) + { + if (xd->update_mb_segmentation_map) + { + // Is temporal coding of the segment id for this mb enabled. + if (cm->temporal_update) + { + // Get the context based probability for reading the + // prediction status flag + vp8_prob pred_prob = + get_pred_prob( cm, xd, PRED_SEG_ID ); + + // Read the prediction status flag + unsigned char seg_pred_flag = + (unsigned char)vp8_read(bc, pred_prob ); + + // Store the prediction flag. + set_pred_flag( xd, PRED_SEG_ID, seg_pred_flag ); + + // If the value is flagged as correctly predicted + // then use the predicted value + if ( seg_pred_flag ) + { + mbmi->segment_id = get_pred_mb_segid( cm, index ); + } + // Else .... decode it explicitly + else + { + vp8_read_mb_segid(bc, mbmi, xd ); + cm->last_frame_seg_map[index] = mbmi->segment_id; + } + + } + // Normal unpredicted coding mode + else + { + vp8_read_mb_segid(bc, mbmi, xd); + cm->last_frame_seg_map[index] = mbmi->segment_id; + } + } + } + else + { + // The encoder explicitly sets the segment_id to 0 + // when segmentation is disabled + mbmi->segment_id = 0; + } +} static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, #if CONFIG_NEWNEAR @@ -477,53 +539,13 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, mb_to_right_edge = ((pbi->common.mb_cols - 1 - mb_col) * 16) << 3; mb_to_right_edge += RIGHT_BOTTOM_MARGIN; - /* If required read in new segmentation data for this MB */ - if (xd->segmentation_enabled) - { - if (xd->update_mb_segmentation_map) - { - // Is temporal coding of the segment id for this mb enabled. - if (cm->temporal_update) - { - // Work out a context for decoding seg_id_predicted. - pred_context = 0; - if (mb_col != 0) - pred_context += (mi-1)->mbmi.seg_id_predicted; - if (mb_row != 0) - pred_context += - (mi-cm->mode_info_stride)->mbmi.seg_id_predicted; - - mbmi->seg_id_predicted = - vp8_read(bc, - cm->segment_pred_probs[pred_context]); - - if ( mbmi->seg_id_predicted ) - { - mbmi->segment_id = cm->last_frame_seg_map[index]; - } - // If the segment id was not predicted decode it explicitly - else - { - vp8_read_mb_segid(bc, &mi->mbmi, xd); - cm->last_frame_seg_map[index] = mbmi->segment_id; - } + // Make sure the MACROBLOCKD mode info pointer is pointed at the + // correct entry for the current macroblock. + xd->mode_info_context = mi; + + // Read the macroblock segment id. + read_mb_segment_id ( pbi, mb_row, mb_col ); - } - // Normal unpredicted coding mode - else - { - vp8_read_mb_segid(bc, &mi->mbmi, xd); - cm->last_frame_seg_map[index] = mbmi->segment_id; - } - index++; - } - } - else - { - // The encoder explicitly sets the segment_id to 0 - // when segmentation is disabled - mbmi->segment_id = 0; - } //#if CONFIG_SEGFEATURES if ( pbi->common.mb_no_coeff_skip && ( !segfeature_active( xd, diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index 7725dbc53..bb15f6956 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -1393,6 +1393,9 @@ int vp8_decode_frame(VP8D_COMP *pbi) vpx_memset(pc->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) * pc->mb_cols); + // Resset the macroblock mode info context to the start of the list + xd->mode_info_context = pc->mi; + #if CONFIG_MULTITHREAD if (pbi->b_multithreaded_rd && pc->multi_token_partition != ONE_PARTITION) { diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index 00129f7ae..37292fa71 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -27,6 +27,7 @@ //#if CONFIG_SEGFEATURES #include "vp8/common/seg_common.h" +#include "vp8/common/pred_common.h" #if defined(SECTIONBITS_OUTPUT) unsigned __int64 Sectionbits[500]; @@ -944,6 +945,10 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) int prob_dual_pred[3]; #endif /* CONFIG_DUALPRED */ + // Values used in prediction model coding + vp8_prob pred_prob; + unsigned char prediction_flag; + cpi->mb.partition_info = cpi->mb.pi; // Calculate the probabilities to be used to code the reference frame @@ -1053,6 +1058,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) // Make sure the MacroBlockD mode info pointer is set correctly xd->mode_info_context = m; + #if CONFIG_NEWNEAR xd->prev_mode_info_context = prev_m; #endif @@ -1066,20 +1072,16 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) // Is temporal coding of the segment map enabled if (pc->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.seg_id_predicted; - if (mb_row != 0) - pred_context += (m-pc->mode_info_stride)->mbmi.seg_id_predicted; - - // Code the prediction flag for this mb - vp8_write( w, m->mbmi.seg_id_predicted, - pc->segment_pred_probs[pred_context]); + prediction_flag = + get_pred_flag( xd, PRED_SEG_ID ); + pred_prob = + get_pred_prob( pc, xd, PRED_SEG_ID); + + // Code the segment id prediction flag for this mb + vp8_write( w, prediction_flag, pred_prob ); // If the mbs segment id was not predicted code explicitly - if (!m->mbmi.seg_id_predicted) + if (!prediction_flag) write_mb_segid(w, mi, &cpi->mb.e_mbd); } else diff --git a/vp8/encoder/segmentation.c b/vp8/encoder/segmentation.c index 9fce482f6..1d2e98bd0 100644 --- a/vp8/encoder/segmentation.c +++ b/vp8/encoder/segmentation.c @@ -12,6 +12,7 @@ #include "limits.h" #include "vpx_mem/vpx_mem.h" #include "segmentation.h" +#include "vp8/common/pred_common.h" void vp8_update_gf_useage_maps(VP8_COMP *cpi, VP8_COMMON *cm, MACROBLOCK *x) { @@ -57,7 +58,7 @@ void vp8_update_gf_useage_maps(VP8_COMP *cpi, VP8_COMMON *cm, MACROBLOCK *x) } x->gf_active_ptr++; // Step onto next entry - this_mb_mode_info++; // skip to next mb + this_mb_mode_info++; // skip to next mb } @@ -229,34 +230,22 @@ void choose_segmap_coding_method( VP8_COMP *cpi ) // Temporal prediction not allowed on key frames if (cm->frame_type != KEY_FRAME) { - // Get temporal prediction context - pred_context = 0; - if (mb_col != 0) - pred_context += - (xd->mode_info_context-1)->mbmi.seg_id_predicted; - if (mb_row != 0) - { - pred_context += - (xd->mode_info_context-cm->mode_info_stride)-> - mbmi.seg_id_predicted; - } + // Test to see if the segment id matches the predicted value. + int seg_predicted = + (segment_id == get_pred_mb_segid( cm, segmap_index )); - // Test to see if the last frame segment id at the same - // location correctly predicts the segment_id for this MB. - // Update the prediction flag and count as appropriate; - if ( segment_id == cm->last_frame_seg_map[segmap_index] ) - { - xd->mode_info_context->mbmi.seg_id_predicted = 1; - temporal_predictor_count[pred_context][1]++; - } - else - { - xd->mode_info_context->mbmi.seg_id_predicted = 0; - temporal_predictor_count[pred_context][0]++; + // Get the segment id prediction context + pred_context = + get_pred_context( cm, xd, PRED_SEG_ID ); + + // Store the prediction status for this mb and update counts + // as appropriate + set_pred_flag( xd, PRED_SEG_ID, seg_predicted ); + temporal_predictor_count[pred_context][seg_predicted]++; + if ( !seg_predicted ) // Update the "undpredicted" segment count t_unpred_seg_counts[segment_id]++; - } } // Step on to the next mb -- 2.40.0