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/decoder/decodemv.c b/av1/decoder/decodemv.c
index 3a2ab56..24e7cee 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -902,6 +902,32 @@
   }
 }
 
+#if CONFIG_INTRABC
+static INLINE void read_mv(aom_reader *r, MV *mv, const MV *ref,
+                           nmv_context *ctx, nmv_context_counts *counts,
+                           int allow_hp);
+
+static INLINE int is_mv_valid(const MV *mv);
+
+static INLINE int assign_dv(AV1_COMMON *cm, MACROBLOCKD *xd, int_mv *mv,
+                            const int_mv *ref_mv, int mi_row, int mi_col,
+                            BLOCK_SIZE bsize, aom_reader *r) {
+#if CONFIG_EC_ADAPT
+  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
+  (void)cm;
+#else
+  FRAME_CONTEXT *ec_ctx = cm->fc;
+#endif
+  FRAME_COUNTS *counts = xd->counts;
+  nmv_context_counts *const dv_counts = counts ? &counts->dv : NULL;
+  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
+
 static void read_intra_frame_mode_info(AV1_COMMON *const cm,
                                        MACROBLOCKD *const xd, int mi_row,
                                        int mi_col, aom_reader *r) {
@@ -942,6 +968,21 @@
   mbmi->ref_frame[0] = INTRA_FRAME;
   mbmi->ref_frame[1] = NONE_FRAME;
 
+#if CONFIG_INTRABC
+  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;
+      mbmi->interp_filter = BILINEAR;
+      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);
+      return;
+    }
+  }
+#endif  // CONFIG_INTRABC
+
 #if CONFIG_CB4X4
   (void)i;
   mbmi->mode =
@@ -2283,6 +2324,10 @@
   MV_REF *frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
   int w, h;
 
+#if CONFIG_INTRABC
+  mi->mbmi.use_intrabc = 0;
+#endif  // CONFIG_INTRABC
+
   if (frame_is_intra_only(cm)) {
     read_intra_frame_mode_info(cm, xd, mi_row, mi_col, r);
 #if CONFIG_REF_MV