From c09f652590fe6a18f76eeee15c8722ce236c8a0a Mon Sep 17 00:00:00 2001 From: Dmitry Kovalev Date: Fri, 19 Apr 2013 14:25:32 -0700 Subject: [PATCH] Removing get_segment_id function and using existing vp9_get_pred_mb_segid. Change-Id: Iff35d4b2f8f65511f80c594958c01fb4673fa033 --- vp9/common/vp9_pred_common.c | 38 ++++++------ vp9/common/vp9_pred_common.h | 5 +- vp9/decoder/vp9_decodemv.c | 108 ++++++++++++--------------------- vp9/encoder/vp9_bitstream.c | 6 +- vp9/encoder/vp9_segmentation.c | 4 +- 5 files changed, 64 insertions(+), 97 deletions(-) diff --git a/vp9/common/vp9_pred_common.c b/vp9/common/vp9_pred_common.c index ffdfa6782..e110cff44 100644 --- a/vp9/common/vp9_pred_common.c +++ b/vp9/common/vp9_pred_common.c @@ -9,6 +9,8 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include + #include "vp9/common/vp9_common.h" #include "vp9/common/vp9_pred_common.h" #include "vp9/common/vp9_seg_common.h" @@ -225,30 +227,26 @@ void vp9_set_pred_flag(MACROBLOCKD *const xd, // peredict various bitstream signals. // Macroblock segment id prediction function -unsigned char vp9_get_pred_mb_segid(const VP9_COMMON *const cm, - const MACROBLOCKD *const xd, int MbIndex) { - // Currently the prediction for the macroblock segment ID is - // the value stored for this macroblock in the previous frame. - if (!xd->mode_info_context->mbmi.sb_type) { - return cm->last_frame_seg_map[MbIndex]; - } else { - BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type; - const int bh = 1 << mb_height_log2(bsize); - const int bw = 1 << mb_width_log2(bsize); - const int mb_col = MbIndex % cm->mb_cols; - const int mb_row = MbIndex / cm->mb_cols; - const int x_mbs = MIN(bw, cm->mb_cols - mb_col); - const int y_mbs = MIN(bh, cm->mb_rows - mb_row); +int vp9_get_pred_mb_segid(VP9_COMMON *cm, BLOCK_SIZE_TYPE sb_type, + int mb_row, int mb_col) { + const int mb_index = mb_row * cm->mb_cols + mb_col; + if (sb_type) { + const int bw = 1 << mb_width_log2(sb_type); + const int bh = 1 << mb_height_log2(sb_type); + const int ymbs = MIN(cm->mb_rows - mb_row, bh); + const int xmbs = MIN(cm->mb_cols - mb_col, bw); + int segment_id = INT_MAX; int x, y; - unsigned seg_id = -1; - for (y = mb_row; y < mb_row + y_mbs; y++) { - for (x = mb_col; x < mb_col + x_mbs; x++) { - seg_id = MIN(seg_id, cm->last_frame_seg_map[cm->mb_cols * y + x]); + for (y = 0; y < ymbs; y++) { + for (x = 0; x < xmbs; x++) { + const int index = mb_index + (y * cm->mb_cols + x); + segment_id = MIN(segment_id, cm->last_frame_seg_map[index]); } } - - return seg_id; + return segment_id; + } else { + return cm->last_frame_seg_map[mb_index]; } } diff --git a/vp9/common/vp9_pred_common.h b/vp9/common/vp9_pred_common.h index 49dcf0a4c..222d5f3d0 100644 --- a/vp9/common/vp9_pred_common.h +++ b/vp9/common/vp9_pred_common.h @@ -43,9 +43,8 @@ void vp9_set_pred_flag(MACROBLOCKD *const xd, unsigned char pred_flag); -unsigned char vp9_get_pred_mb_segid(const VP9_COMMON *const cm, - const MACROBLOCKD *const xd, - int MbIndex); +int vp9_get_pred_mb_segid(VP9_COMMON *cm, BLOCK_SIZE_TYPE sb_type, + int mb_row, int mb_col); MV_REFERENCE_FRAME vp9_get_pred_ref(const VP9_COMMON *const cm, const MACROBLOCKD *const xd); diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c index 2a8521a14..d64c8e62f 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -84,8 +84,8 @@ static int read_mb_segid(vp9_reader *r, MACROBLOCKD *xd) { static int read_mb_segid_except(vp9_reader *r, VP9_COMMON *cm, MACROBLOCKD *xd, int mb_row, int mb_col) { - const int mb_index = mb_row * cm->mb_cols + mb_col; - const int pred_seg_id = vp9_get_pred_mb_segid(cm, xd, mb_index); + const BLOCK_SIZE_TYPE sb_type = xd->mode_info_context->mbmi.sb_type; + const int pred_seg_id = vp9_get_pred_mb_segid(cm, sb_type, mb_row, mb_col); const vp9_prob *const p = xd->mb_segment_tree_probs; const vp9_prob prob = xd->mb_segment_mispred_tree_probs[pred_seg_id]; @@ -116,30 +116,6 @@ static void set_segment_id(VP9_COMMON *cm, MB_MODE_INFO *mbmi, } } -static int get_segment_id(VP9_COMMON *cm, MB_MODE_INFO *mbmi, - int mb_row, int mb_col) { - const int mb_index = mb_row * cm->mb_cols + mb_col; - const BLOCK_SIZE_TYPE sb_type = mbmi->sb_type; - if (sb_type) { - const int bw = 1 << mb_width_log2(sb_type); - const int bh = 1 << mb_height_log2(sb_type); - const int ymbs = MIN(cm->mb_rows - mb_row, bh); - const int xmbs = MIN(cm->mb_cols - mb_col, bw); - int segment_id = INT_MAX; - int x, y; - - for (y = 0; y < ymbs; y++) { - for (x = 0; x < xmbs; x++) { - const int index = mb_index + (y * cm->mb_cols + x); - segment_id = MIN(segment_id, cm->last_frame_seg_map[index]); - } - } - return segment_id; - } else { - return cm->last_frame_seg_map[mb_index]; - } -} - extern const int vp9_i8x8_block[4]; static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m, int mb_row, int mb_col, @@ -149,19 +125,19 @@ static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m, const int mis = cm->mode_info_stride; m->mbmi.ref_frame = INTRA_FRAME; - // Read the Macroblock segmentation map if it is being updated explicitly - // this frame (reset to 0 by default). + // Read segmentation map if it is being updated explicitly this frame m->mbmi.segment_id = 0; if (xd->segmentation_enabled && xd->update_mb_segmentation_map) { m->mbmi.segment_id = read_mb_segid(r, xd); set_segment_id(cm, &m->mbmi, mb_row, mb_col, m->mbmi.segment_id); } - m->mbmi.mb_skip_coeff = vp9_segfeature_active(&pbi->mb, m->mbmi.segment_id, + m->mbmi.mb_skip_coeff = vp9_segfeature_active(xd, m->mbmi.segment_id, SEG_LVL_SKIP); if (!m->mbmi.mb_skip_coeff) m->mbmi.mb_skip_coeff = vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_MBSKIP)); + // luma mode m->mbmi.mode = m->mbmi.sb_type ? read_kf_sb_ymode(r, cm->sb_kf_ymode_prob[cm->kf_ymode_probs_index]): read_kf_mb_ymode(r, cm->kf_ymode_prob[cm->kf_ymode_probs_index]); @@ -169,19 +145,19 @@ static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m, m->mbmi.ref_frame = INTRA_FRAME; if (m->mbmi.mode == I4X4_PRED) { - int i = 0; - do { + int i; + for (i = 0; i < 16; ++i) { const B_PREDICTION_MODE a = above_block_mode(m, i, mis); const B_PREDICTION_MODE l = xd->left_available || (i & 3) ? left_block_mode(m, i) : B_DC_PRED; m->bmi[i].as_mode.first = read_kf_bmode(r, cm->kf_bmode_prob[a][l]); - } while (++i < 16); + } } if (m->mbmi.mode == I8X8_PRED) { int i; - for (i = 0; i < 4; i++) { + for (i = 0; i < 4; ++i) { const int ib = vp9_i8x8_block[i]; const int mode8x8 = read_i8x8_mode(r, cm->fc.i8x8_mode_prob); @@ -190,7 +166,10 @@ static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m, m->bmi[ib + 4].as_mode.first = mode8x8; m->bmi[ib + 5].as_mode.first = mode8x8; } - } else { + } + + // chroma mode + if (m->mbmi.mode != I8X8_PRED) { m->mbmi.uv_mode = read_uv_mode(r, cm->kf_uv_mode_prob[m->mbmi.mode]); } @@ -527,12 +506,10 @@ static void mb_mode_mv_init(VP9D_COMP *pbi, vp9_reader *r) { for (i = 0; i < VP9_I32X32_MODES - 1; ++i) cm->fc.sb_ymode_prob[i] = vp9_read_prob(r); - for (j = 0; j < PARTITION_PLANES; j++) { - if (vp9_read_bit(r)) { + for (j = 0; j < PARTITION_PLANES; j++) + if (vp9_read_bit(r)) for (i = 0; i < PARTITION_TYPES - 1; i++) cm->fc.partition_prob[j][i] = vp9_read_prob(r); - } - } read_nmvprobs(r, nmvc, xd->allow_high_precision_mv); } @@ -541,47 +518,40 @@ static void mb_mode_mv_init(VP9D_COMP *pbi, vp9_reader *r) { // 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(VP9D_COMP *pbi, - int mb_row, int mb_col, - vp9_reader *r) { +static int read_mb_segment_id(VP9D_COMP *pbi, int mb_row, int mb_col, + vp9_reader *r) { VP9_COMMON *const cm = &pbi->common; MACROBLOCKD *const xd = &pbi->mb; MODE_INFO *const mi = xd->mode_info_context; MB_MODE_INFO *const mbmi = &mi->mbmi; - const int mb_index = mb_row * cm->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 - vp9_prob pred_prob = vp9_get_pred_prob(cm, xd, PRED_SEG_ID); + if (!xd->segmentation_enabled) + return 0; // Default for disabled segmentation - // Read the prediction status flag - unsigned char seg_pred_flag = vp9_read(r, pred_prob); + if (xd->update_mb_segmentation_map) { + int segment_id; - // Store the prediction flag. - vp9_set_pred_flag(xd, PRED_SEG_ID, seg_pred_flag); + if (cm->temporal_update) { + // Temporal coding of the segment id for this mb is enabled. + // Get the context based probability for reading the + // prediction status flag + const vp9_prob pred_prob = vp9_get_pred_prob(cm, xd, PRED_SEG_ID); + const int pred_flag = vp9_read(r, pred_prob); + vp9_set_pred_flag(xd, PRED_SEG_ID, pred_flag); - // If the value is flagged as correctly predicted - // then use the predicted value, otherwise decode it explicitly - mbmi->segment_id = seg_pred_flag ? - vp9_get_pred_mb_segid(cm, xd, mb_index) : - read_mb_segid_except(r, cm, xd, mb_row, mb_col); - } else { - // Normal unpredicted coding mode - mbmi->segment_id = read_mb_segid(r, xd); - } - - set_segment_id(cm, mbmi, mb_row, mb_col, mbmi->segment_id); + // If the value is flagged as correctly predicted + // then use the predicted value, otherwise decode it explicitly + segment_id = pred_flag ? vp9_get_pred_mb_segid(cm, mbmi->sb_type, + mb_row, mb_col) + : read_mb_segid_except(r, cm, xd, mb_row, mb_col); } else { - mbmi->segment_id = get_segment_id(cm, mbmi, mb_row, mb_col); + segment_id = read_mb_segid(r, xd); // Normal unpredicted coding mode } + + set_segment_id(cm, mbmi, mb_row, mb_col, segment_id); // Side effect + return segment_id; } else { - // The encoder explicitly sets the segment_id to 0 - // when segmentation is disabled - mbmi->segment_id = 0; + return vp9_get_pred_mb_segid(cm, mbmi->sb_type, mb_row, mb_col); } } @@ -656,7 +626,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, mb_to_right_edge = xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN; // Read the macroblock segment id. - read_mb_segment_id(pbi, mb_row, mb_col, r); + mbmi->segment_id = read_mb_segment_id(pbi, mb_row, mb_col, r); mbmi->mb_skip_coeff = vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_SKIP); diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index d4ccf8ca2..bc269dc46 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -554,9 +554,9 @@ static void write_mb_segid_except(VP9_COMMON *cm, const MACROBLOCKD *xd, int mb_row, int mb_col) { // Encode the MB segment id. - int seg_id = mi->segment_id; - int pred_seg_id = vp9_get_pred_mb_segid(cm, xd, - mb_row * cm->mb_cols + mb_col); + const int seg_id = mi->segment_id; + const BLOCK_SIZE_TYPE sb_type = xd->mode_info_context->mbmi.sb_type; + const int pred_seg_id = vp9_get_pred_mb_segid(cm, sb_type, mb_row, mb_col); const vp9_prob *p = xd->mb_segment_tree_probs; const vp9_prob p1 = xd->mb_segment_mispred_tree_probs[pred_seg_id]; diff --git a/vp9/encoder/vp9_segmentation.c b/vp9/encoder/vp9_segmentation.c index aac42f738..58208c6cd 100644 --- a/vp9/encoder/vp9_segmentation.c +++ b/vp9/encoder/vp9_segmentation.c @@ -215,7 +215,6 @@ static void count_segs(VP9_COMP *cpi, int bw, int bh, int mb_row, int mb_col) { VP9_COMMON *const cm = &cpi->common; MACROBLOCKD *const xd = &cpi->mb.e_mbd; - const int segmap_index = mb_row * cm->mb_cols + mb_col; const int segment_id = mi->mbmi.segment_id; xd->mode_info_context = mi; @@ -228,7 +227,8 @@ static void count_segs(VP9_COMP *cpi, // Temporal prediction not allowed on key frames if (cm->frame_type != KEY_FRAME) { // Test to see if the segment id matches the predicted value. - const int pred_seg_id = vp9_get_pred_mb_segid(cm, xd, segmap_index); + const int pred_seg_id = vp9_get_pred_mb_segid(cm, mi->mbmi.sb_type, + mb_row, mb_col); const int seg_predicted = (segment_id == pred_seg_id); // Get the segment id prediction context