Fix --test-decode=warn to test mismatch

This patch always compares the most recent show frames between
the encoder and the decoder to test the mismatch.

Change-Id: I68a91ad0996a598231450debfd616e24992419b5
diff --git a/vp10/decoder/decoder.c b/vp10/decoder/decoder.c
index 6d567d6..11a4b7c 100644
--- a/vp10/decoder/decoder.c
+++ b/vp10/decoder/decoder.c
@@ -483,6 +483,17 @@
   return ret;
 }
 
+int vp10_get_frame_to_show(VP10Decoder *pbi,
+                           YV12_BUFFER_CONFIG *frame) {
+  VP10_COMMON *const cm = &pbi->common;
+
+  if (!cm->show_frame || !cm->frame_to_show)
+    return -1;
+
+  *frame = *cm->frame_to_show;
+  return 0;
+}
+
 vpx_codec_err_t vp10_parse_superframe_index(const uint8_t *data,
                                            size_t data_sz,
                                            uint32_t sizes[8], int *count,
diff --git a/vp10/decoder/decoder.h b/vp10/decoder/decoder.h
index 0839e46..b34b009 100644
--- a/vp10/decoder/decoder.h
+++ b/vp10/decoder/decoder.h
@@ -104,6 +104,8 @@
 int vp10_get_raw_frame(struct VP10Decoder *pbi, YV12_BUFFER_CONFIG *sd,
                       vp10_ppflags_t *flags);
 
+int vp10_get_frame_to_show(struct VP10Decoder *pbi, YV12_BUFFER_CONFIG *frame);
+
 vpx_codec_err_t vp10_copy_reference_dec(struct VP10Decoder *pbi,
                                        VP9_REFFRAME ref_frame_flag,
                                        YV12_BUFFER_CONFIG *sd);
diff --git a/vp10/encoder/encoder.c b/vp10/encoder/encoder.c
index 43b5401..2965614 100644
--- a/vp10/encoder/encoder.c
+++ b/vp10/encoder/encoder.c
@@ -2409,6 +2409,7 @@
   cm->current_video_frame = 0;
   cpi->partition_search_skippable_frame = 0;
   cpi->tile_data = NULL;
+  cpi->last_show_frame_buf_idx = INVALID_IDX;
 
   realloc_segmentation_maps(cpi);
 
@@ -3322,6 +3323,11 @@
   int ref_frame;
 #endif  // CONFIG_EXT_REFS
 
+  // NOTE: Save the new show frame buffer index for --test-code=warn, i.e.,
+  //       for the purpose to verify no mismatch between encoder and decoder.
+  if (cm->show_frame)
+    cpi->last_show_frame_buf_idx = cm->new_fb_idx;
+
   if (use_upsampled_ref) {
     // Up-sample the current encoded frame.
     RefCntBuffer *bufs = pool->frame_bufs;
@@ -5336,6 +5342,15 @@
   }
 }
 
+int vp10_get_last_show_frame(VP10_COMP *cpi, YV12_BUFFER_CONFIG *frame) {
+  if (cpi->last_show_frame_buf_idx == INVALID_IDX)
+    return -1;
+
+  *frame =
+      cpi->common.buffer_pool->frame_bufs[cpi->last_show_frame_buf_idx].buf;
+  return 0;
+}
+
 int vp10_set_internal_size(VP10_COMP *cpi,
                           VPX_SCALING horiz_mode, VPX_SCALING vert_mode) {
   VP10_COMMON *cm = &cpi->common;
diff --git a/vp10/encoder/encoder.h b/vp10/encoder/encoder.h
index 673a9e6..7020087 100644
--- a/vp10/encoder/encoder.h
+++ b/vp10/encoder/encoder.h
@@ -353,6 +353,8 @@
   int gld_fb_idx;
   int alt_fb_idx;
 
+  int last_show_frame_buf_idx;  // last show frame buffer index
+
   int refresh_last_frame;
   int refresh_golden_frame;
   int refresh_alt_ref_frame;
@@ -610,6 +612,8 @@
 int vp10_get_preview_raw_frame(VP10_COMP *cpi, YV12_BUFFER_CONFIG *dest,
                               vp10_ppflags_t *flags);
 
+int vp10_get_last_show_frame(VP10_COMP *cpi, YV12_BUFFER_CONFIG *frame);
+
 int vp10_use_as_reference(VP10_COMP *cpi, int ref_frame_flags);
 
 void vp10_update_reference(VP10_COMP *cpi, int ref_frame_flags);
diff --git a/vp10/vp10_cx_iface.c b/vp10/vp10_cx_iface.c
index 0cad961..94a5f2f 100644
--- a/vp10/vp10_cx_iface.c
+++ b/vp10/vp10_cx_iface.c
@@ -1141,6 +1141,24 @@
   }
 }
 
+static vpx_codec_err_t ctrl_get_new_frame_image(vpx_codec_alg_priv_t *ctx,
+                                                va_list args) {
+  vpx_image_t *const new_img = va_arg(args, vpx_image_t *);
+
+  if (new_img != NULL) {
+    YV12_BUFFER_CONFIG new_frame;
+
+    if (vp10_get_last_show_frame(ctx->cpi, &new_frame) == 0) {
+      yuvconfig2image(new_img, &new_frame, NULL);
+      return VPX_CODEC_OK;
+    } else {
+      return VPX_CODEC_ERROR;
+    }
+  } else {
+    return VPX_CODEC_INVALID_PARAM;
+  }
+}
+
 static vpx_codec_err_t ctrl_set_previewpp(vpx_codec_alg_priv_t *ctx,
                                           va_list args) {
 #if CONFIG_VP9_POSTPROC
@@ -1330,6 +1348,7 @@
   {VP8E_GET_LAST_QUANTIZER_64,        ctrl_get_quantizer64},
   {VP9_GET_REFERENCE,                 ctrl_get_reference},
   {VP9E_GET_ACTIVEMAP,                ctrl_get_active_map},
+  {VP10_GET_NEW_FRAME_IMAGE,          ctrl_get_new_frame_image},
 
   { -1, NULL},
 };
diff --git a/vp10/vp10_dx_iface.c b/vp10/vp10_dx_iface.c
index 8dc49f2..d5c4c1c 100644
--- a/vp10/vp10_dx_iface.c
+++ b/vp10/vp10_dx_iface.c
@@ -921,6 +921,32 @@
   }
 }
 
+static vpx_codec_err_t ctrl_get_new_frame_image(vpx_codec_alg_priv_t *ctx,
+                                                va_list args) {
+  vpx_image_t *new_img = va_arg(args, vpx_image_t *);
+
+  // Only support this function in serial decode.
+  if (ctx->frame_parallel_decode) {
+    set_error_detail(ctx, "Not supported in frame parallel decode");
+    return VPX_CODEC_INCAPABLE;
+  }
+
+  if (new_img) {
+    YV12_BUFFER_CONFIG new_frame;
+    VPxWorker *const worker = ctx->frame_workers;
+    FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
+
+    if (vp10_get_frame_to_show(frame_worker_data->pbi, &new_frame) == 0) {
+      yuvconfig2image(new_img, &new_frame, NULL);
+      return VPX_CODEC_OK;
+    } else {
+      return VPX_CODEC_ERROR;
+    }
+  } else {
+    return VPX_CODEC_INVALID_PARAM;
+  }
+}
+
 static vpx_codec_err_t ctrl_set_postproc(vpx_codec_alg_priv_t *ctx,
                                          va_list args) {
 #if CONFIG_VP9_POSTPROC
@@ -1156,6 +1182,7 @@
   {VP9D_GET_DISPLAY_SIZE,         ctrl_get_render_size},
   {VP9D_GET_BIT_DEPTH,            ctrl_get_bit_depth},
   {VP9D_GET_FRAME_SIZE,           ctrl_get_frame_size},
+  {VP10_GET_NEW_FRAME_IMAGE,      ctrl_get_new_frame_image},
 
   { -1, NULL},
 };
diff --git a/vpx/vp8.h b/vpx/vp8.h
index 8a035f9..ba67c38 100644
--- a/vpx/vp8.h
+++ b/vpx/vp8.h
@@ -56,6 +56,9 @@
    */
   VP9_GET_REFERENCE           = 128,  /**< get a pointer to a reference frame */
   VP8_COMMON_CTRL_ID_MAX,
+
+  VP10_GET_NEW_FRAME_IMAGE    = 192,  /**< get a pointer to the new frame */
+
   VP8_DECODER_CTRL_ID_START   = 256
 };
 
@@ -137,6 +140,8 @@
 #define VPX_CTRL_VP8_SET_DBG_DISPLAY_MV
 VPX_CTRL_USE_TYPE(VP9_GET_REFERENCE,           vp9_ref_frame_t *)
 #define VPX_CTRL_VP9_GET_REFERENCE
+VPX_CTRL_USE_TYPE(VP10_GET_NEW_FRAME_IMAGE,    vpx_image_t *)
+#define VPX_CTRL_VP10_GET_NEW_FRAME_IMAGE
 
 /*!\endcond */
 /*! @} - end defgroup vp8 */
diff --git a/vpxenc.c b/vpxenc.c
index 9a52d54..d988b30 100644
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -1856,26 +1856,25 @@
     vpx_codec_control(&stream->encoder, VP8_COPY_REFERENCE, &ref_enc);
     vpx_codec_control(&stream->decoder, VP8_COPY_REFERENCE, &ref_dec);
   } else {
-    struct vp9_ref_frame ref_enc, ref_dec;
+    vpx_codec_control(&stream->encoder, VP10_GET_NEW_FRAME_IMAGE, &enc_img);
+    vpx_codec_control(&stream->decoder, VP10_GET_NEW_FRAME_IMAGE, &dec_img);
 
-    ref_enc.idx = 0;
-    ref_dec.idx = 0;
-    vpx_codec_control(&stream->encoder, VP9_GET_REFERENCE, &ref_enc);
-    enc_img = ref_enc.img;
-    vpx_codec_control(&stream->decoder, VP9_GET_REFERENCE, &ref_dec);
-    dec_img = ref_dec.img;
 #if CONFIG_VP9_HIGHBITDEPTH
     if ((enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) !=
         (dec_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH)) {
       if (enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) {
-        vpx_img_alloc(&enc_img, enc_img.fmt - VPX_IMG_FMT_HIGHBITDEPTH,
+        vpx_image_t enc_hbd_img;
+        vpx_img_alloc(&enc_hbd_img, enc_img.fmt - VPX_IMG_FMT_HIGHBITDEPTH,
                       enc_img.d_w, enc_img.d_h, 16);
-        vpx_img_truncate_16_to_8(&enc_img, &ref_enc.img);
+        vpx_img_truncate_16_to_8(&enc_hbd_img, &enc_img);
+        enc_img = enc_hbd_img;
       }
       if (dec_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) {
-        vpx_img_alloc(&dec_img, dec_img.fmt - VPX_IMG_FMT_HIGHBITDEPTH,
+        vpx_image_t dec_hbd_img;
+        vpx_img_alloc(&dec_hbd_img, dec_img.fmt - VPX_IMG_FMT_HIGHBITDEPTH,
                       dec_img.d_w, dec_img.d_h, 16);
-        vpx_img_truncate_16_to_8(&dec_img, &ref_dec.img);
+        vpx_img_truncate_16_to_8(&dec_hbd_img, &dec_img);
+        dec_img = dec_hbd_img;
       }
     }
 #endif