Add bottom line buffer to Cdef frame

This CL adds bottom linebuf to cdef frame to suit row-level
multi-threading.

Change-Id: I09213cdc267bd2b26b095020b136f4c96c30d909
diff --git a/av1/common/alloccommon.c b/av1/common/alloccommon.c
index acc6280..442973d 100644
--- a/av1/common/alloccommon.c
+++ b/av1/common/alloccommon.c
@@ -81,9 +81,10 @@
   const int is_large_scale_tile_changed =
       cdef_info->prev_large_scale_tile_flag != cm->tiles.large_scale;
   const int is_num_planes_changed = cdef_info->prev_num_planes != num_planes;
-  // num-bufs=2 represents ping-pong buffers for top linebuf.
-  // this is to avoid linebuf over-write by consecutive row.
-  int num_bufs = 2;
+  // num-bufs=3 represents ping-pong buffers for top linebuf,
+  // followed by bottom linebuf.
+  // ping-pong is to avoid top linebuf over-write by consecutive row.
+  int num_bufs = 3;
 
   if (is_frame_scaled || is_sub_sampling_changed || is_cdef_flag_changed ||
       is_large_scale_tile_changed || is_num_planes_changed)
diff --git a/av1/common/cdef.c b/av1/common/cdef.c
index 97c643b..33c936a 100644
--- a/av1/common/cdef.c
+++ b/av1/common/cdef.c
@@ -27,6 +27,7 @@
 typedef struct {
   uint16_t *src;
   uint16_t *top_linebuf[MAX_MB_PLANE];
+  uint16_t *bot_linebuf[MAX_MB_PLANE];
   uint8_t *dst;
   cdef_list dlist[MI_SIZE_64X64 * MI_SIZE_64X64];
 
@@ -173,6 +174,8 @@
   int hsize = nhb << fb_info->mi_wide_l2;
   int vsize = nvb << fb_info->mi_high_l2;
   const uint16_t *top_linebuf = fb_info->top_linebuf[plane];
+  const uint16_t *bot_linebuf = fb_info->bot_linebuf[plane];
+  const int bot_offset = (vsize + CDEF_VBORDER) * CDEF_BSTRIDE;
   const int stride =
       luma_stride >> (plane == AOM_PLANE_Y ? 0 : cm->seq_params.subsampling_x);
 
@@ -186,18 +189,38 @@
   else
     rend = vsize + CDEF_VBORDER;
 
-  if (fbr == nvfb - 1) {
-    /* On the last superblock row, fill in the bottom border with
-    CDEF_VERY_LARGE to avoid filtering with the outside. */
-    fill_rect(&src[(rend + CDEF_VBORDER) * CDEF_BSTRIDE], CDEF_BSTRIDE,
-              CDEF_VBORDER, hsize + 2 * CDEF_HBORDER, CDEF_VERY_LARGE);
-  }
   /* Copy in the pixels we need from the current superblock for
   deringing.*/
   copy_sb8_16(cm, &src[CDEF_VBORDER * CDEF_BSTRIDE + CDEF_HBORDER + cstart],
               CDEF_BSTRIDE, fb_info->dst, fb_info->roffset,
-              fb_info->coffset + cstart, fb_info->dst_stride, rend,
+              fb_info->coffset + cstart, fb_info->dst_stride, vsize,
               cend - cstart);
+
+  /* Copy in the pixels we need for the current superblock from bottom buffer.*/
+  if (fbr < nvfb - 1) {
+    copy_rect(&src[bot_offset + CDEF_HBORDER], CDEF_BSTRIDE,
+              &bot_linebuf[fb_info->coffset], stride, CDEF_VBORDER, hsize);
+  } else {
+    fill_rect(&src[bot_offset + CDEF_HBORDER], CDEF_BSTRIDE, CDEF_VBORDER,
+              hsize, CDEF_VERY_LARGE);
+  }
+  if (fbr < nvfb - 1 && fbc > 0) {
+    copy_rect(&src[bot_offset], CDEF_BSTRIDE,
+              &bot_linebuf[fb_info->coffset - CDEF_HBORDER], stride,
+              CDEF_VBORDER, CDEF_HBORDER);
+  } else {
+    fill_rect(&src[bot_offset], CDEF_BSTRIDE, CDEF_VBORDER, CDEF_HBORDER,
+              CDEF_VERY_LARGE);
+  }
+  if (fbr < nvfb - 1 && fbc < nhfb - 1) {
+    copy_rect(&src[bot_offset + hsize + CDEF_HBORDER], CDEF_BSTRIDE,
+              &bot_linebuf[fb_info->coffset + hsize], stride, CDEF_VBORDER,
+              CDEF_HBORDER);
+  } else {
+    fill_rect(&src[bot_offset + hsize + CDEF_HBORDER], CDEF_BSTRIDE,
+              CDEF_VBORDER, CDEF_HBORDER, CDEF_VERY_LARGE);
+  }
+
   /* Copy in the pixels we need from the current superblock from top buffer.*/
   if (fbr > 0) {
     copy_rect(&src[CDEF_HBORDER], CDEF_BSTRIDE, &top_linebuf[fb_info->coffset],
@@ -370,6 +393,7 @@
     // to avoid linebuf over-write by consecutive row.
     uint16_t *const top_linebuf =
         &linebuf[plane][ping_pong * CDEF_VBORDER * stride];
+    fb_info->bot_linebuf[plane] = &linebuf[plane][(CDEF_VBORDER << 1) * stride];
 
     if (fbr != nvfb - 1)  // top line buffer copy
       copy_sb8_16(cm, top_linebuf, stride, xd->plane[plane].dst.buf,
@@ -377,6 +401,11 @@
                   CDEF_VBORDER, stride);
     fb_info->top_linebuf[plane] =
         &linebuf[plane][(!ping_pong) * CDEF_VBORDER * stride];
+
+    if (fbr != nvfb - 1)  // bottom line buffer copy
+      copy_sb8_16(cm, fb_info->bot_linebuf[plane], stride,
+                  xd->plane[plane].dst.buf, offset, 0,
+                  xd->plane[plane].dst.stride, CDEF_VBORDER, stride);
   }
 }