]> granicus.if.org Git - libvpx/commitdiff
intrabc: displacement vector prediction
authorAlex Converse <aconverse@google.com>
Mon, 27 Apr 2015 16:40:48 +0000 (09:40 -0700)
committerAlex Converse <aconverse@google.com>
Wed, 24 Jun 2015 17:02:50 +0000 (10:02 -0700)
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
vp9/encoder/vp9_bitstream.c
vp9/encoder/vp9_encodeframe.c
vp9/encoder/vp9_rdopt.c
vp9/encoder/vp9_rdopt.h

index 24d7cf20f0de8874f4c9b74a6285617205c33f9b..b086aab6b9c2404e0c980fc390940b08b2e50f30 100644 (file)
@@ -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
index 9e7f0da78efc7cd9e92ebb9ae8b2ec81276d4058..be981acb24ec53b12f4476cdf6a35805f789c02c 100644 (file)
@@ -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
index d6cba2ef2245c5982d708288667733bf713ab0f5..3d0f2fc54ad1fb45c2377b83f6b83ac4d34d4b7a 100644 (file)
@@ -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
index a201e35dc22379871528647271d51da549768e28..2974d00c3df25dc18511710e134a843bcb73ff12 100644 (file)
@@ -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;
index f4cbfa7a3c20630a00609335d8c980be7ca3be95..1db059674152ad435db34149e7350aa5f504d42c 100644 (file)
@@ -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,