summaryrefslogtreecommitdiff
path: root/vp8/encoder
diff options
context:
space:
mode:
authorRonald S. Bultje <rbultje@google.com>2012-10-29 17:58:18 -0700
committerRonald S. Bultje <rbultje@google.com>2012-10-29 17:58:18 -0700
commit7944b4f239f6c11fbd3316d491eaec363a7fd2aa (patch)
tree2791f97d1ce0120942319042b2f89867f781af89 /vp8/encoder
parent1758dc03d45df9b64c17ddf74a6310e615f2d612 (diff)
downloadlibvpx-7944b4f239f6c11fbd3316d491eaec363a7fd2aa.tar
libvpx-7944b4f239f6c11fbd3316d491eaec363a7fd2aa.tar.gz
libvpx-7944b4f239f6c11fbd3316d491eaec363a7fd2aa.tar.bz2
libvpx-7944b4f239f6c11fbd3316d491eaec363a7fd2aa.zip
Fix superblock experiment.
Also merge some duplicate code related to the superblock experiment in the RD loop. Change-Id: Ic93f1d4d1ed81220fd7ecf6e65da2821a215b2de
Diffstat (limited to 'vp8/encoder')
-rw-r--r--vp8/encoder/bitstream.c29
-rw-r--r--vp8/encoder/encodeframe.c49
-rw-r--r--vp8/encoder/onyx_if.c10
-rw-r--r--vp8/encoder/onyx_int.h2
-rw-r--r--vp8/encoder/rdopt.c985
-rw-r--r--vp8/encoder/rdopt.h1
-rw-r--r--vp8/encoder/segmentation.c22
7 files changed, 461 insertions, 637 deletions
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
index 4c1d61ed8..ff7d836d7 100644
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -744,8 +744,22 @@ static unsigned int pick_best_mv_ref(MACROBLOCK *x,
static void write_mb_segid(vp8_writer *bc,
const MB_MODE_INFO *mi, const MACROBLOCKD *xd) {
// Encode the MB segment id.
+ int seg_id = mi->segment_id;
+#if CONFIG_SUPERBLOCKS
+ if (mi->encoded_as_sb) {
+ if (xd->mb_to_right_edge > 0)
+ seg_id = seg_id && xd->mode_info_context[1].mbmi.segment_id;
+ if (xd->mb_to_bottom_edge > 0) {
+ seg_id = seg_id &&
+ xd->mode_info_context[xd->mode_info_stride].mbmi.segment_id;
+ if (xd->mb_to_right_edge > 0)
+ seg_id = seg_id &&
+ xd->mode_info_context[xd->mode_info_stride + 1].mbmi.segment_id;
+ }
+ }
+#endif
if (xd->segmentation_enabled && xd->update_mb_segmentation_map) {
- switch (mi->segment_id) {
+ switch (seg_id) {
case 0:
vp8_write(bc, 0, xd->mb_segment_tree_probs[0]);
vp8_write(bc, 0, xd->mb_segment_tree_probs[1]);
@@ -952,7 +966,6 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi, vp8_writer *const bc) {
#ifdef ENTROPY_STATS
active_section = 9;
#endif
-
if (cpi->mb.e_mbd.update_mb_segmentation_map) {
// Is temporal coding of the segment map enabled
if (pc->temporal_update) {
@@ -1245,7 +1258,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi, vp8_writer *const bc) {
}
}
- if (((rf == INTRA_FRAME && mode <= I8X8_PRED) ||
+ if (
+#if CONFIG_SUPERBLOCKS
+ !mi->encoded_as_sb &&
+#endif
+ ((rf == INTRA_FRAME && mode <= I8X8_PRED) ||
(rf != INTRA_FRAME && !(mode == SPLITMV &&
mi->partitioning == PARTITIONING_4X4))) &&
pc->txfm_mode == TX_MODE_SELECT &&
@@ -1386,7 +1403,11 @@ static void write_mb_modes_kf(const VP8_COMMON *c,
} else
write_uv_mode(bc, m->mbmi.uv_mode, c->kf_uv_mode_prob[ym]);
- if (ym <= I8X8_PRED && c->txfm_mode == TX_MODE_SELECT &&
+ if (
+#if CONFIG_SUPERBLOCKS
+ !m->mbmi.encoded_as_sb &&
+#endif
+ ym <= I8X8_PRED && c->txfm_mode == TX_MODE_SELECT &&
!((c->mb_no_coeff_skip && m->mbmi.mb_skip_coeff) ||
(segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
get_segdata(xd, segment_id, SEG_LVL_EOB) == 0))) {
diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c
index e464fde38..0a9a63607 100644
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -389,9 +389,14 @@ static void update_state(VP8_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
vpx_memcpy(xd->mode_info_context, mi, sizeof(MODE_INFO));
#if CONFIG_SUPERBLOCKS
if (mi->mbmi.encoded_as_sb) {
- vpx_memcpy(xd->mode_info_context + 1, mi, sizeof(MODE_INFO));
- vpx_memcpy(xd->mode_info_context + cpi->common.mode_info_stride, mi, sizeof(MODE_INFO));
- vpx_memcpy(xd->mode_info_context + cpi->common.mode_info_stride + 1, mi, sizeof(MODE_INFO));
+ const int mis = cpi->common.mode_info_stride;
+ if (xd->mb_to_right_edge > 0)
+ vpx_memcpy(xd->mode_info_context + 1, mi, sizeof(MODE_INFO));
+ if (xd->mb_to_bottom_edge > 0) {
+ vpx_memcpy(xd->mode_info_context + mis, mi, sizeof(MODE_INFO));
+ if (xd->mb_to_right_edge > 0)
+ vpx_memcpy(xd->mode_info_context + mis + 1, mi, sizeof(MODE_INFO));
+ }
}
#endif
@@ -1442,25 +1447,47 @@ static int check_dual_ref_flags(VP8_COMP *cpi) {
static void reset_skip_txfm_size(VP8_COMP *cpi, TX_SIZE txfm_max) {
VP8_COMMON *cm = &cpi->common;
- int mb_row, mb_col, mis = cm->mode_info_stride;
+ int mb_row, mb_col, mis = cm->mode_info_stride, segment_id;
MODE_INFO *mi, *mi_ptr = cm->mi;
+#if CONFIG_SUPERBLOCKS
+ MODE_INFO *sb_mi_ptr = cm->mi, *sb_mi;
+ MB_MODE_INFO *sb_mbmi;
+#endif
MB_MODE_INFO *mbmi;
MACROBLOCK *x = &cpi->mb;
MACROBLOCKD *xd = &x->e_mbd;
for (mb_row = 0; mb_row < cm->mb_rows; mb_row++, mi_ptr += mis) {
mi = mi_ptr;
+#if CONFIG_SUPERBLOCKS
+ sb_mi = sb_mi_ptr;
+#endif
for (mb_col = 0; mb_col < cm->mb_cols; mb_col++, mi++) {
mbmi = &mi->mbmi;
- if (mbmi->txfm_size > txfm_max) {
- int segment_id = mbmi->segment_id;
+#if CONFIG_SUPERBLOCKS
+ sb_mbmi = &sb_mi->mbmi;
+#endif
+ if (
+#if CONFIG_SUPERBLOCKS
+ !sb_mbmi->encoded_as_sb &&
+#endif
+ mbmi->txfm_size > txfm_max) {
+ segment_id = mbmi->segment_id;
xd->mode_info_context = mi;
assert((segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
get_segdata(xd, segment_id, SEG_LVL_EOB) == 0) ||
(cm->mb_no_coeff_skip && mbmi->mb_skip_coeff));
mbmi->txfm_size = txfm_max;
}
+#if CONFIG_SUPERBLOCKS
+ if (mb_col & 1)
+ sb_mi += 2;
+#endif
}
+#if CONFIG_SUPERBLOCKS
+ if (mb_row & 1)
+ sb_mi_ptr += 2 * mis;
+#endif
}
}
@@ -1854,8 +1881,7 @@ void vp8cx_encode_intra_super_block(VP8_COMP *cpi,
vp8_build_intra_predictors_sbuv_s(&x->e_mbd);
assert(x->e_mbd.mode_info_context->mbmi.txfm_size == TX_8X8);
- for (n = 0; n < 4; n++)
- {
+ for (n = 0; n < 4; n++) {
int x_idx = n & 1, y_idx = n >> 1;
xd->above_context = cm->above_context + mb_col + (n & 1);
@@ -2249,8 +2275,7 @@ void vp8cx_encode_inter_superblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
}
assert(x->e_mbd.mode_info_context->mbmi.txfm_size == TX_8X8);
- for (n = 0; n < 4; n++)
- {
+ for (n = 0; n < 4; n++) {
int x_idx = n & 1, y_idx = n >> 1;
vp8_subtract_mby_s_c(x->src_diff,
@@ -2281,7 +2306,7 @@ void vp8cx_encode_inter_superblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
if (!x->skip) {
if (output_enabled) {
xd->left_context = cm->left_context + (n >> 1);
- xd->above_context = cm->above_context + mb_col + (n >> 1);
+ xd->above_context = cm->above_context + mb_col + (n & 1);
memcpy(&ta[n], xd->above_context, sizeof(ta[n]));
memcpy(&tl[n], xd->left_context, sizeof(tl[n]));
tp[n] = *t;
@@ -2298,7 +2323,7 @@ void vp8cx_encode_inter_superblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
if (cpi->common.mb_no_coeff_skip) {
skip[n] = xd->mode_info_context->mbmi.mb_skip_coeff = 1;
xd->left_context = cm->left_context + (n >> 1);
- xd->above_context = cm->above_context + mb_col + (n >> 1);
+ xd->above_context = cm->above_context + mb_col + (n & 1);
memcpy(&ta[n], xd->above_context, sizeof(ta[n]));
memcpy(&tl[n], xd->left_context, sizeof(tl[n]));
tp[n] = *t;
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 1c37eb133..3fefc8ad9 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -629,8 +629,14 @@ static void update_reference_segmentation_map(VP8_COMP *cpi) {
uint8_t *cache = segcache + col * 2;
#if CONFIG_SUPERBLOCKS
if (miptr->mbmi.encoded_as_sb) {
- cache[0] = cache[1] = cache[cm->mb_cols] = cache[cm->mb_cols + 1] =
- miptr->mbmi.segment_id;
+ cache[0] = miptr->mbmi.segment_id;
+ if (!(cm->mb_cols & 1) || col < sb_cols - 1)
+ cache[1] = miptr->mbmi.segment_id;
+ if (!(cm->mb_rows & 1) || row < sb_rows - 1) {
+ cache[cm->mb_cols] = miptr->mbmi.segment_id;
+ if (!(cm->mb_cols & 1) || col < sb_cols - 1)
+ cache[cm->mb_cols + 1] = miptr->mbmi.segment_id;
+ }
} else
#endif
{
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
index b94b736bc..75a767b19 100644
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -353,7 +353,7 @@ typedef struct VP8_ENCODER_RTCD {
vp8_temporal_rtcd_vtable_t temporal;
} VP8_ENCODER_RTCD;
-enum {
+enum BlockSize {
BLOCK_16X8 = PARTITIONING_16X8,
BLOCK_8X16 = PARTITIONING_8X16,
BLOCK_8X8 = PARTITIONING_8X8,
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c
index 12ff9c3ec..410996942 100644
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -2941,11 +2941,17 @@ void vp8_mv_pred(VP8_COMP *cpi, MACROBLOCKD *xd, const MODE_INFO *here,
vp8_clamp_mv2(mvp, xd);
}
-void vp8_cal_sad(VP8_COMP *cpi, MACROBLOCKD *xd, MACROBLOCK *x, int recon_yoffset, int near_sadidx[]) {
-
- int near_sad[8] = {0}; // 0-cf above, 1-cf left, 2-cf aboveleft, 3-lf current, 4-lf above, 5-lf left, 6-lf right, 7-lf below
+static void cal_sad(VP8_COMP *cpi, MACROBLOCKD *xd, MACROBLOCK *x,
+ int recon_yoffset, int near_sadidx[],
+ enum BlockSize block_size) {
+ /* 0-cf above, 1-cf left, 2-cf aboveleft, 3-lf current, 4-lf above,
+ * 5-lf left, 6-lf right, 7-lf below */
+ int near_sad[8] = {0};
BLOCK *b = &x->block[0];
unsigned char *src_y_ptr = *(b->base_src);
+ const unsigned char *dst_y_ptr = xd->dst.y_buffer;
+ const int bs = (block_size == BLOCK_16X16) ? 16 : 32;
+ const int dst_y_str = xd->dst.y_stride;
// calculate sad for current frame 3 nearby MBs.
if (xd->mb_to_top_edge == 0 && xd->mb_to_left_edge == 0) {
@@ -2953,36 +2959,56 @@ void vp8_cal_sad(VP8_COMP *cpi, MACROBLOCKD *xd, MACROBLOCK *x, int recon_yoffse
} else if (xd->mb_to_top_edge == 0) {
// only has left MB for sad calculation.
near_sad[0] = near_sad[2] = INT_MAX;
- near_sad[1] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, xd->dst.y_buffer - 16, xd->dst.y_stride, 0x7fffffff);
+ near_sad[1] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+ dst_y_ptr - bs,
+ dst_y_str, 0x7fffffff);
} else if (xd->mb_to_left_edge == 0) {
// only has left MB for sad calculation.
near_sad[1] = near_sad[2] = INT_MAX;
- near_sad[0] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, xd->dst.y_buffer - xd->dst.y_stride * 16, xd->dst.y_stride, 0x7fffffff);
+ near_sad[0] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+ dst_y_ptr - dst_y_str * bs,
+ dst_y_str, 0x7fffffff);
} else {
- near_sad[0] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, xd->dst.y_buffer - xd->dst.y_stride * 16, xd->dst.y_stride, 0x7fffffff);
- near_sad[1] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, xd->dst.y_buffer - 16, xd->dst.y_stride, 0x7fffffff);
- near_sad[2] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, xd->dst.y_buffer - xd->dst.y_stride * 16 - 16, xd->dst.y_stride, 0x7fffffff);
+ near_sad[0] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+ dst_y_ptr - dst_y_str * bs,
+ dst_y_str, 0x7fffffff);
+ near_sad[1] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+ dst_y_ptr - bs,
+ dst_y_str, 0x7fffffff);
+ near_sad[2] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+ dst_y_ptr - dst_y_str * bs - bs,
+ dst_y_str, 0x7fffffff);
}
if (cpi->common.last_frame_type != KEY_FRAME) {
// calculate sad for last frame 5 nearby MBs.
unsigned char *pre_y_buffer = cpi->common.yv12_fb[cpi->common.lst_fb_idx].y_buffer + recon_yoffset;
- int pre_y_stride = cpi->common.yv12_fb[cpi->common.lst_fb_idx].y_stride;
+ const int pre_y_str = cpi->common.yv12_fb[cpi->common.lst_fb_idx].y_stride;
if (xd->mb_to_top_edge == 0) near_sad[4] = INT_MAX;
if (xd->mb_to_left_edge == 0) near_sad[5] = INT_MAX;
if (xd->mb_to_right_edge == 0) near_sad[6] = INT_MAX;
if (xd->mb_to_bottom_edge == 0) near_sad[7] = INT_MAX;
+ near_sad[3] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+ pre_y_buffer,
+ pre_y_str, 0x7fffffff);
if (near_sad[4] != INT_MAX)
- near_sad[4] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, pre_y_buffer - pre_y_stride * 16, pre_y_stride, 0x7fffffff);
+ near_sad[4] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+ pre_y_buffer - pre_y_str * bs,
+ pre_y_str, 0x7fffffff);
if (near_sad[5] != INT_MAX)
- near_sad[5] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, pre_y_buffer - 16, pre_y_stride, 0x7fffffff);
- near_sad[3] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, pre_y_buffer, pre_y_stride, 0x7fffffff);
+ near_sad[5] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+ pre_y_buffer - bs,
+ pre_y_str, 0x7fffffff);
if (near_sad[6] != INT_MAX)
- near_sad[6] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, pre_y_buffer + 16, pre_y_stride, 0x7fffffff);
+ near_sad[6] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+ pre_y_buffer + bs,
+ pre_y_str, 0x7fffffff);
if (near_sad[7] != INT_MAX)
- near_sad[7] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, pre_y_buffer + pre_y_stride * 16, pre_y_stride, 0x7fffffff);
+ near_sad[7] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+ pre_y_buffer + pre_y_str * bs,
+ pre_y_str, 0x7fffffff);
}
if (cpi->common.last_frame_type != KEY_FRAME) {
@@ -3181,7 +3207,11 @@ static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
ctx->comp_pred_diff = comp_pred_diff;
ctx->hybrid_pred_diff = hybrid_pred_diff;
- memcpy(ctx->txfm_rd_diff, txfm_size_diff, sizeof(ctx->txfm_rd_diff));
+ if (txfm_size_diff) {
+ memcpy(ctx->txfm_rd_diff, txfm_size_diff, sizeof(ctx->txfm_rd_diff));
+ } else {
+ memset(ctx->txfm_rd_diff, 0, sizeof(ctx->txfm_rd_diff));
+ }
}
static void inter_mode_cost(VP8_COMP *cpi, MACROBLOCK *x, int this_mode,
@@ -3248,11 +3278,258 @@ void setup_buffer_inter(VP8_COMP *cpi, MACROBLOCK *x, int idx, int frame_type,
#endif
}
+static int64_t handle_inter_mode(VP8_COMP *cpi, MACROBLOCK *x,
+ enum BlockSize block_size,
+ int *saddone, int near_sadidx[],
+ int mdcounts[4], int64_t txfm_cache[],
+ int *rate2, int *distortion, int *skippable,
+ int *compmode_cost,
+ int *rate_y, int *distortion_y,
+ int *rate_uv, int *distortion_uv,
+ int *mode_excluded, int *disable_skip,
+ int recon_yoffset, int mode_index,
+ int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
+ int_mv frame_best_ref_mv[4]) {
+ VP8_COMMON *cm = &cpi->common;
+ MACROBLOCKD *xd = &x->e_mbd;
+ MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
+ BLOCK *b = &x->block[0];
+ BLOCKD *d = &xd->block[0];
+ const int is_comp_pred = (mbmi->second_ref_frame != 0);
+ const int num_refs = is_comp_pred ? 2 : 1;
+ const int this_mode = mbmi->mode;
+ int i;
+ int refs[2] = { mbmi->ref_frame, mbmi->second_ref_frame };
+ int_mv cur_mv[2];
+ int_mv mvp;
+ int64_t this_rd = 0;
+
+ switch (this_mode) {
+ case NEWMV:
+ if (is_comp_pred) {
+ if (frame_mv[NEWMV][refs[0]].as_int == INVALID_MV ||
+ frame_mv[NEWMV][refs[1]].as_int == INVALID_MV)
+ return INT64_MAX;
+ *rate2 += vp8_mv_bit_cost(&frame_mv[NEWMV][refs[0]],
+ &frame_best_ref_mv[refs[0]],
+ XMVCOST, 96,
+ x->e_mbd.allow_high_precision_mv);
+ *rate2 += vp8_mv_bit_cost(&frame_mv[NEWMV][refs[1]],
+ &frame_best_ref_mv[refs[1]],
+ XMVCOST, 96,
+ x->e_mbd.allow_high_precision_mv);
+ } else {
+ int bestsme = INT_MAX;
+ int further_steps, step_param = cpi->sf.first_step;
+ int sadpb = x->sadperbit16;
+ int_mv mvp_full, tmp_mv;
+ // search range got from mv_pred(). It uses step_param levels. (0-7)
+ int sr = 0;
+
+ int tmp_col_min = x->mv_col_min;
+ int tmp_col_max = x->mv_col_max;
+ int tmp_row_min = x->mv_row_min;
+ int tmp_row_max = x->mv_row_max;
+
+ vp8_clamp_mv_min_max(x, &frame_best_ref_mv[refs[0]]);
+
+ if (!*saddone) {
+ cal_sad(cpi, xd, x, recon_yoffset, &near_sadidx[0], block_size);
+ *saddone = 1;
+ }
+
+ vp8_mv_pred(cpi, &x->e_mbd, x->e_mbd.mode_info_context, &mvp,
+ mbmi->ref_frame, cpi->common.ref_frame_sign_bias,
+ &sr, &near_sadidx[0]);
+
+ mvp_full.as_mv.col = mvp.as_mv.col >> 3;
+ mvp_full.as_mv.row = mvp.as_mv.row >> 3;
+
+ // adjust search range according to sr from mv prediction
+ step_param = MAX(step_param, sr);
+
+ // Further step/diamond searches as necessary
+ further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
+
+ bestsme = vp8_full_pixel_diamond(cpi, x, b, d, &mvp_full, step_param,
+ sadpb, further_steps, 1,
+ &cpi->fn_ptr[block_size],
+ &frame_best_ref_mv[refs[0]], &tmp_mv);
+
+ x->mv_col_min = tmp_col_min;
+ x->mv_col_max = tmp_col_max;
+ x->mv_row_min = tmp_row_min;
+ x->mv_row_max = tmp_row_max;
+
+ if (bestsme < INT_MAX) {
+ int dis; /* TODO: use dis in distortion calculation later. */
+ unsigned int sse;
+ cpi->find_fractional_mv_step(x, b, d, &tmp_mv,
+ &frame_best_ref_mv[refs[0]],
+ x->errorperbit,
+ &cpi->fn_ptr[block_size],
+ XMVCOST, &dis, &sse);
+ }
+ d->bmi.as_mv.first.as_int = tmp_mv.as_int;
+ frame_mv[NEWMV][refs[0]].as_int = d->bmi.as_mv.first.as_int;
+
+ // Add the new motion vector cost to our rolling cost variable
+ *rate2 += vp8_mv_bit_cost(&tmp_mv, &frame_best_ref_mv[refs[0]],
+ XMVCOST, 96, xd->allow_high_precision_mv);
+ }
+ break;
+ case NEARESTMV:
+ case NEARMV:
+ // Do not bother proceeding if the vector (from newmv, nearest or
+ // near) is 0,0 as this should then be coded using the zeromv mode.
+ for (i = 0; i < num_refs; ++i)
+ if (frame_mv[this_mode][refs[i]].as_int == 0)
+ return INT64_MAX;
+ case ZEROMV:
+ default:
+ break;
+ }
+ for (i = 0; i < num_refs; ++i) {
+ cur_mv[i] = frame_mv[this_mode][refs[i]];
+ // Clip "next_nearest" so that it does not extend to far out of image
+ vp8_clamp_mv2(&cur_mv[i], xd);
+ if (mv_check_bounds(x, &cur_mv[i]))
+ return INT64_MAX;
+ mbmi->mv[i].as_int = cur_mv[i].as_int;
+ }
+
+#if CONFIG_PRED_FILTER
+ // Filtered prediction:
+ mbmi->pred_filter_enabled = vp8_mode_order[mode_index].pred_filter_flag;
+ *rate2 += vp8_cost_bit(cpi->common.prob_pred_filter_off,
+ mbmi->pred_filter_enabled);
+#endif
+ if (cpi->common.mcomp_filter_type == SWITCHABLE) {
+ const int c = vp9_get_pred_context(cm, xd, PRED_SWITCHABLE_INTERP);
+ const int m = vp8_switchable_interp_map[mbmi->interp_filter];
+ *rate2 += SWITCHABLE_INTERP_RATE_FACTOR * x->switchable_interp_costs[c][m];
+ }
+
+ /* We don't include the cost of the second reference here, because there
+ * are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
+ * words if you present them in that order, the second one is always known
+ * if the first is known */
+ *compmode_cost = vp8_cost_bit(vp9_get_pred_prob(cm, xd, PRED_COMP),
+ is_comp_pred);
+ *rate2 += vp8_cost_mv_ref(cpi, this_mode, mdcounts);
+
+ if (block_size == BLOCK_16X16) {
+ vp8_build_1st_inter16x16_predictors_mby(xd, xd->predictor, 16, 0);
+ if (is_comp_pred)
+ vp8_build_2nd_inter16x16_predictors_mby(xd, xd->predictor, 16);
+ } else {
+#if CONFIG_SUPERBLOCKS
+ vp8_build_inter32x32_predictors_sb(xd,
+ xd->dst.y_buffer,
+ xd->dst.u_buffer,
+ xd->dst.v_buffer,
+ xd->dst.y_stride,
+ xd->dst.uv_stride);
+#endif
+ }
+
+ if (cpi->active_map_enabled && x->active_ptr[0] == 0)
+ x->skip = 1;
+ else if (x->encode_breakout) {
+ unsigned int sse, var;
+ int threshold = (xd->block[0].dequant[1]
+ * xd->block[0].dequant[1] >> 4);
+
+ if (threshold < x->encode_breakout)
+ threshold = x->encode_breakout;
+
+ if (block_size == BLOCK_16X16) {
+ var = vp8_variance16x16(*(b->base_src), b->src_stride,
+ xd->predictor, 16, &sse);
+ } else {
+#if CONFIG_SUPERBLOCKS
+ var = vp8_variance32x32(*(b->base_src), b->src_stride,
+ xd->dst.y_buffer, xd->dst.y_stride, &sse);
+#endif
+ }
+
+ if (sse < threshold) {
+ unsigned int q2dc = xd->block[24].dequant[0];
+ /* If there is no codeable 2nd order dc
+ or a very small uniform pixel change change */
+ if ((sse - var < q2dc * q2dc >> 4) ||
+ (sse / 2 > var && sse - var < 64)) {
+ // Check u and v to make sure skip is ok
+ int sse2;
+
+ if (block_size == BLOCK_16X16) {
+ sse2 = vp8_uvsse(x);
+ } else {
+ unsigned int sse2u, sse2v;
+ var = vp8_variance16x16(x->src.u_buffer, x->src.uv_stride,
+ xd->dst.u_buffer, xd->dst.uv_stride, &sse2u);
+ var = vp8_variance16x16(x->src.v_buffer, x->src.uv_stride,
+ xd->dst.v_buffer, xd->dst.uv_stride, &sse2v);
+ sse2 = sse2u + sse2v;
+ }
+
+ if (sse2 * 2 < threshold) {
+ x->skip = 1;
+ *distortion = sse + sse2;
+ *rate2 = 500;
+
+ /* for best_yrd calculation */
+ *rate_uv = 0;
+ *distortion_uv = sse2;
+
+ *disable_skip = 1;
+ this_rd = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
+ }
+ }
+ }
+ }
+
+ if (!x->skip) {
+ if (block_size == BLOCK_16X16) {
+ vp8_build_1st_inter16x16_predictors_mbuv(xd, &xd->predictor[256],
+ &xd->predictor[320], 8);
+ if (is_comp_pred)
+ vp8_build_2nd_inter16x16_predictors_mbuv(xd, &xd->predictor[256],
+ &xd->predictor[320], 8);
+ inter_mode_cost(cpi, x, this_mode, rate2, distortion,
+ rate_y, distortion_y, rate_uv, distortion_uv,
+ skippable, txfm_cache);
+ } else {
+#if CONFIG_SUPERBLOCKS
+ int skippable_y, skippable_uv;
+
+ // Y cost and distortion - FIXME support other transform sizes
+ super_block_yrd_8x8(x, rate_y, distortion_y,
+ IF_RTCD(&cpi->rtcd), &skippable_y);
+ *rate2 += *rate_y;
+ *distortion += *distortion_y;
+
+ rd_inter32x32_uv_8x8(cpi, x, rate_uv, distortion_uv,
+ cm->full_pixel, &skippable_uv);
+
+ *rate2 += *rate_uv;
+ *distortion += *distortion_uv;
+ *skippable = skippable_y && skippable_uv;
+#endif
+ }
+ }
+ if (is_comp_pred) {
+ *mode_excluded = (cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY);
+ } else {
+ *mode_excluded = (cpi->common.comp_pred_mode == COMP_PREDICTION_ONLY);
+ }
+
+ return this_rd; // if 0, this will be re-calculated by caller
+}
+
void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int recon_uvoffset,
int *returnrate, int *returndistortion, int64_t *returnintra) {
VP8_COMMON *cm = &cpi->common;
- BLOCK *b = &x->block[0];
- BLOCKD *d = &x->e_mbd.block[0];
MACROBLOCKD *xd = &x->e_mbd;
union b_mode_info best_bmodes[16];
MB_MODE_INFO best_mbmode;
@@ -3291,10 +3568,8 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
MB_PREDICTION_MODE uv_intra_mode;
MB_PREDICTION_MODE uv_intra_mode_8x8 = 0;
- int_mv mvp;
int near_sadidx[8] = {0, 1, 2, 3, 4, 5, 6, 7};
int saddone = 0;
- int sr = 0; // search range got from mv_pred(). It uses step_param levels. (0-7)
int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
int_mv frame_best_ref_mv[4];
@@ -3377,7 +3652,6 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
for (mode_index = 0; mode_index < MAX_MODES;
mode_index += (!switchable_filter_index)) {
int64_t this_rd = INT64_MAX;
- int is_comp_pred;
int disable_skip = 0, skippable = 0;
int other_cost = 0;
int compmode_cost = 0;
@@ -3395,7 +3669,6 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
mbmi->uv_mode = DC_PRED;
mbmi->ref_frame = vp8_mode_order[mode_index].ref_frame;
mbmi->second_ref_frame = vp8_mode_order[mode_index].second_ref_frame;
- is_comp_pred = xd->mode_info_context->mbmi.second_ref_frame != 0;
#if CONFIG_PRED_FILTER
mbmi->pred_filter_enabled = 0;
#endif
@@ -3648,6 +3921,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
// Split MV. The code is very different from the other inter modes so
// special case it.
else if (this_mode == SPLITMV) {
+ const int is_comp_pred = mbmi->second_ref_frame != 0;
int64_t tmp_rd, this_rd_thresh;
int_mv *second_ref = is_comp_pred ? &second_best_ref_mv : NULL;
@@ -3696,189 +3970,15 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
mbmi->mode = this_mode;
}
else {
- const int num_refs = is_comp_pred ? 2 : 1;
- int flag, skip;
- int refs[2] = {xd->mode_info_context->mbmi.ref_frame,
- xd->mode_info_context->mbmi.second_ref_frame};
- int_mv cur_mv[2];
- switch (this_mode) {
- case NEWMV:
- if (is_comp_pred) {
- if (frame_mv[NEWMV][refs[0]].as_int == INVALID_MV ||
- frame_mv[NEWMV][refs[1]].as_int == INVALID_MV)
- continue;
- rate2 += vp8_mv_bit_cost(&frame_mv[NEWMV][refs[0]],
- &frame_best_ref_mv[refs[0]],
- XMVCOST, 96,
- xd->allow_high_precision_mv);
- rate2 += vp8_mv_bit_cost(&frame_mv[NEWMV][refs[1]],
- &frame_best_ref_mv[refs[1]],
- XMVCOST, 96,
- xd->allow_high_precision_mv);
- } else {
- int bestsme = INT_MAX;
- int further_steps, step_param = cpi->sf.first_step;
- int sadpb = x->sadperbit16;
- int_mv mvp_full, tmp_mv;
-
- int tmp_col_min = x->mv_col_min;
- int tmp_col_max = x->mv_col_max;
- int tmp_row_min = x->mv_row_min;
- int tmp_row_max = x->mv_row_max;
-
- vp8_clamp_mv_min_max(x, &best_ref_mv);
-
- if (!saddone) {
- vp8_cal_sad(cpi, xd, x, recon_yoffset, &near_sadidx[0]);
- saddone = 1;
- }
-
- vp8_mv_pred(cpi, &x->e_mbd, xd->mode_info_context, &mvp,
- mbmi->ref_frame, cpi->common.ref_frame_sign_bias,
- &sr, &near_sadidx[0]);
-
- mvp_full.as_mv.col = mvp.as_mv.col >> 3;
- mvp_full.as_mv.row = mvp.as_mv.row >> 3;
-
- // adjust search range according to sr from mv prediction
- step_param = MAX(step_param, sr);
-
- // Further step/diamond searches as necessary
- further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
-
- bestsme = vp8_full_pixel_diamond(cpi, x, b, d, &mvp_full, step_param,
- sadpb, further_steps, 1,
- &cpi->fn_ptr[BLOCK_16X16],
- &best_ref_mv, &tmp_mv);
-
- x->mv_col_min = tmp_col_min;
- x->mv_col_max = tmp_col_max;
- x->mv_row_min = tmp_row_min;
- x->mv_row_max = tmp_row_max;
-
- if (bestsme < INT_MAX) {
- int dis; /* TODO: use dis in distortion calculation later. */
- unsigned int sse;
- cpi->find_fractional_mv_step(x, b, d, &tmp_mv, &best_ref_mv,
- x->errorperbit,
- &cpi->fn_ptr[BLOCK_16X16],
- XMVCOST, &dis, &sse);
- }
- d->bmi.as_mv.first.as_int = tmp_mv.as_int;
- frame_mv[NEWMV][refs[0]].as_int = d->bmi.as_mv.first.as_int;
-
- // Add the new motion vector cost to our rolling cost variable
- rate2 += vp8_mv_bit_cost(&tmp_mv, &best_ref_mv,
- XMVCOST, 96,
- xd->allow_high_precision_mv);
- }
- break;
- case NEARESTMV:
- case NEARMV:
- flag = 0;
- // Do not bother proceeding if the vector (from newmv, nearest or
- // near) is 0,0 as this should then be coded using the zeromv mode.
- for (i = 0; i < num_refs; ++i)
- if (frame_mv[this_mode][refs[i]].as_int == 0)
- flag = 1;
- if (flag)
- continue;
-
- case ZEROMV:
-
- default:
- break;
- }
- flag = 0;
- for (i = 0; i < num_refs; ++i) {
- cur_mv[i] = frame_mv[this_mode][refs[i]];
- // Clip "next_nearest" so that it does not extend to far out of image
- vp8_clamp_mv2(&cur_mv[i], xd);
- if (mv_check_bounds(x, &cur_mv[i]))
- flag = 1;
- xd->mode_info_context->mbmi.mv[i].as_int = cur_mv[i].as_int;
- }
- if (flag)
+ this_rd = handle_inter_mode(cpi, x, BLOCK_16X16,
+ &saddone, near_sadidx, mdcounts, txfm_cache,
+ &rate2, &distortion2, &skippable,
+ &compmode_cost, &rate_y, &distortion,
+ &rate_uv, &distortion_uv,
+ &mode_excluded, &disable_skip, recon_yoffset,
+ mode_index, frame_mv, frame_best_ref_mv);
+ if (this_rd == INT64_MAX)
continue;
-
-#if CONFIG_PRED_FILTER
- // Filtered prediction:
- xd->mode_info_context->mbmi.pred_filter_enabled =
- vp8_mode_order[mode_index].pred_filter_flag;
- rate2 += vp8_cost_bit(cpi->common.prob_pred_filter_off,
- xd->mode_info_context->mbmi.pred_filter_enabled);
-#endif
- if (cpi->common.mcomp_filter_type == SWITCHABLE)
- rate2 += SWITCHABLE_INTERP_RATE_FACTOR * x->switchable_interp_costs
- [vp9_get_pred_context(&cpi->common, xd, PRED_SWITCHABLE_INTERP)]
- [vp8_switchable_interp_map[
- xd->mode_info_context->mbmi.interp_filter]];
-
- /* We don't include the cost of the second reference here, because there are only
- * three options: Last/Golden, ARF/Last or Golden/ARF, or in other words if you
- * present them in that order, the second one is always known if the first is known */
- compmode_cost = vp8_cost_bit(vp9_get_pred_prob(cm, xd, PRED_COMP),
- is_comp_pred);
- rate2 += vp8_cost_mv_ref(cpi, this_mode, mdcounts);
-
- vp8_build_1st_inter16x16_predictors_mby(&x->e_mbd, xd->predictor,
- 16, 0);
- if (is_comp_pred)
- vp8_build_2nd_inter16x16_predictors_mby(&x->e_mbd, xd->predictor,
- 16);
-
- if (cpi->active_map_enabled && x->active_ptr[0] == 0)
- x->skip = 1;
- else if (x->encode_breakout) {
- unsigned int sse, var;
- int threshold = (xd->block[0].dequant[1]
- * xd->block[0].dequant[1] >> 4);
-
- if (threshold < x->encode_breakout)
- threshold = x->encode_breakout;
-
- var = vp8_variance16x16(*(b->base_src), b->src_stride,
- xd->predictor, 16, &sse);
-
- if (sse < threshold) {
- unsigned int q2dc = xd->block[24].dequant[0];
- /* If there is no codeable 2nd order dc
- or a very small uniform pixel change change */
- if ((sse - var < q2dc *q2dc >> 4) ||
- (sse / 2 > var && sse - var < 64)) {
- // Check u and v to make sure skip is ok
- int sse2 = vp8_uvsse(x);
- if (sse2 * 2 < threshold) {
- x->skip = 1;
- distortion2 = sse + sse2;
- rate2 = 500;
-
- /* for best_yrd calculation */
- rate_uv = 0;
- distortion_uv = sse2;
-
- disable_skip = 1;
- this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
- }
- }
- }
- }
-
- if (!x->skip) {
- vp8_build_1st_inter16x16_predictors_mbuv(&x->e_mbd, &xd->predictor[256],
- &xd->predictor[320], 8);
- if (is_comp_pred)
- vp8_build_2nd_inter16x16_predictors_mbuv(&x->e_mbd,
- &xd->predictor[256],
- &xd->predictor[320], 8);
- inter_mode_cost(cpi, x, this_mode, &rate2, &distortion2,
- &rate_y, &distortion, &rate_uv, &distortion_uv,
- &skippable, txfm_cache);
- }
- if (is_comp_pred)
- mode_excluded = cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY;
- else
- mode_excluded = cpi->common.comp_pred_mode == COMP_PREDICTION_ONLY;
}
if (cpi->common.comp_pred_mode == HYBRID_PREDICTION)
@@ -3895,9 +3995,6 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
// segment level as the cost wont have been added in.
if (cpi->common.mb_no_coeff_skip) {
int mb_skip_allowed;
- int has_y2 = (this_mode != SPLITMV
- && this_mode != B_PRED
- && this_mode != I8X8_PRED);
// Is Mb level skip allowed for this mb.
mb_skip_allowed =
@@ -4372,71 +4469,59 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
int *returnrate, int *returndistortion) {
VP8_COMMON *cm = &cpi->common;
MACROBLOCKD *xd = &x->e_mbd;
- BLOCK *b = &x->block[0];
- BLOCKD *d = &xd->block[0];
+ MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
MB_PREDICTION_MODE this_mode;
MV_REFERENCE_FRAME ref_frame;
unsigned char segment_id = xd->mode_info_context->mbmi.segment_id;
int comp_pred;
- int_mv best_ref_mv, second_best_ref_mv;
- int_mv mode_mv[MB_MODE_COUNT];
- int_mv frame_nearest_mv[4];
- int_mv frame_near_mv[4];
+ int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
int_mv frame_best_ref_mv[4];
- int_mv mc_search_result[4];
int frame_mdcounts[4][4];
unsigned char *y_buffer[4];
unsigned char *u_buffer[4];
unsigned char *v_buffer[4];
- static const int flag_list[4] = { 0, VP8_LAST_FLAG, VP8_GOLD_FLAG, VP8_ALT_FLAG };
- int idx_list[4] = { 0, cpi->common.lst_fb_idx, cpi->common.gld_fb_idx, cpi->common.alt_fb_idx };
+ static const int flag_list[4] = { 0, VP8_LAST_FLAG, VP8_GOLD_FLAG,
+ VP8_ALT_FLAG };
+ int idx_list[4] = { 0, cpi->common.lst_fb_idx, cpi->common.gld_fb_idx,
+ cpi->common.alt_fb_idx };
int mdcounts[4];
- int near_sadidx[8] = {0, 1, 2, 3, 4, 5, 6, 7};
+ int near_sadidx[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
int saddone = 0;
- int sr = 0; // search range got from mv_pred(). It uses step_param levels. (0-7)
int64_t best_rd = INT64_MAX;
int64_t best_comp_rd = INT64_MAX;
int64_t best_single_rd = INT64_MAX;
int64_t best_hybrid_rd = INT64_MAX;
int64_t best_yrd = INT64_MAX;
MB_MODE_INFO best_mbmode;
- int mode_index = 0;
+ int mode_index, best_mode_index;
unsigned int ref_costs[MAX_REF_FRAMES];
+ x->skip = 0;
xd->mode_info_context->mbmi.segment_id = segment_id;
vp8_estimate_ref_frame_costs(cpi, segment_id, ref_costs);
+ vpx_memset(&best_mbmode, 0, sizeof(best_mbmode));
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
if (cpi->ref_frame_flags & flag_list[ref_frame]) {
- YV12_BUFFER_CONFIG *ref_buf = &cpi->common.yv12_fb[idx_list[ref_frame]];
-
- vp8_find_near_mvs(xd, xd->mode_info_context,
- xd->prev_mode_info_context,
- &frame_nearest_mv[ref_frame], &frame_near_mv[ref_frame],
- &frame_best_ref_mv[ref_frame], frame_mdcounts[ref_frame],
- ref_frame, cpi->common.ref_frame_sign_bias);
-
- y_buffer[ref_frame] = ref_buf->y_buffer + recon_yoffset;
- u_buffer[ref_frame] = ref_buf->u_buffer + recon_uvoffset;
- v_buffer[ref_frame] = ref_buf->v_buffer + recon_uvoffset;
+ setup_buffer_inter(cpi, x, idx_list[ref_frame], ref_frame,
+ recon_yoffset, recon_uvoffset, frame_mv[NEARESTMV],
+ frame_mv[NEARMV], frame_best_ref_mv,
+ frame_mdcounts, y_buffer, u_buffer, v_buffer);
}
- mc_search_result[ref_frame].as_int = INVALID_MV;
+ frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
+ frame_mv[ZEROMV][ref_frame].as_int = 0;
}
for (mode_index = 0; mode_index < MAX_MODES; mode_index++) {
- int_mv mvp;
int mode_excluded;
int64_t this_rd = INT64_MAX;
int disable_skip = 0;
int other_cost = 0;
int compmode_cost = 0;
- int rate2 = 0;
- int distortion2 = 0;
- int rate_y = 0;
- int rate_uv = 0;
- int distortion_uv;
- int distortion;
- int skippable_y, skippable_uv;
+ int rate2 = 0, rate_y = 0, rate_uv = 0;
+ int distortion2 = 0, distortion_y = 0, distortion_uv = 0;
+ int skippable;
+ int64_t txfm_cache[NB_TXFM_MODES];
// Test best rd so far against threshold for trying this mode.
if (best_rd <= cpi->rd_threshes[mode_index]) {
@@ -4445,17 +4530,13 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
this_mode = vp8_mode_order[mode_index].mode;
ref_frame = vp8_mode_order[mode_index].ref_frame;
- xd->mode_info_context->mbmi.ref_frame = ref_frame;
+ mbmi->ref_frame = ref_frame;
comp_pred = vp8_mode_order[mode_index].second_ref_frame != INTRA_FRAME;
- xd->mode_info_context->mbmi.mode = this_mode;
- xd->mode_info_context->mbmi.uv_mode = DC_PRED;
-#if 0 && CONFIG_PRED_FILTER
- xd->mode_info_context->mbmi.pred_filter_enabled = 0;
-#endif
-
-#if 0 && CONFIG_COMP_INTRA_PRED
- xd->mode_info_context->mbmi.second_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
- xd->mode_info_context->mbmi.second_uv_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
+ mbmi->mode = this_mode;
+ mbmi->uv_mode = DC_PRED;
+#if CONFIG_COMP_INTRA_PRED
+ mbmi->second_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
+ mbmi->second_uv_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
#endif
if (!(cpi->ref_frame_flags & flag_list[ref_frame]))
@@ -4476,25 +4557,20 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
}
if (!(cpi->ref_frame_flags & flag_list[second_ref]))
continue;
- xd->mode_info_context->mbmi.second_ref_frame = second_ref;
+ mbmi->second_ref_frame = second_ref;
xd->second_pre.y_buffer = y_buffer[second_ref];
xd->second_pre.u_buffer = u_buffer[second_ref];
xd->second_pre.v_buffer = v_buffer[second_ref];
- second_best_ref_mv = frame_best_ref_mv[second_ref];
mode_excluded = cm->comp_pred_mode == SINGLE_PREDICTION_ONLY;
} else {
- xd->mode_info_context->mbmi.second_ref_frame = INTRA_FRAME;
+ mbmi->second_ref_frame = INTRA_FRAME;
mode_excluded = cm->comp_pred_mode == COMP_PREDICTION_ONLY;
}
xd->pre.y_buffer = y_buffer[ref_frame];
xd->pre.u_buffer = u_buffer[ref_frame];
xd->pre.v_buffer = v_buffer[ref_frame];
- mode_mv[ZEROMV].as_int = 0;
- mode_mv[NEARESTMV] = frame_nearest_mv[ref_frame];
- mode_mv[NEARMV] = frame_near_mv[ref_frame];
- best_ref_mv = frame_best_ref_mv[ref_frame];
vpx_memcpy(mdcounts, frame_mdcounts[ref_frame], sizeof(mdcounts));
// If the segment reference frame feature is enabled....
@@ -4524,342 +4600,20 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
}
}
- if (!comp_pred) {
- switch (this_mode) {
- case NEWMV: {
- int thissme;
- int bestsme = INT_MAX;
- int step_param = cpi->sf.first_step;
- int further_steps;
- int n;
- int do_refine = 1; /* If last step (1-away) of n-step search doesn't pick the center point as the best match,
- we will do a final 1-away diamond refining search */
- int num00;
-
- int sadpb = x->sadperbit16;
- int_mv mvp_full;
-
- int col_min = (best_ref_mv.as_mv.col >> 3) - MAX_FULL_PEL_VAL + ((best_ref_mv.as_mv.col & 7) ? 1 : 0);
- int row_min = (best_ref_mv.as_mv.row >> 3) - MAX_FULL_PEL_VAL + ((best_ref_mv.as_mv.row & 7) ? 1 : 0);
- int col_max = (best_ref_mv.as_mv.col >> 3) + MAX_FULL_PEL_VAL;
- int row_max = (best_ref_mv.as_mv.row >> 3) + MAX_FULL_PEL_VAL;
-
- int tmp_col_min = x->mv_col_min;
- int tmp_col_max = x->mv_col_max;
- int tmp_row_min = x->mv_row_min;
- int tmp_row_max = x->mv_row_max;
-
- if (!saddone) {
- vp8_cal_sad(cpi, xd, x, recon_yoffset, &near_sadidx[0]);
- saddone = 1;
- }
-
- vp8_mv_pred(cpi, xd, xd->mode_info_context, &mvp,
- xd->mode_info_context->mbmi.ref_frame,
- cpi->common.ref_frame_sign_bias, &sr, &near_sadidx[0]);
-
- mvp_full.as_mv.col = mvp.as_mv.col >> 3;
- mvp_full.as_mv.row = mvp.as_mv.row >> 3;
-
- // Get intersection of UMV window and valid MV window to reduce # of checks in diamond search.
- if (x->mv_col_min < col_min)
- x->mv_col_min = col_min;
- if (x->mv_col_max > col_max)
- x->mv_col_max = col_max;
- if (x->mv_row_min < row_min)
- x->mv_row_min = row_min;
- if (x->mv_row_max > row_max)
- x->mv_row_max = row_max;
-
- // adjust search range according to sr from mv prediction
- if (sr > step_param)
- step_param = sr;
-
- // Initial step/diamond search
- {
- bestsme = cpi->diamond_search_sad(x, b, d, &mvp_full, &d->bmi.as_mv.first,
- step_param, sadpb, &num00,
- &cpi->fn_ptr[BLOCK_32X32],
- XMVCOST, &best_ref_mv);
- mode_mv[NEWMV].as_int = d->bmi.as_mv.first.as_int;
-
- // Further step/diamond searches as necessary
- n = 0;
- further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
-
- n = num00;
- num00 = 0;
-
- /* If there won't be more n-step search, check to see if refining search is needed. */
- if (n > further_steps)
- do_refine = 0;
-
- while (n < further_steps) {
- n++;
-
- if (num00)
- num00--;
- else {
- thissme = cpi->diamond_search_sad(x, b, d, &mvp_full,
- &d->bmi.as_mv.first, step_param + n, sadpb, &num00,
- &cpi->fn_ptr[BLOCK_32X32],
- XMVCOST, &best_ref_mv);
-
- /* check to see if refining search is needed. */
- if (num00 > (further_steps - n))
- do_refine = 0;
-
- if (thissme < bestsme) {
- bestsme = thissme;
- mode_mv[NEWMV].as_int = d->bmi.as_mv.first.as_int;
- } else {
- d->bmi.as_mv.first.as_int = mode_mv[NEWMV].as_int;
- }
- }
- }
- }
-
- /* final 1-away diamond refining search */
- if (do_refine == 1) {
- int search_range;
-
- // It seems not a good way to set search_range. Need further investigation.
- // search_range = MAXF(abs((mvp.row>>3) - d->bmi.mv.as_mv.row), abs((mvp.col>>3) - d->bmi.mv.as_mv.col));
- search_range = 8;
-
- thissme = cpi->refining_search_sad(x, b, d, &d->bmi.as_mv.first, sadpb,
- search_range, &cpi->fn_ptr[BLOCK_32X32],
- XMVCOST, &best_ref_mv);
-
- if (thissme < bestsme) {
- bestsme = thissme;
- mode_mv[NEWMV].as_int = d->bmi.as_mv.first.as_int;
- } else {
- d->bmi.as_mv.first.as_int = mode_mv[NEWMV].as_int;
- }
- }
-
- x->mv_col_min = tmp_col_min;
- x->mv_col_max = tmp_col_max;
- x->mv_row_min = tmp_row_min;
- x->mv_row_max = tmp_row_max;
-
- if (bestsme < INT_MAX) {
- int dis; /* TODO: use dis in distortion calculation later. */
- unsigned int sse;
- cpi->find_fractional_mv_step(x, b, d, &d->bmi.as_mv.first, &best_ref_mv,
- x->errorperbit,
- &cpi->fn_ptr[BLOCK_32X32],
- XMVCOST, &dis, &sse);
- }
- mc_search_result[xd->mode_info_context->mbmi.ref_frame].as_int =
- d->bmi.as_mv.first.as_int;
-
- mode_mv[NEWMV].as_int = d->bmi.as_mv.first.as_int;
-
- // Add the new motion vector cost to our rolling cost variable
- rate2 += vp8_mv_bit_cost(&mode_mv[NEWMV], &best_ref_mv,
- XMVCOST, 96,
- xd->allow_high_precision_mv);
- }
-
- case NEARESTMV:
- case NEARMV:
- // Clip "next_nearest" so that it does not extend to far out of image
- vp8_clamp_mv2(&mode_mv[this_mode], xd);
-
- // Do not bother proceeding if the vector (from newmv,nearest or near) is 0,0 as this should then be coded using the zeromv mode.
- if (((this_mode == NEARMV) || (this_mode == NEARESTMV)) && (mode_mv[this_mode].as_int == 0)) {
- continue;
- }
-
- case ZEROMV:
- // Trap vectors that reach beyond the UMV borders
- // Note that ALL New MV, Nearest MV Near MV and Zero MV code drops through to this point
- // because of the lack of break statements in the previous two cases.
- if (((mode_mv[this_mode].as_mv.row >> 3) < x->mv_row_min) || ((mode_mv[this_mode].as_mv.row >> 3) > x->mv_row_max) ||
- ((mode_mv[this_mode].as_mv.col >> 3) < x->mv_col_min) || ((mode_mv[this_mode].as_mv.col >> 3) > x->mv_col_max)) {
- continue;
- }
-
- vp8_set_mbmode_and_mvs(x, this_mode, &mode_mv[this_mode]);
-
-#if CONFIG_PRED_FILTER
- // Filtered prediction:
- xd->mode_info_context->mbmi.pred_filter_enabled =
- vp8_mode_order[mode_index].pred_filter_flag;
- rate2 += vp8_cost_bit(cpi->common.prob_pred_filter_off,
- xd->mode_info_context->mbmi.pred_filter_enabled);
-#endif
-
- vp8_build_inter32x32_predictors_sb(xd,
- xd->dst.y_buffer,
- xd->dst.u_buffer,
- xd->dst.v_buffer,
- xd->dst.y_stride,
- xd->dst.uv_stride);
-
- compmode_cost =
- vp8_cost_bit(vp9_get_pred_prob(cm, xd, PRED_COMP), 0);
-
- if (cpi->active_map_enabled && x->active_ptr[0] == 0) {
- x->skip = 1;
- } else if (x->encode_breakout) {
- unsigned int sse;
- unsigned int var;
- int threshold = (xd->block[0].dequant[1] *
- xd->block[0].dequant[1] >> 4);
-
- if (threshold < x->encode_breakout)
- threshold = x->encode_breakout;
-
- var = vp8_variance32x32(*(b->base_src), b->src_stride,
- xd->dst.y_buffer, xd->dst.y_stride, &sse);
-
- if (sse < threshold) {
- unsigned int q2dc = xd->block[24].dequant[0];
- /* If there is no codeable 2nd order dc
- or a very small uniform pixel change change */
- if ((sse - var < q2dc *q2dc >> 4) ||
- (sse / 2 > var && sse - var < 64)) {
- // Check u and v to make sure skip is ok
- unsigned int sse2, sse3;
- var += vp8_variance16x16(x->src.u_buffer, x->src.uv_stride,
- xd->dst.u_buffer, xd->dst.uv_stride, &sse2);
- var += vp8_variance16x16(x->src.v_buffer, x->src.uv_stride,
- xd->dst.v_buffer, xd->dst.uv_stride, &sse3);
- sse2 += sse3;
- if (sse2 * 2 < threshold) {
- x->skip = 1;
- distortion2 = sse + sse2;
- rate2 = 500;
-
- /* for best_yrd calculation */
- rate_uv = 0;
- distortion_uv = sse2;
-
- disable_skip = 1;
- this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
- break;
- }
- }
- }
- }
-
- // Add in the Mv/mode cost
- rate2 += vp8_cost_mv_ref(cpi, this_mode, mdcounts);
-
- // Y cost and distortion - FIXME support other transform sizes
- super_block_yrd_8x8(x, &rate_y, &distortion,
- IF_RTCD(&cpi->rtcd), &skippable_y);
- rate2 += rate_y;
- distortion2 += distortion;
-
- rd_inter32x32_uv_8x8(cpi, x, &rate_uv, &distortion_uv,
- cpi->common.full_pixel, &skippable_uv);
-
- rate2 += rate_uv;
- distortion2 += distortion_uv;
- mode_excluded = cpi->common.comp_pred_mode == COMP_PREDICTION_ONLY;
- break;
-
- default:
- break;
- }
- } else { /* xd->mode_info_context->mbmi.second_ref_frame != 0 */
- int ref1 = xd->mode_info_context->mbmi.ref_frame;
- int ref2 = xd->mode_info_context->mbmi.second_ref_frame;
-
- mode_excluded = cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY;
- switch (this_mode) {
- case NEWMV:
- if (mc_search_result[ref1].as_int == INVALID_MV ||
- mc_search_result[ref2].as_int == INVALID_MV)
- continue;
- xd->mode_info_context->mbmi.mv[0].as_int = mc_search_result[ref1].as_int;
- xd->mode_info_context->mbmi.mv[1].as_int = mc_search_result[ref2].as_int;
- rate2 += vp8_mv_bit_cost(&mc_search_result[ref1],
- &frame_best_ref_mv[ref1],
- XMVCOST, 96,
- xd->allow_high_precision_mv);
- rate2 += vp8_mv_bit_cost(&mc_search_result[ref2],
- &frame_best_ref_mv[ref2],
- XMVCOST, 96,
- xd->allow_high_precision_mv);
- break;
- case ZEROMV:
- xd->mode_info_context->mbmi.mv[0].as_int = 0;
- xd->mode_info_context->mbmi.mv[1].as_int = 0;
- break;
- case NEARMV:
- if (frame_near_mv[ref1].as_int == 0 || frame_near_mv[ref2].as_int == 0) {
- continue;
- }
- xd->mode_info_context->mbmi.mv[0].as_int = frame_near_mv[ref1].as_int;
- xd->mode_info_context->mbmi.mv[1].as_int = frame_near_mv[ref2].as_int;
- break;
- case NEARESTMV:
- if (frame_nearest_mv[ref1].as_int == 0 || frame_nearest_mv[ref2].as_int == 0) {
- continue;
- }
- xd->mode_info_context->mbmi.mv[0].as_int = frame_nearest_mv[ref1].as_int;
- xd->mode_info_context->mbmi.mv[1].as_int = frame_nearest_mv[ref2].as_int;
- break;
- default:
- break;
- }
-
- /* Add in the Mv/mode cost */
- rate2 += vp8_cost_mv_ref(cpi, this_mode, mdcounts);
-
- vp8_clamp_mv2(&xd->mode_info_context->mbmi.mv[0], xd);
- vp8_clamp_mv2(&xd->mode_info_context->mbmi.mv[1], xd);
- if (((xd->mode_info_context->mbmi.mv[0].as_mv.row >> 3) < x->mv_row_min) ||
- ((xd->mode_info_context->mbmi.mv[0].as_mv.row >> 3) > x->mv_row_max) ||
- ((xd->mode_info_context->mbmi.mv[0].as_mv.col >> 3) < x->mv_col_min) ||
- ((xd->mode_info_context->mbmi.mv[0].as_mv.col >> 3) > x->mv_col_max) ||
- ((xd->mode_info_context->mbmi.mv[1].as_mv.row >> 3) < x->mv_row_min) ||
- ((xd->mode_info_context->mbmi.mv[1].as_mv.row >> 3) > x->mv_row_max) ||
- ((xd->mode_info_context->mbmi.mv[1].as_mv.col >> 3) < x->mv_col_min) ||
- ((xd->mode_info_context->mbmi.mv[1].as_mv.col >> 3) > x->mv_col_max)) {
- continue;
- }
-
- /* build first and second prediction */
- vp8_build_inter32x32_predictors_sb(xd, xd->dst.y_buffer,
- xd->dst.u_buffer, xd->dst.v_buffer,
- xd->dst.y_stride, xd->dst.uv_stride);
-
- /* Y cost and distortion - TODO(rbultje) support other transform sizes */
- super_block_yrd_8x8(x, &rate_y, &distortion,
- IF_RTCD(&cpi->rtcd), &skippable_y);
-
- rate2 += rate_y;
- distortion2 += distortion;
-
- /* UV cost and distortion */
- rd_inter32x32_uv_8x8(cpi, x, &rate_uv, &distortion_uv,
- cpi->common.full_pixel, &skippable_uv);
-
- rate2 += rate_uv;
- distortion2 += distortion_uv;
-
- /* don't bother w/ skip, we would never have come here if skip were
- * enabled */
- xd->mode_info_context->mbmi.mode = this_mode;
-
- /* We don't include the cost of the second reference here, because there
- * are only three options: Last/Golden, ARF/Last or Golden/ARF, or in
- * other words if you present them in that order, the second one is
- * always known if the first is known */
- compmode_cost = vp8_cost_bit(vp9_get_pred_prob(cm, xd, PRED_COMP), 1);
- }
+ this_rd = handle_inter_mode(cpi, x, BLOCK_32X32,
+ &saddone, near_sadidx, mdcounts, txfm_cache,
+ &rate2, &distortion2, &skippable,
+ &compmode_cost, &rate_y, &distortion_y,
+ &rate_uv, &distortion_uv,
+ &mode_excluded, &disable_skip, recon_yoffset,
+ mode_index, frame_mv, frame_best_ref_mv);
+ if (this_rd == INT64_MAX)
+ continue;
if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) {
rate2 += compmode_cost;
}
-
// Estimate the reference frame signaling cost and add it
// to the rolling cost variable.
rate2 += ref_costs[xd->mode_info_context->mbmi.ref_frame];
@@ -4870,7 +4624,6 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
// necessary adjustment for rate. Ignore if skip is coded at
// segment level as the cost wont have been added in.
if (cpi->common.mb_no_coeff_skip) {
- int mb_skippable = skippable_y && skippable_uv;
int mb_skip_allowed;
// Is Mb level skip allowed for this mb.
@@ -4878,7 +4631,7 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
!segfeature_active(xd, segment_id, SEG_LVL_EOB) ||
get_segdata(xd, segment_id, SEG_LVL_EOB);
- if (mb_skippable) {
+ if (skippable) {
// Back out the coefficient coding costs
rate2 -= (rate_y + rate_uv);
// for best_yrd calculation
@@ -4932,10 +4685,10 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
// Did this mode help.. i.e. is it the new best mode
if (this_rd < best_rd || x->skip) {
if (!mode_excluded) {
-#if 0
// Note index of best mode so far
best_mode_index = mode_index;
+#if 0
if (this_mode <= B_PRED) {
xd->mode_info_context->mbmi.uv_mode = uv_intra_mode_8x8;
/* required for left and above block mv */
@@ -4952,7 +4705,7 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
*returnrate = rate2;
*returndistortion = distortion2;
best_rd = this_rd;
- vpx_memcpy(&best_mbmode, &xd->mode_info_context->mbmi, sizeof(MB_MODE_INFO));
+ vpx_memcpy(&best_mbmode, mbmi, sizeof(MB_MODE_INFO));
}
#if 0
// Testing this mode gave rise to an improvement in best error score. Lower threshold a bit for next time
@@ -4973,7 +4726,7 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
}
/* keep record of best compound/single-only prediction */
- if (!disable_skip && xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME) {
+ if (!disable_skip && mbmi->ref_frame != INTRA_FRAME) {
int single_rd, hybrid_rd, single_rate, hybrid_rate;
if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) {
@@ -4987,10 +4740,9 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
- if (xd->mode_info_context->mbmi.second_ref_frame == INTRA_FRAME &&
- single_rd < best_single_rd) {
+ if (mbmi->second_ref_frame == INTRA_FRAME && single_rd < best_single_rd) {
best_single_rd = single_rd;
- } else if (xd->mode_info_context->mbmi.second_ref_frame != INTRA_FRAME &&
+ } else if (mbmi->second_ref_frame != INTRA_FRAME &&
single_rd < best_comp_rd) {
best_comp_rd = single_rd;
}
@@ -5027,36 +4779,37 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
cpi->is_src_frame_alt_ref &&
(cpi->oxcf.arnr_max_frames == 0) &&
(best_mbmode.mode != ZEROMV || best_mbmode.ref_frame != ALTREF_FRAME)) {
- xd->mode_info_context->mbmi.mode = ZEROMV;
- xd->mode_info_context->mbmi.ref_frame = ALTREF_FRAME;
- xd->mode_info_context->mbmi.mv[0].as_int = 0;
- xd->mode_info_context->mbmi.uv_mode = DC_PRED;
- xd->mode_info_context->mbmi.mb_skip_coeff =
- (cpi->common.mb_no_coeff_skip) ? 1 : 0;
- xd->mode_info_context->mbmi.partitioning = 0;
-
- xd->mode_info_context->mbmi.txfm_size = TX_8X8;
+ mbmi->mode = ZEROMV;
+ mbmi->ref_frame = ALTREF_FRAME;
+ mbmi->second_ref_frame = 0;
+ mbmi->mv[0].as_int = 0;
+ mbmi->uv_mode = DC_PRED;
+ mbmi->mb_skip_coeff = (cpi->common.mb_no_coeff_skip) ? 1 : 0;
+ mbmi->partitioning = 0;
+ mbmi->txfm_size = TX_8X8;
if (best_rd != INT64_MAX)
- store_coding_context(x, &x->sb_context[0], mode_index, NULL,
- &frame_best_ref_mv[xd->mode_info_context->mbmi.ref_frame],
- &frame_best_ref_mv[xd->mode_info_context->mbmi.second_ref_frame],
- 0, 0, 0, NULL);
+ store_coding_context(x, &x->sb_context[0], best_mode_index, NULL,
+ &frame_best_ref_mv[mbmi->ref_frame],
+ &frame_best_ref_mv[mbmi->second_ref_frame],
+ 0, 0, 0, NULL);
return best_rd;
}
// macroblock modes
- vpx_memcpy(&xd->mode_info_context->mbmi, &best_mbmode,
- sizeof(MB_MODE_INFO));
- xd->mode_info_context->mbmi.txfm_size = TX_8X8;
+ vpx_memcpy(mbmi, &best_mbmode, sizeof(MB_MODE_INFO));
+ mbmi->txfm_size = TX_8X8;
if (best_rd != INT64_MAX)
- store_coding_context(x, &x->sb_context[0], mode_index, NULL,
- &frame_best_ref_mv[xd->mode_info_context->mbmi.ref_frame],
- &frame_best_ref_mv[xd->mode_info_context->mbmi.second_ref_frame],
- (best_single_rd == INT64_MAX) ? INT_MIN : (best_rd - best_single_rd),
- (best_comp_rd == INT64_MAX) ? INT_MIN : (best_rd - best_comp_rd),
- (best_hybrid_rd == INT64_MAX) ? INT_MIN : (best_rd - best_hybrid_rd),
+ store_coding_context(x, &x->sb_context[0], best_mode_index, NULL,
+ &frame_best_ref_mv[mbmi->ref_frame],
+ &frame_best_ref_mv[mbmi->second_ref_frame],
+ (best_single_rd == INT64_MAX) ? INT_MIN :
+ (best_rd - best_single_rd),
+ (best_comp_rd == INT64_MAX) ? INT_MIN :
+ (best_rd - best_comp_rd),
+ (best_hybrid_rd == INT64_MAX) ? INT_MIN :
+ (best_rd - best_hybrid_rd),
NULL);
return best_rd;
diff --git a/vp8/encoder/rdopt.h b/vp8/encoder/rdopt.h
index 448a70244..0495037eb 100644
--- a/vp8/encoder/rdopt.h
+++ b/vp8/encoder/rdopt.h
@@ -32,7 +32,6 @@ extern void vp8_mv_pred
int *sr,
int near_sadidx[]
);
-extern void vp8_cal_sad(VP8_COMP *cpi, MACROBLOCKD *xd, MACROBLOCK *x, int recon_yoffset, int near_sadidx[]);
extern void vp8_init_me_luts();
extern void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv);
#endif
diff --git a/vp8/encoder/segmentation.c b/vp8/encoder/segmentation.c
index fea816ca2..f6f3f3110 100644
--- a/vp8/encoder/segmentation.c
+++ b/vp8/encoder/segmentation.c
@@ -164,6 +164,7 @@ void choose_segmap_coding_method(VP8_COMP *cpi) {
VP8_COMMON *const cm = &cpi->common;
MACROBLOCKD *const xd = &cpi->mb.e_mbd;
+ const int mis = cm->mode_info_stride;
int i;
int tot_count;
int no_pred_cost;
@@ -212,8 +213,27 @@ void choose_segmap_coding_method(VP8_COMP *cpi) {
goto end;
}
+ xd->mb_to_top_edge = -((mb_row * 16) << 3);
+ xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;
+ xd->mb_to_left_edge = -((mb_col * 16) << 3);
+ xd->mb_to_right_edge = ((cm->mb_cols - 1 - mb_row) * 16) << 3;
+
segmap_index = (mb_row + y_idx) * cm->mb_cols + mb_col + x_idx;
segment_id = xd->mode_info_context->mbmi.segment_id;
+#if CONFIG_SUPERBLOCKS
+ if (xd->mode_info_context->mbmi.encoded_as_sb) {
+ if (mb_col + 1 < cm->mb_cols)
+ segment_id = segment_id &&
+ xd->mode_info_context[1].mbmi.segment_id;
+ if (mb_row + 1 < cm->mb_rows) {
+ segment_id = segment_id &&
+ xd->mode_info_context[mis].mbmi.segment_id;
+ if (mb_col + 1 < cm->mb_cols)
+ segment_id = segment_id &&
+ xd->mode_info_context[mis + 1].mbmi.segment_id;
+ }
+ }
+#endif
// Count the number of hits on each segment with no prediction
no_pred_segcounts[segment_id]++;
@@ -222,7 +242,7 @@ void choose_segmap_coding_method(VP8_COMP *cpi) {
if (cm->frame_type != KEY_FRAME) {
// Test to see if the segment id matches the predicted value.
int seg_predicted =
- (segment_id == vp9_get_pred_mb_segid(cm, segmap_index));
+ (segment_id == vp9_get_pred_mb_segid(cm, xd, segmap_index));
// Get the segment id prediction context
pred_context =