shithub: libvpx

Download patch

ref: bb7a2ccc38475ce0e70be134b5bf862000a3fc82
parent: e3ae48b861d18badb414c8fbe201e5c4aafb5180
author: angiebird <angiebird@google.com>
date: Fri Aug 7 11:44:08 EDT 2020

Fix ObserveFirstPassMotionVectors()

1) Use kRefFrameTypeNone in the unit test
2) Reset mv_info in fp_motion_vector_info_init
3) Call fp_motion_vector_info_init() in first_pass_encode()
4) Set mv_info for intra frame.
5) Set mv_info with zero mv as default for inter frame
6) Remove duplicated fp_motion_vector_info in encode_frame_info

Change-Id: I2f7db5cd4cf1f19db039c9ce638d17b832f45b6e

--- a/test/simple_encode_test.cc
+++ b/test/simple_encode_test.cc
@@ -74,8 +74,9 @@
     EXPECT_EQ(num_blocks, fps_motion_vectors[i].size());
     for (size_t j = 0; j < num_blocks; ++j) {
       const int mv_count = fps_motion_vectors[i][j].mv_count;
-      const int ref_count = (fps_motion_vectors[i][j].ref_frame[0] > 0) +
-                            (fps_motion_vectors[i][j].ref_frame[1] > 0);
+      const int ref_count =
+          (fps_motion_vectors[i][j].ref_frame[0] != kRefFrameTypeNone) +
+          (fps_motion_vectors[i][j].ref_frame[1] != kRefFrameTypeNone);
       EXPECT_EQ(mv_count, ref_count);
     }
   }
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -983,6 +983,13 @@
   cpi->partition_info = NULL;
 }
 
+static INLINE void reset_mv_info(MOTION_VECTOR_INFO *mv_info) {
+  mv_info->ref_frame[0] = NONE;
+  mv_info->ref_frame[1] = NONE;
+  mv_info->mv[0].as_int = INVALID_MV;
+  mv_info->mv[1].as_int = INVALID_MV;
+}
+
 // Allocates memory for the motion vector information.
 // The unit size is each 4x4 block.
 // Only called once in vp9_create_compressor().
@@ -1011,11 +1018,13 @@
   VP9_COMMON *const cm = &cpi->common;
   const int unit_width = get_num_unit_16x16(cpi->frame_info.frame_width);
   const int unit_height = get_num_unit_16x16(cpi->frame_info.frame_height);
+  int i;
   CHECK_MEM_ERROR(cm, cpi->fp_motion_vector_info,
                   (MOTION_VECTOR_INFO *)vpx_calloc(unit_width * unit_height,
                                                    sizeof(MOTION_VECTOR_INFO)));
-  memset(cpi->fp_motion_vector_info, 0,
-         unit_width * unit_height * sizeof(MOTION_VECTOR_INFO));
+  for (i = 0; i < unit_width * unit_height; ++i) {
+    reset_mv_info(cpi->fp_motion_vector_info + i);
+  }
 }
 
 // Frees memory of the first pass motion vector information.
@@ -1046,7 +1055,6 @@
   FRAME_COUNTS frame_counts;
   const PARTITION_INFO *partition_info;
   const MOTION_VECTOR_INFO *motion_vector_info;
-  const MOTION_VECTOR_INFO *fp_motion_vector_info;
   IMAGE_BUFFER coded_frame;
 #endif  // CONFIG_RATE_CTRL
   int quantize_index;
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -842,20 +842,16 @@
 #if CONFIG_RATE_CTRL
 static void store_fp_motion_vector(VP9_COMP *cpi, const MV *mv,
                                    const int mb_row, const int mb_col,
-                                   const int is_second_mv) {
+                                   MV_REFERENCE_FRAME frame_type,
+                                   const int mv_idx) {
   VP9_COMMON *const cm = &cpi->common;
   const int mb_index = mb_row * cm->mb_cols + mb_col;
   MOTION_VECTOR_INFO *this_motion_vector_info =
       &cpi->fp_motion_vector_info[mb_index];
-  if (!is_second_mv) {
-    this_motion_vector_info->ref_frame[0] = LAST_FRAME;
-    this_motion_vector_info->mv[0].as_mv.row = mv->row;
-    this_motion_vector_info->mv[0].as_mv.col = mv->col;
-    return;
+  this_motion_vector_info->ref_frame[mv_idx] = frame_type;
+  if (frame_type != INTRA_FRAME) {
+    this_motion_vector_info->mv[mv_idx].as_mv = *mv;
   }
-  this_motion_vector_info->ref_frame[1] = GOLDEN_FRAME;
-  this_motion_vector_info->mv[1].as_mv.row = mv->row;
-  this_motion_vector_info->mv[1].as_mv.col = mv->col;
 }
 #endif  // CONFIG_RATE_CTRL
 
@@ -1093,6 +1089,11 @@
       struct buf_2d unscaled_last_source_buf_2d;
       vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize];
 
+#if CONFIG_RATE_CTRL
+      // Store zero mv as default
+      store_fp_motion_vector(cpi, &mv, mb_row, mb_col, LAST_FRAME, 0);
+#endif  // CONFIG_RAGE_CTRL
+
       xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset;
 #if CONFIG_VP9_HIGHBITDEPTH
       if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
@@ -1158,7 +1159,7 @@
           }
         }
 #if CONFIG_RATE_CTRL
-        store_fp_motion_vector(cpi, &mv, mb_row, mb_col, /*is_second_mv=*/0);
+        store_fp_motion_vector(cpi, &mv, mb_row, mb_col, LAST_FRAME, 0);
 #endif  // CONFIG_RAGE_CTRL
 
         // Search in an older reference frame.
@@ -1182,8 +1183,7 @@
 
           first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv, &gf_motion_error);
 #if CONFIG_RATE_CTRL
-          store_fp_motion_vector(cpi, &tmp_mv, mb_row, mb_col,
-                                 /*is_second_mv=*/1);
+          store_fp_motion_vector(cpi, &tmp_mv, mb_row, mb_col, GOLDEN_FRAME, 1);
 #endif  // CONFIG_RAGE_CTRL
 
           if (gf_motion_error < motion_error && gf_motion_error < this_error)
@@ -1358,6 +1358,9 @@
       }
     } else {
       fp_acc_data->sr_coded_error += (int64_t)this_error;
+#if CONFIG_RATE_CTRL
+      store_fp_motion_vector(cpi, NULL, mb_row, mb_col, INTRA_FRAME, 0);
+#endif  // CONFIG_RAGE_CTRL
     }
     fp_acc_data->coded_error += (int64_t)this_error;
 
@@ -1383,6 +1386,10 @@
   MV best_ref_mv;
   // Tiling is ignored in the first pass.
   vp9_tile_init(tile, cm, 0, 0);
+
+#if CONFIG_RATE_CTRL
+  fp_motion_vector_info_init(cpi);
+#endif
 
   for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) {
     best_ref_mv = zero_mv;
--- a/vp9/simple_encode.cc
+++ b/vp9/simple_encode.cc
@@ -778,9 +778,8 @@
         assert(size == 0);
         // Get vp9 first pass motion vector info.
         std::vector<MotionVectorInfo> mv_info(num_rows_16x16 * num_cols_16x16);
-        update_motion_vector_info(&encode_frame_info.fp_motion_vector_info[0],
-                                  num_rows_16x16, num_cols_16x16,
-                                  mv_info.data());
+        update_motion_vector_info(cpi->fp_motion_vector_info, num_rows_16x16,
+                                  num_cols_16x16, mv_info.data());
         fp_motion_vector_info_.push_back(mv_info);
       }
       impl_ptr_->first_pass_stats.push_back(vp9_get_frame_stats(&cpi->twopass));