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
Unified · Split
| @@ -74,8 +74,9 @@ TEST_F(SimpleEncodeTest, ObserveFirstPassMotionVectors) { · 73 unmodified lines | ||
| 74 | 74 | EXPECT_EQ(num_blocks, fps_motion_vectors[i].size()); |
| 75 | 75 | for (size_t j = 0; j < num_blocks; ++j) { |
| 76 | 76 | const int mv_count = fps_motion_vectors[i][j].mv_count; |
| 77 | − const int ref_count = (fps_motion_vectors[i][j].ref_frame[0] > 0) + | |
| 78 | − (fps_motion_vectors[i][j].ref_frame[1] > 0); | |
| 77 | + const int ref_count = | |
| 78 | + (fps_motion_vectors[i][j].ref_frame[0] != kRefFrameTypeNone) + | |
| 79 | + (fps_motion_vectors[i][j].ref_frame[1] != kRefFrameTypeNone); | |
| 79 | 80 | EXPECT_EQ(mv_count, ref_count); |
| 80 | 81 | } |
| 81 | 82 | } |
| @@ -983,6 +983,13 @@ static INLINE void free_partition_info(struct VP9_COMP *cpi) { · 982 unmodified lines | ||
| 983 | 983 | cpi->partition_info = NULL; |
| 984 | 984 | } |
| 985 | 985 | |
| 986 | +static INLINE void reset_mv_info(MOTION_VECTOR_INFO *mv_info) { | |
| 987 | + mv_info->ref_frame[0] = NONE; | |
| 988 | + mv_info->ref_frame[1] = NONE; | |
| 989 | + mv_info->mv[0].as_int = INVALID_MV; | |
| 990 | + mv_info->mv[1].as_int = INVALID_MV; | |
| 991 | +} | |
| 992 | + | |
| 986 | 993 | // Allocates memory for the motion vector information. |
| 987 | 994 | // The unit size is each 4x4 block. |
| 988 | 995 | // Only called once in vp9_create_compressor(). |
| @@ -1011,11 +1018,13 @@ static INLINE void fp_motion_vector_info_init(struct VP9_COMP *cpi) { · 22 unmodified lines | ||
| 1011 | 1018 | VP9_COMMON *const cm = &cpi->common; |
| 1012 | 1019 | const int unit_width = get_num_unit_16x16(cpi->frame_info.frame_width); |
| 1013 | 1020 | const int unit_height = get_num_unit_16x16(cpi->frame_info.frame_height); |
| 1021 | + int i; | |
| 1014 | 1022 | CHECK_MEM_ERROR(cm, cpi->fp_motion_vector_info, |
| 1015 | 1023 | (MOTION_VECTOR_INFO *)vpx_calloc(unit_width * unit_height, |
| 1016 | 1024 | sizeof(MOTION_VECTOR_INFO))); |
| 1017 | − memset(cpi->fp_motion_vector_info, 0, | |
| 1018 | − unit_width * unit_height * sizeof(MOTION_VECTOR_INFO)); | |
| 1025 | + for (i = 0; i < unit_width * unit_height; ++i) { | |
| 1026 | + reset_mv_info(cpi->fp_motion_vector_info + i); | |
| 1027 | + } | |
| 1019 | 1028 | } |
| 1020 | 1029 | |
| 1021 | 1030 | // Frees memory of the first pass motion vector information. |
| @@ -1046,7 +1055,6 @@ typedef struct ENCODE_FRAME_RESULT { · 24 unmodified lines | ||
| 1046 | 1055 | FRAME_COUNTS frame_counts; |
| 1047 | 1056 | const PARTITION_INFO *partition_info; |
| 1048 | 1057 | const MOTION_VECTOR_INFO *motion_vector_info; |
| 1049 | − const MOTION_VECTOR_INFO *fp_motion_vector_info; | |
| 1050 | 1058 | IMAGE_BUFFER coded_frame; |
| 1051 | 1059 | #endif // CONFIG_RATE_CTRL |
| 1052 | 1060 | int quantize_index; |
| @@ -842,20 +842,16 @@ static void accumulate_fp_mb_row_stat(TileDataEnc *this_tile, · 841 unmodified lines | ||
| 842 | 842 | #if CONFIG_RATE_CTRL |
| 843 | 843 | static void store_fp_motion_vector(VP9_COMP *cpi, const MV *mv, |
| 844 | 844 | const int mb_row, const int mb_col, |
| 845 | − const int is_second_mv) { | |
| 845 | + MV_REFERENCE_FRAME frame_type, | |
| 846 | + const int mv_idx) { | |
| 846 | 847 | VP9_COMMON *const cm = &cpi->common; |
| 847 | 848 | const int mb_index = mb_row * cm->mb_cols + mb_col; |
| 848 | 849 | MOTION_VECTOR_INFO *this_motion_vector_info = |
| 849 | 850 | &cpi->fp_motion_vector_info[mb_index]; |
| 850 | − if (!is_second_mv) { | |
| 851 | − this_motion_vector_info->ref_frame[0] = LAST_FRAME; | |
| 852 | − this_motion_vector_info->mv[0].as_mv.row = mv->row; | |
| 853 | − this_motion_vector_info->mv[0].as_mv.col = mv->col; | |
| 854 | − return; | |
| 851 | + this_motion_vector_info->ref_frame[mv_idx] = frame_type; | |
| 852 | + if (frame_type != INTRA_FRAME) { | |
| 853 | + this_motion_vector_info->mv[mv_idx].as_mv = *mv; | |
| 855 | 854 | } |
| 856 | − this_motion_vector_info->ref_frame[1] = GOLDEN_FRAME; | |
| 857 | − this_motion_vector_info->mv[1].as_mv.row = mv->row; | |
| 858 | − this_motion_vector_info->mv[1].as_mv.col = mv->col; | |
| 859 | 855 | } |
| 860 | 856 | #endif // CONFIG_RATE_CTRL |
| 861 | 857 | |
| @@ -1093,6 +1089,11 @@ void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td, · 231 unmodified lines | ||
| 1093 | 1089 | struct buf_2d unscaled_last_source_buf_2d; |
| 1094 | 1090 | vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize]; |
| 1095 | 1091 | |
| 1092 | +#if CONFIG_RATE_CTRL | |
| 1093 | + // Store zero mv as default | |
| 1094 | + store_fp_motion_vector(cpi, &mv, mb_row, mb_col, LAST_FRAME, 0); | |
| 1095 | +#endif // CONFIG_RAGE_CTRL | |
| 1096 | + | |
| 1096 | 1097 | xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset; |
| 1097 | 1098 | #if CONFIG_VP9_HIGHBITDEPTH |
| 1098 | 1099 | 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, · 59 unmodified lines | ||
| 1158 | 1159 | } |
| 1159 | 1160 | } |
| 1160 | 1161 | #if CONFIG_RATE_CTRL |
| 1161 | − store_fp_motion_vector(cpi, &mv, mb_row, mb_col, /*is_second_mv=*/0); | |
| 1162 | + store_fp_motion_vector(cpi, &mv, mb_row, mb_col, LAST_FRAME, 0); | |
| 1162 | 1163 | #endif // CONFIG_RAGE_CTRL |
| 1163 | 1164 | |
| 1164 | 1165 | // Search in an older reference frame. |
| @@ -1182,8 +1183,7 @@ void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td, · 17 unmodified lines | ||
| 1182 | 1183 | |
| 1183 | 1184 | first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv, &gf_motion_error); |
| 1184 | 1185 | #if CONFIG_RATE_CTRL |
| 1185 | − store_fp_motion_vector(cpi, &tmp_mv, mb_row, mb_col, | |
| 1186 | − /*is_second_mv=*/1); | |
| 1186 | + store_fp_motion_vector(cpi, &tmp_mv, mb_row, mb_col, GOLDEN_FRAME, 1); | |
| 1187 | 1187 | #endif // CONFIG_RAGE_CTRL |
| 1188 | 1188 | |
| 1189 | 1189 | 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, · 168 unmodified lines | ||
| 1358 | 1358 | } |
| 1359 | 1359 | } else { |
| 1360 | 1360 | fp_acc_data->sr_coded_error += (int64_t)this_error; |
| 1361 | +#if CONFIG_RATE_CTRL | |
| 1362 | + store_fp_motion_vector(cpi, NULL, mb_row, mb_col, INTRA_FRAME, 0); | |
| 1363 | +#endif // CONFIG_RAGE_CTRL | |
| 1361 | 1364 | } |
| 1362 | 1365 | fp_acc_data->coded_error += (int64_t)this_error; |
| 1363 | 1366 | |
| @@ -1384,6 +1387,10 @@ static void first_pass_encode(VP9_COMP *cpi, FIRSTPASS_DATA *fp_acc_data) { · 20 unmodified lines | ||
| 1384 | 1387 | // Tiling is ignored in the first pass. |
| 1385 | 1388 | vp9_tile_init(tile, cm, 0, 0); |
| 1386 | 1389 | |
| 1390 | +#if CONFIG_RATE_CTRL | |
| 1391 | + fp_motion_vector_info_init(cpi); | |
| 1392 | +#endif | |
| 1393 | + | |
| 1387 | 1394 | for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) { |
| 1388 | 1395 | best_ref_mv = zero_mv; |
| 1389 | 1396 | vp9_first_pass_encode_tile_mb_row(cpi, &cpi->td, fp_acc_data, &tile_data, |
| @@ -778,9 +778,8 @@ void SimpleEncode::ComputeFirstPassStats() { · 777 unmodified lines | ||
| 778 | 778 | assert(size == 0); |
| 779 | 779 | // Get vp9 first pass motion vector info. |
| 780 | 780 | std::vector<MotionVectorInfo> mv_info(num_rows_16x16 * num_cols_16x16); |
| 781 | − update_motion_vector_info(&encode_frame_info.fp_motion_vector_info[0], | |
| 782 | − num_rows_16x16, num_cols_16x16, | |
| 783 | − mv_info.data()); | |
| 781 | + update_motion_vector_info(cpi->fp_motion_vector_info, num_rows_16x16, | |
| 782 | + num_cols_16x16, mv_info.data()); | |
| 784 | 783 | fp_motion_vector_info_.push_back(mv_info); |
| 785 | 784 | } |
| 786 | 785 | impl_ptr_->first_pass_stats.push_back(vp9_get_frame_stats(&cpi->twopass)); |