Commit d1cad9c3 authored by Yue Chen's avatar Yue Chen

Overlapped block motion compensation experiment

In this experiment, an obmc inter prediction mode is enabled for
>= 8X8 inter blocks. When the obmc flag is on, the regular block-
based motion compensation will be refined by using predictors of
the above and left blocks.
Fixed some compatibility issues with vp9_highbitdepth, supertx,
ref_mv, and ext_interp.

Coding gain (%) on derflr/hevcmr/hevchd
OBMC:
1.047/1.022/0.708
OBMC + SUPERTX:
1.652/1.616/1.137
SUPERTX:
0.862/0.779/0.630

Change-Id: I5d8d3c4729c6d3ccb03ec7034563107893103b7f
parent a45d5d3f
......@@ -167,6 +167,10 @@ typedef struct {
INTRA_FILTER intra_filter;
#endif // CONFIG_EXT_INTRA
#if CONFIG_OBMC
int8_t obmc;
#endif // CONFIG_OBMC
int_mv mv[2];
int_mv pred_mv[2];
#if CONFIG_REF_MV
......@@ -192,6 +196,12 @@ static INLINE int has_second_ref(const MB_MODE_INFO *mbmi) {
return mbmi->ref_frame[1] > INTRA_FRAME;
}
#if CONFIG_OBMC
static INLINE int is_obmc_allowed(const MB_MODE_INFO *mbmi) {
return (mbmi->sb_type >= BLOCK_8X8);
}
#endif // CONFIG_OBMC
PREDICTION_MODE vp10_left_block_mode(const MODE_INFO *cur_mi,
const MODE_INFO *left_mi, int b);
......
......@@ -228,6 +228,12 @@ static const vpx_prob default_inter_compound_mode_probs
};
#endif // CONFIG_EXT_INTER
#if CONFIG_OBMC
static const vpx_prob default_obmc_prob[BLOCK_SIZES] = {
255, 255, 255, 151, 153, 144, 178, 165, 160, 207, 195, 168, 244,
};
#endif // CONFIG_OBMC
/* Array indices are identical to previously-existing INTRAMODECONTEXTNODES. */
const vpx_tree_index vp10_intra_mode_tree[TREE_SIZE(INTRA_MODES)] = {
-DC_PRED, 2, /* 0 = DC_NODE */
......@@ -1303,6 +1309,9 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
#endif // CONFIG_EXT_INTER
#endif // CONFIG_REF_MV
vp10_copy(fc->inter_mode_probs, default_inter_mode_probs);
#if CONFIG_OBMC
vp10_copy(fc->obmc_prob, default_obmc_prob);
#endif // CONFIG_OBMC
#if CONFIG_EXT_INTER
vp10_copy(fc->inter_compound_mode_probs, default_inter_compound_mode_probs);
#endif // CONFIG_EXT_INTER
......@@ -1383,6 +1392,12 @@ void vp10_adapt_inter_frame_probs(VP10_COMMON *cm) {
counts->inter_mode[i], fc->inter_mode_probs[i]);
#endif
#if CONFIG_OBMC
for (i = BLOCK_8X8; i < BLOCK_SIZES; ++i)
fc->obmc_prob[i] = mode_mv_merge_probs(pre_fc->obmc_prob[i],
counts->obmc[i]);
#endif // CONFIG_OBMC
#if CONFIG_SUPERTX
for (i = 0; i < PARTITION_SUPERTX_CONTEXTS; ++i) {
int j;
......
......@@ -81,6 +81,9 @@ typedef struct frame_contexts {
vpx_prob inter_compound_mode_probs[INTER_MODE_CONTEXTS]
[INTER_COMPOUND_MODES - 1];
#endif // CONFIG_EXT_INTER
#if CONFIG_OBMC
vpx_prob obmc_prob[BLOCK_SIZES];
#endif // CONFIG_OBMC
vpx_prob intra_inter_prob[INTRA_INTER_CONTEXTS];
vpx_prob comp_inter_prob[COMP_INTER_CONTEXTS];
vpx_prob single_ref_prob[REF_CONTEXTS][SINGLE_REFS-1];
......@@ -135,6 +138,9 @@ typedef struct FRAME_COUNTS {
#if CONFIG_EXT_INTER
unsigned int inter_compound_mode[INTER_MODE_CONTEXTS][INTER_COMPOUND_MODES];
#endif // CONFIG_EXT_INTER
#if CONFIG_OBMC
unsigned int obmc[BLOCK_SIZES][2];
#endif // CONFIG_OBMC
unsigned int intra_inter[INTRA_INTER_CONTEXTS][2];
unsigned int comp_inter[COMP_INTER_CONTEXTS][2];
unsigned int single_ref[REF_CONTEXTS][SINGLE_REFS-1][2];
......
This diff is collapsed.
......@@ -177,7 +177,11 @@ static INLINE MV average_split_mvs(const struct macroblockd_plane *pd,
return res;
}
void build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
void build_inter_predictors(MACROBLOCKD *xd, int plane,
#if CONFIG_OBMC
int mi_col_offset, int mi_row_offset,
#endif // CONFIG_OBMC
int block,
int bw, int bh,
int x, int y, int w, int h,
int mi_x, int mi_y);
......@@ -352,6 +356,19 @@ static INLINE int vp10_is_interp_needed(const MACROBLOCKD *const xd) {
return !intpel_mv;
}
#endif // CONFIG_EXT_INTERP
#if CONFIG_OBMC
void vp10_build_obmc_inter_prediction(VP10_COMMON *cm,
MACROBLOCKD *xd, int mi_row, int mi_col,
int use_tmp_dst_buf,
uint8_t *final_buf[MAX_MB_PLANE],
int final_stride[MAX_MB_PLANE],
uint8_t *tmp_buf1[MAX_MB_PLANE],
int tmp_stride1[MAX_MB_PLANE],
uint8_t *tmp_buf2[MAX_MB_PLANE],
int tmp_stride2[MAX_MB_PLANE]);
#endif // CONFIG_OBMC
#ifdef __cplusplus
} // extern "C"
#endif
......
This diff is collapsed.
......@@ -778,6 +778,24 @@ static void read_ref_frames(VP10_COMMON *const cm, MACROBLOCKD *const xd,
}
#if CONFIG_OBMC
static int read_is_obmc_block(VP10_COMMON *const cm, MACROBLOCKD *const xd,
vpx_reader *r) {
BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
FRAME_COUNTS *counts = xd->counts;
int is_obmc;
if (is_obmc_allowed(&xd->mi[0]->mbmi)) {
is_obmc = vpx_read(r, cm->fc->obmc_prob[bsize]);
if (counts)
++counts->obmc[bsize][is_obmc];
return is_obmc;
} else {
return 0;
}
}
#endif // CONFIG_OBMC
static INLINE INTERP_FILTER read_switchable_interp_filter(
VP10_COMMON *const cm, MACROBLOCKD *const xd,
vpx_reader *r) {
......@@ -1016,7 +1034,12 @@ static void fpm_sync(void *const data, int mi_row) {
static void read_inter_block_mode_info(VP10Decoder *const pbi,
MACROBLOCKD *const xd,
MODE_INFO *const mi,
#if CONFIG_OBMC && CONFIG_SUPERTX
int mi_row, int mi_col, vpx_reader *r,
int supertx_enabled) {
#else
int mi_row, int mi_col, vpx_reader *r) {
#endif // CONFIG_OBMC && CONFIG_SUPERTX
VP10_COMMON *const cm = &pbi->common;
MB_MODE_INFO *const mbmi = &mi->mbmi;
const BLOCK_SIZE bsize = mbmi->sb_type;
......@@ -1062,6 +1085,13 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
mi_row, mi_col, fpm_sync, (void *)pbi, inter_mode_ctx);
}
#if CONFIG_OBMC
#if CONFIG_SUPERTX
if (!supertx_enabled)
#endif // CONFIG_SUPERTX
mbmi->obmc = read_is_obmc_block(cm, xd, r);
#endif // CONFIG_OBMC
#if CONFIG_REF_MV
#if CONFIG_EXT_INTER
if (is_compound)
......@@ -1365,14 +1395,19 @@ static void read_inter_frame_mode_info(VP10Decoder *const pbi,
xd->mi[0]->mbmi.tx_size = xd->supertx_size;
for (idy = 0; idy < height; ++idy)
for (idx = 0; idx < width; ++idx)
xd->mi[0]->mbmi.inter_tx_size[(idy >> 1) * 8 + (idx >> 1)] = xd->supertx_size;
xd->mi[0]->mbmi.inter_tx_size[(idy >> 1) * 8 + (idx >> 1)] =
xd->supertx_size;
}
#endif // CONFIG_VAR_TX
#endif // CONFIG_SUPERTX
if (inter_block)
read_inter_block_mode_info(pbi, xd,
#if CONFIG_OBMC && CONFIG_SUPERTX
mi, mi_row, mi_col, r, supertx_enabled);
#else
mi, mi_row, mi_col, r);
#endif // CONFIG_OBMC && CONFIG_SUPERTX
else
read_intra_block_mode_info(cm, xd, mi, r);
......
......@@ -995,6 +995,13 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
} else {
int16_t mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
write_ref_frames(cm, xd, w);
#if CONFIG_OBMC
#if CONFIG_SUPERTX
if (!supertx_enabled)
#endif // CONFIG_SUPERTX
if (is_obmc_allowed(mbmi))
vpx_write(w, mbmi->obmc, cm->fc->obmc_prob[bsize]);
#endif // CONFIG_OBMC
#if CONFIG_REF_MV
#if CONFIG_EXT_INTER
......@@ -2395,6 +2402,12 @@ static size_t write_compressed_header(VP10_COMP *cpi, uint8_t *data) {
update_inter_compound_mode_probs(cm, &header_bc);
#endif // CONFIG_EXT_INTER
#if CONFIG_OBMC
for (i = BLOCK_8X8; i < BLOCK_SIZES; ++i)
vp10_cond_prob_diff_update(&header_bc, &fc->obmc_prob[i],
counts->obmc[i]);
#endif // CONFIG_OBMC
if (cm->interp_filter == SWITCHABLE)
update_switchable_interp_probs(cm, &header_bc, counts);
......
......@@ -1801,6 +1801,13 @@ static void update_stats(VP10_COMMON *cm, ThreadData *td
[ref0 != GOLDEN_FRAME]++;
#endif // CONFIG_EXT_REFS
}
#if CONFIG_OBMC
#if CONFIG_SUPERTX
if (!supertx_enabled)
#endif // CONFIG_SUPERTX
if (is_obmc_allowed(mbmi))
counts->obmc[mbmi->sb_type][mbmi->obmc]++;
#endif // CONFIG_OBMC
}
}
if (inter_block &&
......@@ -4421,6 +4428,55 @@ static void encode_superblock(VP10_COMP *cpi, ThreadData *td,
vp10_build_inter_predictors_sbuv(xd, mi_row, mi_col,
VPXMAX(bsize, BLOCK_8X8));
#if CONFIG_OBMC
if (mbmi->obmc) {
#if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * 64 * 64]);
DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * 64 * 64]);
#else
DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * 64 * 64]);
DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * 64 * 64]);
#endif // CONFIG_VP9_HIGHBITDEPTH
uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
int dst_stride1[MAX_MB_PLANE] = {64, 64, 64};
int dst_stride2[MAX_MB_PLANE] = {64, 64, 64};
assert(mbmi->sb_type >= BLOCK_8X8);
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
int len = sizeof(uint16_t);
dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + 4096 * len);
dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 8192 * len);
dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + 4096 * len);
dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 8192 * len);
} else {
#endif // CONFIG_VP9_HIGHBITDEPTH
dst_buf1[0] = tmp_buf1;
dst_buf1[1] = tmp_buf1 + 4096;
dst_buf1[2] = tmp_buf1 + 8192;
dst_buf2[0] = tmp_buf2;
dst_buf2[1] = tmp_buf2 + 4096;
dst_buf2[2] = tmp_buf2 + 8192;
#if CONFIG_VP9_HIGHBITDEPTH
}
#endif // CONFIG_VP9_HIGHBITDEPTH
vp10_build_prediction_by_above_preds(cpi, xd, mi_row, mi_col, dst_buf1,
dst_stride1);
vp10_build_prediction_by_left_preds(cpi, xd, mi_row, mi_col, dst_buf2,
dst_stride2);
vp10_setup_dst_planes(xd->plane, get_frame_new_buffer(cm),
mi_row, mi_col);
vp10_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, 0, NULL, NULL,
dst_buf1, dst_stride1,
dst_buf2, dst_stride2);
}
#endif // CONFIG_OBMC
vp10_encode_sb(x, VPXMAX(bsize, BLOCK_8X8));
#if CONFIG_VAR_TX
vp10_tokenize_sb_inter(cpi, td, t, !output_enabled,
......
......@@ -479,6 +479,9 @@ typedef struct VP10_COMP {
unsigned int inter_compound_mode_cost[INTER_MODE_CONTEXTS]
[INTER_COMPOUND_MODES];
#endif // CONFIG_EXT_INTER
#if CONFIG_OBMC
int obmc_cost[BLOCK_SIZES][2];
#endif // CONFIG_OBMC
int intra_uv_mode_cost[INTRA_MODES][INTRA_MODES];
int y_mode_costs[INTRA_MODES][INTRA_MODES][INTRA_MODES];
int switchable_interp_costs[SWITCHABLE_FILTER_CONTEXTS][SWITCHABLE_FILTERS];
......
......@@ -405,6 +405,12 @@ void vp10_initialize_rd_consts(VP10_COMP *cpi) {
cm->fc->inter_compound_mode_probs[i],
vp10_inter_compound_mode_tree);
#endif // CONFIG_EXT_INTER
#if CONFIG_OBMC
for (i = BLOCK_8X8; i < BLOCK_SIZES; i++) {
cpi->obmc_cost[i][0] = vp10_cost_bit(cm->fc->obmc_prob[i], 0);
cpi->obmc_cost[i][1] = vp10_cost_bit(cm->fc->obmc_prob[i], 1);
}
#endif // CONFIG_OBMC
}
}
......
This diff is collapsed.
......@@ -89,6 +89,18 @@ void vp10_txfm_rd_in_plane_supertx(MACROBLOCK *x,
int use_fast_coef_casting);
#endif // CONFIG_SUPERTX
#if CONFIG_OBMC
void vp10_build_prediction_by_above_preds(VP10_COMP *cpi,
MACROBLOCKD *xd,
int mi_row, int mi_col,
uint8_t *tmp_buf[MAX_MB_PLANE],
int tmp_stride[MAX_MB_PLANE]);
void vp10_build_prediction_by_left_preds(VP10_COMP *cpi,
MACROBLOCKD *xd,
int mi_row, int mi_col,
uint8_t *tmp_buf[MAX_MB_PLANE],
int tmp_stride[MAX_MB_PLANE]);
#endif // CONFIG_OBMC
#ifdef __cplusplus
} // extern "C"
#endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment