From bb7a2ccc38475ce0e70be134b5bf862000a3fc82 Mon Sep 17 00:00:00 2001 From: angiebird Date: Fri, 7 Aug 2020 15:44:08 -0700 Subject: [PATCH] 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 --- test/simple_encode_test.cc | 5 +++-- vp9/encoder/vp9_encoder.h | 14 +++++++++++--- vp9/encoder/vp9_firstpass.c | 31 +++++++++++++++++++------------ vp9/simple_encode.cc | 5 ++--- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/test/simple_encode_test.cc b/test/simple_encode_test.cc index 9a938a8d1..1790b56ac 100644 --- a/test/simple_encode_test.cc +++ b/test/simple_encode_test.cc @@ -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); } } diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index 3315a425c..3758ea3ae 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -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; diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 009bab7c5..384775507 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -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, diff --git a/vp9/simple_encode.cc b/vp9/simple_encode.cc index 678cf8add..4ee0bd2e8 100644 --- a/vp9/simple_encode.cc +++ b/vp9/simple_encode.cc @@ -778,9 +778,8 @@ void SimpleEncode::ComputeFirstPassStats() { assert(size == 0); // Get vp9 first pass motion vector info. std::vector 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)); -- 2.40.0