]> granicus.if.org Git - libvpx/commitdiff
Fix ObserveFirstPassMotionVectors()
authorangiebird <angiebird@google.com>
Fri, 7 Aug 2020 22:44:08 +0000 (15:44 -0700)
committerangiebird <angiebird@google.com>
Fri, 7 Aug 2020 22:48:32 +0000 (15:48 -0700)
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

test/simple_encode_test.cc
vp9/encoder/vp9_encoder.h
vp9/encoder/vp9_firstpass.c
vp9/simple_encode.cc

index 9a938a8d1e201c898bdff2b318411f4e25a60481..1790b56ac31836976d386a33d8de682172d50706 100644 (file)
@@ -74,8 +74,9 @@ TEST_F(SimpleEncodeTest, ObserveFirstPassMotionVectors) {
     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);
     }
   }
index 3315a425ccc40ece849ea7bd6bd3fb7ae123140b..3758ea3aea9397696ceaac8a039bb24529cdd9f8 100644 (file)
@@ -983,6 +983,13 @@ static INLINE void free_partition_info(struct VP9_COMP *cpi) {
   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 @@ static INLINE void fp_motion_vector_info_init(struct VP9_COMP *cpi) {
   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 @@ typedef struct ENCODE_FRAME_RESULT {
   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;
index 009bab7c50336eebac64043ea2aecbf47c53c88a..3847755073461db2b1c60c8742e6692f9cbf3960 100644 (file)
@@ -842,20 +842,16 @@ static void accumulate_fp_mb_row_stat(TileDataEnc *this_tile,
 #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 @@ void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td,
       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 @@ void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td,
           }
         }
 #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 @@ void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td,
 
           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 @@ void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td,
       }
     } 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;
 
@@ -1384,6 +1387,10 @@ static void first_pass_encode(VP9_COMP *cpi, FIRSTPASS_DATA *fp_acc_data) {
   // 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;
     vp9_first_pass_encode_tile_mb_row(cpi, &cpi->td, fp_acc_data, &tile_data,
index 678cf8adde5cee3919fa82cdf9cb90f2b13fd46e..4ee0bd2e8461a9e185f703d0a4699c6a5289c1d1 100644 (file)
@@ -778,9 +778,8 @@ void SimpleEncode::ComputeFirstPassStats() {
         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));