Commit 44c2bad5 authored by Alex Converse's avatar Alex Converse

intrabc: Add a DV prediction scheme derived from ref_mv

wikipedia_420.y4m
PSNR: -1.5035 PSNR-HVS: -1.2607 SSIM: -1.1581

Change-Id: I6e6c4bd9671427b99299df39ff0f42af7daf8ce7
parent 40bc8b8a
......@@ -585,6 +585,9 @@ static void find_mv_refs_idx(const AV1_COMMON *cm, const MACROBLOCKD *xd,
cm->use_prev_frame_mvs
? cm->prev_frame->mvs + mi_row * cm->mi_cols + mi_col
: NULL;
#endif
#if CONFIG_INTRABC
assert(IMPLIES(ref_frame == INTRA_FRAME, cm->use_prev_frame_mvs == 0));
#endif
const TileInfo *const tile = &xd->tile;
const BLOCK_SIZE bsize = mi->mbmi.sb_type;
......
......@@ -267,8 +267,12 @@ static INLINE void av1_set_ref_frame(MV_REFERENCE_FRAME *rf,
} else {
rf[0] = ref_frame_type;
rf[1] = NONE_FRAME;
assert(ref_frame_type > INTRA_FRAME &&
ref_frame_type < TOTAL_REFS_PER_FRAME);
#if CONFIG_INTRABC
assert(ref_frame_type > NONE_FRAME);
#else
assert(ref_frame_type > INTRA_FRAME);
#endif
assert(ref_frame_type < TOTAL_REFS_PER_FRAME);
}
}
......
......@@ -1045,7 +1045,6 @@ static INLINE int assign_dv(AV1_COMMON *cm, MACROBLOCKD *xd, int_mv *mv,
read_mv(r, &mv->as_mv, &ref_mv->as_mv, &ec_ctx->ndvc, dv_counts, 0);
int valid = is_mv_valid(&mv->as_mv) &&
is_dv_valid(mv->as_mv, &xd->tile, mi_row, mi_col, bsize);
// TODO(aconverse@google.com): additional validation
return valid;
}
#endif // CONFIG_INTRABC
......@@ -1103,14 +1102,29 @@ static void read_intra_frame_mode_info(AV1_COMMON *const cm,
if (bsize >= BLOCK_8X8 && cm->allow_screen_content_tools) {
mbmi->use_intrabc = aom_read(r, INTRABC_PROB, ACCT_STR);
if (mbmi->use_intrabc) {
int_mv dv_ref;
mbmi->mode = mbmi->uv_mode = DC_PRED;
#if CONFIG_DUAL_FILTER
for (int idx = 0; idx < 4; ++idx) mbmi->interp_filter[idx] = BILINEAR;
#else
mbmi->interp_filter = BILINEAR;
#endif
av1_find_ref_dv(&dv_ref, mi_row, mi_col);
int16_t inter_mode_ctx[MODE_CTX_REF_FRAMES];
int_mv ref_mvs[MAX_MV_REF_CANDIDATES] = {};
av1_find_mv_refs(cm, xd, mi, INTRA_FRAME, &xd->ref_mv_count[INTRA_FRAME],
xd->ref_mv_stack[INTRA_FRAME],
#if CONFIG_EXT_INTER
compound_inter_mode_ctx,
#endif // CONFIG_EXT_INTER
ref_mvs, mi_row, mi_col, NULL, NULL, inter_mode_ctx);
int_mv nearestmv, nearmv;
av1_find_best_ref_mvs(0, ref_mvs, &nearestmv, &nearmv);
int_mv dv_ref = nearestmv.as_int == 0 ? nearmv : nearestmv;
if (dv_ref.as_int == 0) av1_find_ref_dv(&dv_ref, mi_row, mi_col);
xd->corrupted |=
!assign_dv(cm, xd, &mbmi->mv[0], &dv_ref, mi_row, mi_col, bsize, r);
#if CONFIG_EXT_TX && !CONFIG_TXK_SEL
......
......@@ -2144,6 +2144,9 @@ static void write_mb_modes_kf(AV1_COMMON *cm,
#else
const MACROBLOCKD *xd,
#endif // CONFIG_DELTA_Q
#if CONFIG_INTRABC
const MB_MODE_INFO_EXT *mbmi_ext,
#endif // CONFIG_INTRABC
const int mi_row, const int mi_col,
aom_writer *w) {
const struct segmentation *const seg = &cm->seg;
......@@ -2215,8 +2218,7 @@ static void write_mb_modes_kf(AV1_COMMON *cm,
if (use_intrabc) {
assert(mbmi->mode == DC_PRED);
assert(mbmi->uv_mode == DC_PRED);
int_mv dv_ref;
av1_find_ref_dv(&dv_ref, mi_row, mi_col);
int_mv dv_ref = mbmi_ext->ref_mvs[INTRA_FRAME][0];
av1_encode_dv(w, &mbmi->mv[0].as_mv, &dv_ref.as_mv, &ec_ctx->ndvc);
#if CONFIG_EXT_TX && !CONFIG_TXK_SEL
av1_write_tx_type(cm, xd,
......@@ -2365,7 +2367,11 @@ static void write_mbmi_b(AV1_COMP *cpi, const TileInfo *const tile,
cm->mi_rows, cm->mi_cols);
if (frame_is_intra_only(cm)) {
write_mb_modes_kf(cm, xd, mi_row, mi_col, w);
write_mb_modes_kf(cm, xd,
#if CONFIG_INTRABC
cpi->td.mb.mbmi_ext,
#endif // CONFIG_INTRABC
mi_row, mi_col, w);
} else {
#if CONFIG_VAR_TX
xd->above_txfm_context = cm->above_txfm_context + mi_col;
......
......@@ -9065,11 +9065,25 @@ static int64_t rd_pick_intrabc_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
const int h = block_size_high[bsize];
const int sb_row = mi_row / MAX_MIB_SIZE;
int_mv dv_ref;
av1_find_ref_dv(&dv_ref, mi_row, mi_col);
MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
MV_REFERENCE_FRAME ref_frame = INTRA_FRAME;
int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
mbmi_ext->ref_mv_stack[ref_frame],
#if CONFIG_EXT_INTER
mbmi_ext->compound_mode_context,
#endif // CONFIG_EXT_INTER
candidates, mi_row, mi_col, NULL, NULL,
mbmi_ext->mode_context);
const MvLimits tmp_mv_limits = x->mv_limits;
int_mv nearestmv, nearmv;
av1_find_best_ref_mvs(0, candidates, &nearestmv, &nearmv);
int_mv dv_ref = nearestmv.as_int == 0 ? nearmv : nearestmv;
if (dv_ref.as_int == 0) av1_find_ref_dv(&dv_ref, mi_row, mi_col);
mbmi_ext->ref_mvs[INTRA_FRAME][0] = dv_ref;
const MvLimits tmp_mv_limits = x->mv_limits;
// TODO(aconverse@google.com): Handle same row DV.
x->mv_limits.col_min = (tile->mi_col_start - mi_col) * MI_SIZE;
x->mv_limits.col_max = (tile->mi_col_end - mi_col) * MI_SIZE - w;
......@@ -9198,6 +9212,7 @@ void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
xd->mi[0]->mbmi.ref_frame[1] = NONE_FRAME;
#if CONFIG_INTRABC
xd->mi[0]->mbmi.use_intrabc = 0;
xd->mi[0]->mbmi.mv[0].as_int = 0;
#endif // CONFIG_INTRABC
const int64_t intra_yrd =
......
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