From 93cd5cf3f4bfb64bfd2dafd6d696e838135e5de4 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Mon, 27 Apr 2015 09:40:48 -0700 Subject: [PATCH] intrabc: displacement vector prediction Predict displacement vector with the same logic as NEARESTMV. If no neighbors are available fall back to the current one block left or up prediction. vp9+intrabc+tx_skip+palette: -0.489 vp9+intrabc: -0.771 Change-Id: If67d08b54f1a3b847cf7ab8c7b800c55baa1a86b --- vp9/decoder/vp9_decodemv.c | 19 ++++++++++++++-- vp9/encoder/vp9_bitstream.c | 12 ++-------- vp9/encoder/vp9_encodeframe.c | 2 +- vp9/encoder/vp9_rdopt.c | 41 +++++++++++++++++++++++++++++------ vp9/encoder/vp9_rdopt.h | 1 + 5 files changed, 55 insertions(+), 20 deletions(-) diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c index 24d7cf20f..b086aab6b 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -254,6 +254,9 @@ static INLINE int assign_dv(VP9_COMMON *cm, PREDICTION_MODE mode, static void read_intra_frame_mode_info(VP9_COMMON *const cm, MACROBLOCKD *const xd, +#if CONFIG_INTRABC + const TileInfo *const tile, +#endif int mi_row, int mi_col, vp9_reader *r) { MODE_INFO *const mi = xd->mi[0].src_mi; MB_MODE_INFO *const mbmi = &mi->mbmi; @@ -275,7 +278,6 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm, #endif #if CONFIG_INTRABC - vp9_find_ref_dv(&dv_ref, mi_row, mi_col); if (bsize >= BLOCK_8X8 && cm->allow_intrabc_mode) { use_intrabc = vp9_read(r, INTRABC_PROB); if (use_intrabc) { @@ -472,6 +474,15 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm, #if CONFIG_INTRABC if (use_intrabc) { + int_mv nearestmv, nearmv; + vp9_find_mv_refs(cm, xd, tile, mi, INTRA_FRAME, mbmi->ref_mvs[INTRA_FRAME], + mi_row, mi_col); + vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv, + mbmi->ref_mvs[INTRA_FRAME], + &nearestmv, &nearmv); + if (nearestmv.as_int == 0) + vp9_find_ref_dv(&nearestmv, mi_row, mi_col); + dv_ref = nearestmv; xd->corrupted |= !assign_dv(cm, mbmi->mode, &mbmi->mv[0], &dv_ref, r); } else #endif // CONFIG_INTRABC @@ -1609,7 +1620,11 @@ void vp9_read_mode_info(VP9_COMMON *cm, MACROBLOCKD *xd, #endif int mi_row, int mi_col, vp9_reader *r) { if (frame_is_intra_only(cm)) - read_intra_frame_mode_info(cm, xd, mi_row, mi_col, r); + read_intra_frame_mode_info(cm, xd, +#if CONFIG_INTRABC + tile, +#endif // CONFIG_INTRABC + mi_row, mi_col, r); else read_inter_frame_mode_info(cm, xd, tile, #if CONFIG_SUPERTX diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 9e7f0da78..be981acb2 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -865,9 +865,6 @@ static void write_mb_modes_kf(const VP9_COMMON *cm, #else const MACROBLOCKD *xd, #endif // CONFIG_PALETTE -#if CONFIG_INTRABC - int mi_row, int mi_col, -#endif // CONFIG_INTRABC MODE_INFO *mi_8x8, vp9_writer *w) { const struct segmentation *const seg = &cm->seg; const MODE_INFO *const mi = mi_8x8; @@ -879,8 +876,6 @@ static void write_mb_modes_kf(const VP9_COMMON *cm, const BLOCK_SIZE bsize = mbmi->sb_type; #if CONFIG_INTRABC const nmv_context *ndvc = &cm->fc.ndvc; - int_mv dv_ref; - vp9_find_ref_dv(&dv_ref, mi_row, mi_col); #endif // CONFIG_INTRABC if (seg->update_map) @@ -1053,6 +1048,7 @@ static void write_mb_modes_kf(const VP9_COMMON *cm, #endif // CONFIG_FILTERINTRA #if CONFIG_INTRABC if (mbmi->mode == NEWDV) { + int_mv dv_ref = mbmi->ref_mvs[INTRA_FRAME][0]; vp9_encode_dv(w, &mbmi->mv[0].as_mv, &dv_ref.as_mv, ndvc); } #endif // CONFIG_INTRABC @@ -1114,11 +1110,7 @@ static void write_modes_b(VP9_COMP *cpi, const TileInfo *const tile, mi_col, num_8x8_blocks_wide_lookup[m->mbmi.sb_type], cm->mi_rows, cm->mi_cols); if (frame_is_intra_only(cm)) { - write_mb_modes_kf(cm, xd, -#if CONFIG_INTRABC - mi_row, mi_col, -#endif // CONFIG_INTRABC - xd->mi, w); + write_mb_modes_kf(cm, xd, xd->mi, w); } else { pack_inter_mode_mvs(cpi, m, #if CONFIG_SUPERTX diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index d6cba2ef2..3d0f2fc54 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -1454,7 +1454,7 @@ static void rd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile, #endif vp9_rd_pick_intra_mode_sb(cpi, x, #if CONFIG_INTRABC - mi_row, mi_col, + tile, mi_row, mi_col, #endif // CONFIG_INTRABC rd_cost, bsize, ctx, best_rd); #if CONFIG_PALETTE diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index a201e35dc..2974d00c3 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -1462,11 +1462,12 @@ static void intrabc_search(VP9_COMP *cpi, MACROBLOCK *x, int_mv *tmp_mv, int *rate_mv) { const VP9_COMMON *cm = &cpi->common; struct macroblockd_plane *pd = x->e_mbd.plane; + MB_MODE_INFO *mbmi = &x->e_mbd.mi[0].src_mi->mbmi; int bestsme = INT_MAX; int step_param; int sadpb = x->sadperbit16; MV mvp_full; - MV ref_mv; + MV ref_mv = mbmi->ref_mvs[INTRA_FRAME][0].as_mv; int tmp_col_min = x->mv_col_min; int tmp_col_max = x->mv_col_max; @@ -1482,7 +1483,6 @@ static void intrabc_search(VP9_COMP *cpi, MACROBLOCK *x, tmp_mv->as_int = INVALID_MV; *rate_mv = 0; // compiler bug? - vp9_find_ref_dv((int_mv*)&ref_mv, mi_row, mi_col); vp9_set_mv_search_range(x, &ref_mv); @@ -2209,8 +2209,18 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x, } #if CONFIG_INTRABC +static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x, + const TileInfo *const tile, + MV_REFERENCE_FRAME ref_frame, + BLOCK_SIZE block_size, + int mi_row, int mi_col, + int_mv frame_nearest_mv[MAX_REF_FRAMES], + int_mv frame_near_mv[MAX_REF_FRAMES], + struct buf_2d yv12_mb[4][MAX_MB_PLANE]); + // This function is used only for intra_only frames static int64_t rd_pick_intrabc_sb_mode(VP9_COMP *cpi, MACROBLOCK *x, + const TileInfo *const tile, int mi_row, int mi_col, int *rate, int64_t *distortion, int *skippable, @@ -2222,6 +2232,7 @@ static int64_t rd_pick_intrabc_sb_mode(VP9_COMP *cpi, MACROBLOCK *x, MODE_INFO *const mic = xd->mi[0].src_mi; MB_MODE_INFO *mbmi = &mic->mbmi; MB_MODE_INFO mbmi_selected = *mbmi; + int_mv frame_dv[2][MAX_REF_FRAMES]; int best_skip = x->skip; struct buf_2d yv12_mb[MAX_MB_PLANE]; int i; @@ -2242,8 +2253,11 @@ static int64_t rd_pick_intrabc_sb_mode(VP9_COMP *cpi, MACROBLOCK *x, for (i = 0; i < TX_MODES; i++) tx_cache[i] = INT64_MAX; - vp9_setup_pred_block(xd, yv12_mb, xd->cur_buf, mi_row, mi_col, - NULL, NULL); + setup_buffer_inter(cpi, x, tile, INTRA_FRAME, bsize, mi_row, mi_col, + frame_dv[0], frame_dv[1], &yv12_mb); + if (mic->mbmi.ref_mvs[INTRA_FRAME][0].as_int == 0) + vp9_find_ref_dv(&mic->mbmi.ref_mvs[INTRA_FRAME][0], mi_row, mi_col); + for (i = 0; i < MAX_MB_PLANE; i++) { xd->plane[i].pre[0] = yv12_mb[i]; } @@ -2262,6 +2276,7 @@ static int64_t rd_pick_intrabc_sb_mode(VP9_COMP *cpi, MACROBLOCK *x, int64_t this_rd; mbmi->mode = mode; mbmi->uv_mode = mode; + mbmi->mv[0].as_mv = mic->mbmi.ref_mvs[INTRA_FRAME][0].as_mv; assert(mbmi->sb_type >= BLOCK_8X8); cpi->common.interp_filter = BILINEAR; this_rd = handle_intrabc_mode(cpi, x, bsize, @@ -3911,11 +3926,19 @@ static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x, int_mv frame_near_mv[MAX_REF_FRAMES], struct buf_2d yv12_mb[4][MAX_MB_PLANE]) { const VP9_COMMON *cm = &cpi->common; - const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame); MACROBLOCKD *const xd = &x->e_mbd; + const YV12_BUFFER_CONFIG *yv12 = +#if CONFIG_INTRABC + ref_frame == INTRA_FRAME ? xd->cur_buf : +#endif // CONFIG_INTRABC + get_ref_frame_buffer(cpi, ref_frame); MODE_INFO *const mi = xd->mi[0].src_mi; int_mv *const candidates = mi->mbmi.ref_mvs[ref_frame]; - const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf; + const struct scale_factors *const sf = +#if CONFIG_INTRABC + ref_frame == INTRA_FRAME ? NULL : +#endif // CONFIG_INTRABC + &cm->frame_refs[ref_frame - 1].sf; // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this // use the UV scaling factors. @@ -5716,6 +5739,7 @@ static void rd_pick_palette_444(VP9_COMP *cpi, MACROBLOCK *x, RD_COST *rd_cost, void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, #if CONFIG_INTRABC + const TileInfo *const tile, int mi_row, int mi_col, #endif // CONFIG_INTRABC RD_COST *rd_cost, @@ -5732,6 +5756,9 @@ void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, x->skip_encode = 0; ctx->skip = 0; xd->mi[0].src_mi->mbmi.ref_frame[0] = INTRA_FRAME; +#if CONFIG_INTRABC + xd->mi[0].src_mi->mbmi.mv[0].as_int = 0; +#endif // CONFIG_INTRABC vp9_rd_cost_reset(rd_cost); if (bsize >= BLOCK_8X8) { @@ -5783,7 +5810,7 @@ void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, #if CONFIG_INTRABC if (bsize >= BLOCK_8X8 && cm->allow_intrabc_mode) { best_rd = MIN(best_rd, rd_cost->rdcost); - if (rd_pick_intrabc_sb_mode(cpi, x, mi_row, mi_col, &rate_y, + if (rd_pick_intrabc_sb_mode(cpi, x, tile, mi_row, mi_col, &rate_y, &dist_y, &y_skip, bsize, tx_cache, best_rd) < best_rd) { rd_cost->rate = rate_y; diff --git a/vp9/encoder/vp9_rdopt.h b/vp9/encoder/vp9_rdopt.h index f4cbfa7a3..1db059674 100644 --- a/vp9/encoder/vp9_rdopt.h +++ b/vp9/encoder/vp9_rdopt.h @@ -27,6 +27,7 @@ struct RD_COST; void vp9_rd_pick_intra_mode_sb(struct VP9_COMP *cpi, struct macroblock *x, #if CONFIG_INTRABC + const TileInfo *const tile, int mi_row, int mi_col, #endif // CONFIG_INTRABC struct RD_COST *rd_cost, BLOCK_SIZE bsize,