Commit 7944b4f2 authored by Ronald S. Bultje's avatar Ronald S. Bultje
Browse files

Fix superblock experiment.

Also merge some duplicate code related to the superblock experiment
in the RD loop.

Change-Id: Ic93f1d4d1ed81220fd7ecf6e65da2821a215b2de
parent 1758dc03
......@@ -219,14 +219,22 @@ unsigned char vp9_get_pred_flag(const MACROBLOCKD *const xd,
void vp9_set_pred_flag(MACROBLOCKD *const xd,
PRED_ID pred_id,
unsigned char pred_flag) {
#if CONFIG_SUPERBLOCKS
const int mis = xd->mode_info_stride;
#endif
switch (pred_id) {
case PRED_SEG_ID:
xd->mode_info_context->mbmi.seg_id_predicted = pred_flag;
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
xd->mode_info_context[1].mbmi.seg_id_predicted = pred_flag;
xd->mode_info_context[xd->mode_info_stride].mbmi.seg_id_predicted = pred_flag;
xd->mode_info_context[xd->mode_info_stride+1].mbmi.seg_id_predicted = pred_flag;
if (xd->mb_to_right_edge > 0)
xd->mode_info_context[1].mbmi.seg_id_predicted = pred_flag;
if (xd->mb_to_bottom_edge > 0) {
xd->mode_info_context[mis].mbmi.seg_id_predicted = pred_flag;
if (xd->mb_to_right_edge > 0)
xd->mode_info_context[mis + 1].mbmi.seg_id_predicted = pred_flag;
}
}
#endif
break;
......@@ -235,15 +243,30 @@ void vp9_set_pred_flag(MACROBLOCKD *const xd,
xd->mode_info_context->mbmi.ref_predicted = pred_flag;
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
xd->mode_info_context[1].mbmi.ref_predicted = pred_flag;
xd->mode_info_context[xd->mode_info_stride].mbmi.ref_predicted = pred_flag;
xd->mode_info_context[xd->mode_info_stride+1].mbmi.ref_predicted = pred_flag;
if (xd->mb_to_right_edge > 0)
xd->mode_info_context[1].mbmi.ref_predicted = pred_flag;
if (xd->mb_to_bottom_edge > 0) {
xd->mode_info_context[mis].mbmi.ref_predicted = pred_flag;
if (xd->mb_to_right_edge > 0)
xd->mode_info_context[mis + 1].mbmi.ref_predicted = pred_flag;
}
}
#endif
break;
case PRED_MBSKIP:
xd->mode_info_context->mbmi.mb_skip_coeff = pred_flag;
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
if (xd->mb_to_right_edge > 0)
xd->mode_info_context[1].mbmi.mb_skip_coeff = pred_flag;
if (xd->mb_to_bottom_edge > 0) {
xd->mode_info_context[mis].mbmi.mb_skip_coeff = pred_flag;
if (xd->mb_to_right_edge > 0)
xd->mode_info_context[mis + 1].mbmi.mb_skip_coeff = pred_flag;
}
}
#endif
break;
default:
......@@ -257,10 +280,29 @@ 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 VP8_COMMON *const cm, int MbIndex) {
unsigned char vp9_get_pred_mb_segid(const VP8_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.
return cm->last_frame_seg_map[MbIndex];
#if CONFIG_SUPERBLOCKS
if (!xd->mode_info_context->mbmi.encoded_as_sb) {
#endif
return cm->last_frame_seg_map[MbIndex];
#if CONFIG_SUPERBLOCKS
} else {
int seg_id = cm->last_frame_seg_map[MbIndex];
int mb_col = MbIndex % cm->mb_cols;
int mb_row = MbIndex / cm->mb_cols;
if (mb_col + 1 < cm->mb_cols)
seg_id = seg_id && cm->last_frame_seg_map[MbIndex + 1];
if (mb_row + 1 < cm->mb_rows) {
seg_id = seg_id && cm->last_frame_seg_map[MbIndex + cm->mb_cols];
if (mb_col + 1 < cm->mb_cols)
seg_id = seg_id && cm->last_frame_seg_map[MbIndex + cm->mb_cols + 1];
}
return seg_id;
}
#endif
}
MV_REFERENCE_FRAME vp9_get_pred_ref(const VP8_COMMON *const cm,
......
......@@ -46,6 +46,7 @@ extern void vp9_set_pred_flag(MACROBLOCKD *const xd,
extern unsigned char vp9_get_pred_mb_segid(const VP8_COMMON *const cm,
const MACROBLOCKD *const xd,
int MbIndex);
extern MV_REFERENCE_FRAME vp9_get_pred_ref(const VP8_COMMON *const cm,
......
......@@ -188,6 +188,11 @@ static void kfread_modes(VP8D_COMP *pbi,
m->mbmi.second_uv_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
#endif
#if CONFIG_SUPERBLOCKS
if (m->mbmi.encoded_as_sb)
m->mbmi.txfm_size = TX_8X8;
else
#endif
if (cm->txfm_mode == TX_MODE_SELECT && m->mbmi.mb_skip_coeff == 0 &&
m->mbmi.mode <= I8X8_PRED) {
// FIXME(rbultje) code ternary symbol once all experiments are merged
......@@ -589,7 +594,7 @@ static void read_mb_segment_id(VP8D_COMP *pbi,
// If the value is flagged as correctly predicted
// then use the predicted value
if (seg_pred_flag) {
mbmi->segment_id = vp9_get_pred_mb_segid(cm, index);
mbmi->segment_id = vp9_get_pred_mb_segid(cm, xd, index);
}
// Else .... decode it explicitly
else {
......@@ -602,10 +607,14 @@ static void read_mb_segment_id(VP8D_COMP *pbi,
}
#if CONFIG_SUPERBLOCKS
if (mbmi->encoded_as_sb) {
cm->last_frame_seg_map[index] =
cm->last_frame_seg_map[index + 1] =
cm->last_frame_seg_map[index + cm->mb_cols] =
cm->last_frame_seg_map[index + cm->mb_cols + 1] = mbmi->segment_id;
cm->last_frame_seg_map[index] = mbmi->segment_id;
if (mb_col + 1 < cm->mb_cols)
cm->last_frame_seg_map[index + 1] = mbmi->segment_id;
if (mb_row + 1 < cm->mb_rows) {
cm->last_frame_seg_map[index + cm->mb_cols] = mbmi->segment_id;
if (mb_col + 1 < cm->mb_cols)
cm->last_frame_seg_map[index + cm->mb_cols + 1] = mbmi->segment_id;
}
} else
#endif
{
......@@ -614,11 +623,17 @@ static void read_mb_segment_id(VP8D_COMP *pbi,
} else {
#if CONFIG_SUPERBLOCKS
if (mbmi->encoded_as_sb) {
mbmi->segment_id =
cm->last_frame_seg_map[index] &&
cm->last_frame_seg_map[index + 1] &&
cm->last_frame_seg_map[index + cm->mb_cols] &&
cm->last_frame_seg_map[index + cm->mb_cols + 1];
mbmi->segment_id = cm->last_frame_seg_map[index];
if (mb_col < cm->mb_cols - 1)
mbmi->segment_id = mbmi->segment_id &&
cm->last_frame_seg_map[index + 1];
if (mb_row < cm->mb_rows - 1) {
mbmi->segment_id = mbmi->segment_id &&
cm->last_frame_seg_map[index + cm->mb_cols];
if (mb_col < cm->mb_cols - 1)
mbmi->segment_id = mbmi->segment_id &&
cm->last_frame_seg_map[index + cm->mb_cols + 1];
}
} else
#endif
{
......@@ -1131,6 +1146,11 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
#endif
}
#if CONFIG_SUPERBLOCKS
if (mbmi->encoded_as_sb)
mbmi->txfm_size = TX_8X8;
else
#endif
if (cm->txfm_mode == TX_MODE_SELECT && mbmi->mb_skip_coeff == 0 &&
((mbmi->ref_frame == INTRA_FRAME && mbmi->mode <= I8X8_PRED) ||
(mbmi->ref_frame != INTRA_FRAME && !(mbmi->mode == SPLITMV &&
......
......@@ -202,7 +202,7 @@ static void skip_recon_mb(VP8D_COMP *pbi, MACROBLOCKD *xd) {
}
static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
unsigned int mb_col,
int mb_row, unsigned int mb_col,
BOOL_DECODER* const bc) {
int eobtotal = 0;
MB_PREDICTION_MODE mode;
......@@ -218,24 +218,23 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
if (xd->segmentation_enabled)
mb_init_dequantizer(pbi, xd);
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
xd->mode_info_context->mbmi.txfm_size = TX_8X8;
}
#endif
tx_size = xd->mode_info_context->mbmi.txfm_size;
mode = xd->mode_info_context->mbmi.mode;
if (xd->mode_info_context->mbmi.mb_skip_coeff) {
vp8_reset_mb_tokens_context(xd);
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
xd->above_context++;
xd->left_context++;
if (xd->mode_info_context->mbmi.encoded_as_sb &&
(mb_col < pc->mb_cols - 1 || mb_row < pc->mb_rows - 1)) {
if (mb_col < pc->mb_cols - 1)
xd->above_context++;
if (mb_row < pc->mb_rows - 1)
xd->left_context++;
vp8_reset_mb_tokens_context(xd);
xd->above_context--;
xd->left_context--;
if (mb_col < pc->mb_cols - 1)
xd->above_context--;
if (mb_row < pc->mb_rows - 1)
xd->left_context--;
}
#endif
} else if (!vp8dx_bool_error(bc)) {
......@@ -411,6 +410,11 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
void *orig = xd->mode_info_context;
int n, num = xd->mode_info_context->mbmi.encoded_as_sb ? 4 : 1;
for (n = 0; n < num; n++) {
int x_idx = n & 1, y_idx = n >> 1;
if (num == 4 && (mb_col + x_idx >= pc->mb_cols ||
mb_row + y_idx >= pc->mb_rows))
continue;
if (n != 0) {
for (i = 0; i < 25; i++) {
xd->block[i].eob = 0;
......@@ -653,20 +657,17 @@ decode_sb_row(VP8D_COMP *pbi, VP8_COMMON *pc, int mbrow, MACROBLOCKD *xd,
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
mi[1] = mi[0];
mi[pc->mode_info_stride] = mi[0];
mi[pc->mode_info_stride + 1] = mi[0];
if (mb_col < pc->mb_cols - 1)
mi[1] = mi[0];
if (mb_row < pc->mb_rows - 1) {
mi[pc->mode_info_stride] = mi[0];
if (mb_col < pc->mb_cols - 1)
mi[pc->mode_info_stride + 1] = mi[0];
}
}
#endif
vp8_intra_prediction_down_copy(xd);
decode_macroblock(pbi, xd, mb_col, bc);
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
mi[1].mbmi.txfm_size = mi[0].mbmi.txfm_size;
mi[pc->mode_info_stride].mbmi.txfm_size = mi[0].mbmi.txfm_size;
mi[pc->mode_info_stride + 1].mbmi.txfm_size = mi[0].mbmi.txfm_size;
}
#endif
decode_macroblock(pbi, xd, mb_row, mb_col, bc);
/* check if the boolean decoder has suffered an error */
xd->corrupted |= vp8dx_bool_error(bc);
......
......@@ -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))) {
......
......@@ -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;
......
......@@ -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
{
......
......@@ -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,
......
......@@ -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]],