intrabc: Add initial skeleton

Missing features:
* RDOPT (Forced on for certain blocks)
* Any form of border extension
* Non MI sized right and bottom edges
* MV prediction

Present features:
* Force intrabc for some blocks
* Carry intrabc in the bitstream
* Validate DV is causal
* Reconstruct intrabc block assuming border extension is unnecessary

Change-Id: Ib1f6868e89bfacc2a4edfc876485bad1b347263b
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 1091683..f94f1f4 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -9166,6 +9166,39 @@
   return 0;  // The rate-distortion cost will be re-calculated by caller.
 }
 
+#if CONFIG_INTRABC
+// This is a dummy function that forces intrabc on for testing purposes
+// TODO(aconverse@google.com): Implement a real intrabc search
+static int64_t rd_pick_intrabc_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
+                                       RD_COST *rd_cost, BLOCK_SIZE bsize,
+                                       int64_t best_rd) {
+  MACROBLOCKD *const xd = &x->e_mbd;
+  (void)best_rd;
+  if (bsize >= BLOCK_8X8 && cpi->common.allow_screen_content_tools) {
+    if (xd->mb_to_top_edge == -MAX_SB_SIZE * 8) {
+      MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
+      mbmi->use_intrabc = 1;
+      mbmi->mode = DC_PRED;
+      mbmi->uv_mode = DC_PRED;
+      mbmi->mv[0].as_mv.row = -MAX_SB_SIZE * 8;
+      mbmi->mv[0].as_mv.col = 0;
+      mbmi->interp_filter = BILINEAR;
+      mbmi->skip = 1;
+      x->skip = 1;
+      const int mi_row = -xd->mb_to_top_edge / (8 * MI_SIZE);
+      const int mi_col = -xd->mb_to_left_edge / (8 * MI_SIZE);
+      av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, bsize);
+      rd_cost->rate = 1;
+      rd_cost->dist = 0;
+      rd_cost->rdcost =
+          RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
+      return rd_cost->rdcost;
+    }
+  }
+  return INT64_MAX;
+}
+#endif  // CONFIG_INTRABC
+
 void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
                                RD_COST *rd_cost, BLOCK_SIZE bsize,
                                PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
@@ -9181,6 +9214,9 @@
   ctx->skip = 0;
   xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
   xd->mi[0]->mbmi.ref_frame[1] = NONE_FRAME;
+#if CONFIG_INTRABC
+  xd->mi[0]->mbmi.use_intrabc = 0;
+#endif  // CONFIG_INTRABC
 
   if (bsize >= BLOCK_8X8 || unify_bsize) {
     if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y,
@@ -9220,6 +9256,12 @@
     rd_cost->dist = dist_y + dist_uv;
   }
 
+#if CONFIG_INTRABC
+  if (rd_pick_intrabc_mode_sb(cpi, x, rd_cost, bsize, best_rd) < best_rd) {
+    ctx->skip = x->skip;  // FIXME where is the proper place to set this?!
+  }
+#endif
+
   ctx->mic = *xd->mi[0];
   ctx->mbmi_ext = *x->mbmi_ext;
   rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);