rtc: Fix uv sad calculation

The y_sad used in chroma_check for setting the
color_sensitivity is based on last frame so uv_sad
based on last frame should be used in the comparison.
However, for zero motion, uv_sad based on golden frame
was being used sometimes, as the predictor could be set
based on golden frame in the function setup_planes().
To overcome this issue, last frame predictor block
is setup in chroma_check function.

Also, in set_color_sensitivity() function, the predictor
buffer used in uv_sad calculation is corrected, as 'pd->dst'
is not setup before.

STATS_CHANGED

Change-Id: I50ac5a1492bf938da9897a6d3290c0c0242e06fa
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c
index 8ac3b5c..768e888 100644
--- a/av1/encoder/nonrd_pickmode.c
+++ b/av1/encoder/nonrd_pickmode.c
@@ -2428,9 +2428,11 @@
   return 0;
 }
 
-void set_color_sensitivity(AV1_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd,
-                           BLOCK_SIZE bsize, int y_sad,
-                           unsigned int source_variance) {
+void set_color_sensitivity(AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
+                           int y_sad, unsigned int source_variance,
+                           struct buf_2d yv12_mb[MAX_MB_PLANE]) {
+  const int subsampling_x = cpi->common.seq_params->subsampling_x;
+  const int subsampling_y = cpi->common.seq_params->subsampling_y;
   int factor = (bsize >= BLOCK_32X32) ? 2 : 3;
   int shift = 3;
   if (cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN &&
@@ -2457,11 +2459,12 @@
   for (int i = 1; i <= 2; ++i) {
     if (x->color_sensitivity[i - 1] == 2 || source_variance < 50) {
       struct macroblock_plane *const p = &x->plane[i];
-      struct macroblockd_plane *const pd = &xd->plane[i];
       const BLOCK_SIZE bs =
-          get_plane_block_size(bsize, pd->subsampling_x, pd->subsampling_y);
-      const int uv_sad = cpi->ppi->fn_ptr[bs].sdf(p->src.buf, p->src.stride,
-                                                  pd->dst.buf, pd->dst.stride);
+          get_plane_block_size(bsize, subsampling_x, subsampling_y);
+
+      const int uv_sad = cpi->ppi->fn_ptr[bs].sdf(
+          p->src.buf, p->src.stride, yv12_mb[i].buf, yv12_mb[i].stride);
+
       const int norm_uv_sad =
           uv_sad >> (b_width_log2_lookup[bs] + b_height_log2_lookup[bs]);
       x->color_sensitivity[i - 1] =
@@ -3110,7 +3113,8 @@
               (abs(frame_mv[NEARESTMV][LAST_FRAME].as_mv.col) +
                abs(frame_mv[NEARESTMV][LAST_FRAME].as_mv.row)))
         y_sad = x->pred_mv1_sad[LAST_FRAME];
-      set_color_sensitivity(cpi, x, xd, bsize, y_sad, x->source_variance);
+      set_color_sensitivity(cpi, x, bsize, y_sad, x->source_variance,
+                            yv12_mb[LAST_FRAME]);
     }
     mi->motion_mode = SIMPLE_TRANSLATION;
 #if !CONFIG_REALTIME_ONLY
diff --git a/av1/encoder/var_based_part.c b/av1/encoder/var_based_part.c
index 48b5220..2c88427 100644
--- a/av1/encoder/var_based_part.c
+++ b/av1/encoder/var_based_part.c
@@ -906,6 +906,13 @@
       cpi->rc.high_source_sad)
     shift = 5;
 
+  MB_MODE_INFO *mi = xd->mi[0];
+  const AV1_COMMON *const cm = &cpi->common;
+  const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_yv12_buf(cm, LAST_FRAME);
+  const struct scale_factors *const sf =
+      get_ref_scale_factors_const(cm, LAST_FRAME);
+  struct buf_2d dst;
+
   for (i = 1; i <= 2; ++i) {
     struct macroblock_plane *p = &x->plane[i];
     struct macroblockd_plane *pd = &xd->plane[i];
@@ -913,10 +920,21 @@
         get_plane_block_size(bsize, pd->subsampling_x, pd->subsampling_y);
 
     if (bs != BLOCK_INVALID) {
-      if (zero_motion)
-        uv_sad[i - 1] = cpi->ppi->fn_ptr[bs].sdf(
-            p->src.buf, p->src.stride, pd->pre[0].buf, pd->pre[0].stride);
-      else
+      if (zero_motion) {
+        if (mi->ref_frame[0] == LAST_FRAME) {
+          uv_sad[i - 1] = cpi->ppi->fn_ptr[bs].sdf(
+              p->src.buf, p->src.stride, pd->pre[0].buf, pd->pre[0].stride);
+        } else {
+          uint8_t *src = (i == 1) ? yv12->u_buffer : yv12->v_buffer;
+          setup_pred_plane(&dst, xd->mi[0]->bsize, src, yv12->uv_crop_width,
+                           yv12->uv_crop_height, yv12->uv_stride, xd->mi_row,
+                           xd->mi_col, sf, xd->plane[i].subsampling_x,
+                           xd->plane[i].subsampling_y);
+
+          uv_sad[i - 1] = cpi->ppi->fn_ptr[bs].sdf(p->src.buf, p->src.stride,
+                                                   dst.buf, dst.stride);
+        }
+      } else
         uv_sad[i - 1] = cpi->ppi->fn_ptr[bs].sdf(p->src.buf, p->src.stride,
                                                  pd->dst.buf, pd->dst.stride);
     }