diff options
Diffstat (limited to 'vp9')
-rw-r--r-- | vp9/encoder/vp9_encoder.c | 171 | ||||
-rw-r--r-- | vp9/encoder/vp9_encoder.h | 15 | ||||
-rw-r--r-- | vp9/encoder/vp9_mcomp.c | 31 | ||||
-rw-r--r-- | vp9/encoder/vp9_mcomp.h | 5 | ||||
-rw-r--r-- | vp9/encoder/vp9_non_greedy_mv.c | 67 | ||||
-rw-r--r-- | vp9/encoder/vp9_non_greedy_mv.h | 21 | ||||
-rw-r--r-- | vp9/encoder/vp9_rdopt.c | 14 |
7 files changed, 189 insertions, 135 deletions
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index d66e30024..1357573d2 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -5874,10 +5874,11 @@ static void init_tpl_stats(VP9_COMP *cpi) { #if CONFIG_NON_GREEDY_MV static uint32_t full_pixel_motion_search(VP9_COMP *cpi, ThreadData *td, + MotionField *motion_field, int frame_idx, uint8_t *cur_frame_buf, uint8_t *ref_frame_buf, int stride, BLOCK_SIZE bsize, int mi_row, - int mi_col, MV *mv, int rf_idx) { + int mi_col, MV *mv) { MACROBLOCK *const x = &td->mb; MACROBLOCKD *const xd = &x->e_mbd; MV_SPEED_FEATURES *const mv_sf = &cpi->sf.mv; @@ -5907,8 +5908,8 @@ static uint32_t full_pixel_motion_search(VP9_COMP *cpi, ThreadData *td, vp9_set_mv_search_range(&x->mv_limits, &best_ref_mv1); - nb_full_mv_num = vp9_prepare_nb_full_mvs(&cpi->tpl_stats[frame_idx], mi_row, - mi_col, rf_idx, bsize, nb_full_mvs); + nb_full_mv_num = + vp9_prepare_nb_full_mvs(motion_field, mi_row, mi_col, nb_full_mvs); vp9_full_pixel_diamond_new(cpi, x, bsize, &best_ref_mv1_full, step_param, lambda, 1, nb_full_mvs, nb_full_mv_num, mv); @@ -6285,12 +6286,16 @@ static void mode_estimation(VP9_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd, for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) { int_mv mv; +#if CONFIG_NON_GREEDY_MV + MotionField *motion_field; +#endif if (ref_frame[rf_idx] == NULL) continue; #if CONFIG_NON_GREEDY_MV (void)td; - mv.as_int = - get_pyramid_mv(tpl_frame, rf_idx, bsize, mi_row, mi_col)->as_int; + motion_field = vp9_motion_field_info_get_motion_field( + &cpi->motion_field_info, frame_idx, rf_idx, bsize); + mv = vp9_motion_field_mi_get_mv(motion_field, mi_row, mi_col); #else motion_compensated_prediction(cpi, td, xd->cur_buf->y_buffer + mb_y_offset, ref_frame[rf_idx]->y_buffer + mb_y_offset, @@ -6436,8 +6441,9 @@ static int_mv find_ref_mv(int mv_mode, VP9_COMP *cpi, TplDepFrame *tpl_frame, } static int_mv get_mv_from_mv_mode(int mv_mode, VP9_COMP *cpi, - TplDepFrame *tpl_frame, int rf_idx, - BLOCK_SIZE bsize, int mi_row, int mi_col) { + MotionField *motion_field, + TplDepFrame *tpl_frame, BLOCK_SIZE bsize, + int mi_row, int mi_col) { int_mv mv; switch (mv_mode) { case ZERO_MV_MODE: @@ -6445,7 +6451,7 @@ static int_mv get_mv_from_mv_mode(int mv_mode, VP9_COMP *cpi, mv.as_mv.col = 0; break; case NEW_MV_MODE: - mv = *get_pyramid_mv(tpl_frame, rf_idx, bsize, mi_row, mi_col); + mv = vp9_motion_field_mi_get_mv(motion_field, mi_row, mi_col); break; case NEAREST_MV_MODE: mv = find_ref_mv(mv_mode, cpi, tpl_frame, bsize, mi_row, mi_col); @@ -6462,15 +6468,16 @@ static int_mv get_mv_from_mv_mode(int mv_mode, VP9_COMP *cpi, } static double get_mv_dist(int mv_mode, VP9_COMP *cpi, MACROBLOCKD *xd, - GF_PICTURE *gf_picture, int frame_idx, - TplDepFrame *tpl_frame, int rf_idx, BLOCK_SIZE bsize, - int mi_row, int mi_col, int_mv *mv) { + GF_PICTURE *gf_picture, MotionField *motion_field, + int frame_idx, TplDepFrame *tpl_frame, int rf_idx, + BLOCK_SIZE bsize, int mi_row, int mi_col, + int_mv *mv) { uint32_t sse; struct buf_2d src; struct buf_2d pre; MV full_mv; - *mv = get_mv_from_mv_mode(mv_mode, cpi, tpl_frame, rf_idx, bsize, mi_row, - mi_col); + *mv = get_mv_from_mv_mode(mv_mode, cpi, motion_field, tpl_frame, bsize, + mi_row, mi_col); full_mv = get_full_mv(&mv->as_mv); if (get_block_src_pred_buf(xd, gf_picture, frame_idx, rf_idx, mi_row, mi_col, &src, &pre)) { @@ -6507,18 +6514,18 @@ static INLINE double get_mv_diff_cost(MV *new_mv, MV *ref_mv) { mv_diff_cost *= (1 << VP9_PROB_COST_SHIFT); return mv_diff_cost; } -static double get_mv_cost(int mv_mode, VP9_COMP *cpi, TplDepFrame *tpl_frame, - int rf_idx, BLOCK_SIZE bsize, int mi_row, +static double get_mv_cost(int mv_mode, VP9_COMP *cpi, MotionField *motion_field, + TplDepFrame *tpl_frame, BLOCK_SIZE bsize, int mi_row, int mi_col) { double mv_cost = get_mv_mode_cost(mv_mode); if (mv_mode == NEW_MV_MODE) { - MV new_mv = get_mv_from_mv_mode(mv_mode, cpi, tpl_frame, rf_idx, bsize, - mi_row, mi_col) + MV new_mv = get_mv_from_mv_mode(mv_mode, cpi, motion_field, tpl_frame, + bsize, mi_row, mi_col) .as_mv; - MV nearest_mv = get_mv_from_mv_mode(NEAREST_MV_MODE, cpi, tpl_frame, rf_idx, - bsize, mi_row, mi_col) + MV nearest_mv = get_mv_from_mv_mode(NEAREST_MV_MODE, cpi, motion_field, + tpl_frame, bsize, mi_row, mi_col) .as_mv; - MV near_mv = get_mv_from_mv_mode(NEAR_MV_MODE, cpi, tpl_frame, rf_idx, + MV near_mv = get_mv_from_mv_mode(NEAR_MV_MODE, cpi, motion_field, tpl_frame, bsize, mi_row, mi_col) .as_mv; double nearest_cost = get_mv_diff_cost(&new_mv, &nearest_mv); @@ -6529,21 +6536,24 @@ static double get_mv_cost(int mv_mode, VP9_COMP *cpi, TplDepFrame *tpl_frame, } static double eval_mv_mode(int mv_mode, VP9_COMP *cpi, MACROBLOCK *x, - GF_PICTURE *gf_picture, int frame_idx, - TplDepFrame *tpl_frame, int rf_idx, BLOCK_SIZE bsize, - int mi_row, int mi_col, int_mv *mv) { + GF_PICTURE *gf_picture, MotionField *motion_field, + int frame_idx, TplDepFrame *tpl_frame, int rf_idx, + BLOCK_SIZE bsize, int mi_row, int mi_col, + int_mv *mv) { MACROBLOCKD *xd = &x->e_mbd; - double mv_dist = get_mv_dist(mv_mode, cpi, xd, gf_picture, frame_idx, - tpl_frame, rf_idx, bsize, mi_row, mi_col, mv); + double mv_dist = + get_mv_dist(mv_mode, cpi, xd, gf_picture, motion_field, frame_idx, + tpl_frame, rf_idx, bsize, mi_row, mi_col, mv); double mv_cost = - get_mv_cost(mv_mode, cpi, tpl_frame, rf_idx, bsize, mi_row, mi_col); + get_mv_cost(mv_mode, cpi, motion_field, tpl_frame, bsize, mi_row, mi_col); double mult = 180; return mv_cost + mult * log2f(1 + mv_dist); } static int find_best_ref_mv_mode(VP9_COMP *cpi, MACROBLOCK *x, - GF_PICTURE *gf_picture, int frame_idx, + GF_PICTURE *gf_picture, + MotionField *motion_field, int frame_idx, TplDepFrame *tpl_frame, int rf_idx, BLOCK_SIZE bsize, int mi_row, int mi_col, double *rd, int_mv *mv) { @@ -6557,8 +6567,8 @@ static int find_best_ref_mv_mode(VP9_COMP *cpi, MACROBLOCK *x, if (mv_mode == NEW_MV_MODE) { continue; } - this_rd = eval_mv_mode(mv_mode, cpi, x, gf_picture, frame_idx, tpl_frame, - rf_idx, bsize, mi_row, mi_col, &this_mv); + this_rd = eval_mv_mode(mv_mode, cpi, x, gf_picture, motion_field, frame_idx, + tpl_frame, rf_idx, bsize, mi_row, mi_col, &this_mv); if (update == 0) { *rd = this_rd; *mv = this_mv; @@ -6576,8 +6586,8 @@ static int find_best_ref_mv_mode(VP9_COMP *cpi, MACROBLOCK *x, } static void predict_mv_mode(VP9_COMP *cpi, MACROBLOCK *x, - GF_PICTURE *gf_picture, int frame_idx, - TplDepFrame *tpl_frame, int rf_idx, + GF_PICTURE *gf_picture, MotionField *motion_field, + int frame_idx, TplDepFrame *tpl_frame, int rf_idx, BLOCK_SIZE bsize, int mi_row, int mi_col) { const int mi_height = num_8x8_blocks_high_lookup[bsize]; const int mi_width = num_8x8_blocks_wide_lookup[bsize]; @@ -6607,9 +6617,9 @@ static void predict_mv_mode(VP9_COMP *cpi, MACROBLOCK *x, if (nb_row < tpl_frame->mi_rows && nb_col < tpl_frame->mi_cols) { double this_rd; int_mv *mv = &select_mv_arr[nb_row * stride + nb_col]; - mv_mode_arr[nb_row * stride + nb_col] = - find_best_ref_mv_mode(cpi, x, gf_picture, frame_idx, tpl_frame, - rf_idx, bsize, nb_row, nb_col, &this_rd, mv); + mv_mode_arr[nb_row * stride + nb_col] = find_best_ref_mv_mode( + cpi, x, gf_picture, motion_field, frame_idx, tpl_frame, rf_idx, + bsize, nb_row, nb_col, &this_rd, mv); if (r == 0 && c == 0) { this_no_new_mv_rd = this_rd; } @@ -6623,9 +6633,9 @@ static void predict_mv_mode(VP9_COMP *cpi, MACROBLOCK *x, // new mv mv_mode_arr[mi_row * stride + mi_col] = NEW_MV_MODE; - this_new_mv_rd = eval_mv_mode(NEW_MV_MODE, cpi, x, gf_picture, frame_idx, - tpl_frame, rf_idx, bsize, mi_row, mi_col, - &select_mv_arr[mi_row * stride + mi_col]); + this_new_mv_rd = eval_mv_mode( + NEW_MV_MODE, cpi, x, gf_picture, motion_field, frame_idx, tpl_frame, + rf_idx, bsize, mi_row, mi_col, &select_mv_arr[mi_row * stride + mi_col]); new_mv_rd = this_new_mv_rd; // We start from idx = 1 because idx = 0 is evaluated as NEW_MV_MODE // beforehand. @@ -6638,9 +6648,9 @@ static void predict_mv_mode(VP9_COMP *cpi, MACROBLOCK *x, if (nb_row < tpl_frame->mi_rows && nb_col < tpl_frame->mi_cols) { double this_rd; int_mv *mv = &select_mv_arr[nb_row * stride + nb_col]; - mv_mode_arr[nb_row * stride + nb_col] = - find_best_ref_mv_mode(cpi, x, gf_picture, frame_idx, tpl_frame, - rf_idx, bsize, nb_row, nb_col, &this_rd, mv); + mv_mode_arr[nb_row * stride + nb_col] = find_best_ref_mv_mode( + cpi, x, gf_picture, motion_field, frame_idx, tpl_frame, rf_idx, + bsize, nb_row, nb_col, &this_rd, mv); new_mv_rd += this_rd; } } @@ -6670,7 +6680,8 @@ static void predict_mv_mode(VP9_COMP *cpi, MACROBLOCK *x, } static void predict_mv_mode_arr(VP9_COMP *cpi, MACROBLOCK *x, - GF_PICTURE *gf_picture, int frame_idx, + GF_PICTURE *gf_picture, + MotionField *motion_field, int frame_idx, TplDepFrame *tpl_frame, int rf_idx, BLOCK_SIZE bsize) { const int mi_height = num_8x8_blocks_high_lookup[bsize]; @@ -6689,8 +6700,8 @@ static void predict_mv_mode_arr(VP9_COMP *cpi, MACROBLOCK *x, assert(c >= 0 && c < unit_cols); assert(mi_row >= 0 && mi_row < tpl_frame->mi_rows); assert(mi_col >= 0 && mi_col < tpl_frame->mi_cols); - predict_mv_mode(cpi, x, gf_picture, frame_idx, tpl_frame, rf_idx, bsize, - mi_row, mi_col); + predict_mv_mode(cpi, x, gf_picture, motion_field, frame_idx, tpl_frame, + rf_idx, bsize, mi_row, mi_col); } } } @@ -6731,29 +6742,28 @@ static int compare_feature_score(const void *a, const void *b) { } } -static void do_motion_search(VP9_COMP *cpi, ThreadData *td, int frame_idx, +static void do_motion_search(VP9_COMP *cpi, ThreadData *td, + MotionField *motion_field, int frame_idx, YV12_BUFFER_CONFIG *ref_frame, BLOCK_SIZE bsize, - int mi_row, int mi_col, int rf_idx) { + int mi_row, int mi_col) { VP9_COMMON *cm = &cpi->common; MACROBLOCK *x = &td->mb; MACROBLOCKD *xd = &x->e_mbd; - TplDepFrame *tpl_frame = &cpi->tpl_stats[frame_idx]; - TplDepStats *tpl_stats = - &tpl_frame->tpl_stats_ptr[mi_row * tpl_frame->stride + mi_col]; const int mb_y_offset = mi_row * MI_SIZE * xd->cur_buf->y_stride + mi_col * MI_SIZE; assert(ref_frame != NULL); set_mv_limits(cm, x, mi_row, mi_col); - tpl_stats->ready[rf_idx] = 1; { - int_mv *mv = get_pyramid_mv(tpl_frame, rf_idx, bsize, mi_row, mi_col); + int_mv mv = vp9_motion_field_mi_get_mv(motion_field, mi_row, mi_col); uint8_t *cur_frame_buf = xd->cur_buf->y_buffer + mb_y_offset; uint8_t *ref_frame_buf = ref_frame->y_buffer + mb_y_offset; const int stride = xd->cur_buf->y_stride; - full_pixel_motion_search(cpi, td, frame_idx, cur_frame_buf, ref_frame_buf, - stride, bsize, mi_row, mi_col, &mv->as_mv, rf_idx); + full_pixel_motion_search(cpi, td, motion_field, frame_idx, cur_frame_buf, + ref_frame_buf, stride, bsize, mi_row, mi_col, + &mv.as_mv); sub_pixel_motion_search(cpi, td, cur_frame_buf, ref_frame_buf, stride, - bsize, &mv->as_mv); + bsize, &mv.as_mv); + vp9_motion_field_mi_set_mv(motion_field, mi_row, mi_col, mv); } } @@ -6861,14 +6871,11 @@ static void build_motion_field( mi_row * MI_SIZE * xd->cur_buf->y_stride + mi_col * MI_SIZE; const int bw = 4 << b_width_log2_lookup[bsize]; const int bh = 4 << b_height_log2_lookup[bsize]; - TplDepStats *tpl_stats = - &tpl_frame->tpl_stats_ptr[mi_row * tpl_frame->stride + mi_col]; FEATURE_SCORE_LOC *fs_loc = &cpi->feature_score_loc_arr[mi_row * tpl_frame->stride + mi_col]; - tpl_stats->feature_score = get_feature_score( + fs_loc->feature_score = get_feature_score( xd->cur_buf->y_buffer + mb_y_offset, xd->cur_buf->y_stride, bw, bh); fs_loc->visited = 0; - fs_loc->feature_score = tpl_stats->feature_score; fs_loc->mi_row = mi_row; fs_loc->mi_col = mi_col; cpi->feature_score_loc_sort[fs_loc_sort_size] = fs_loc; @@ -6879,28 +6886,21 @@ static void build_motion_field( qsort(cpi->feature_score_loc_sort, fs_loc_sort_size, sizeof(*cpi->feature_score_loc_sort), compare_feature_score); - for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) { - for (mi_row = 0; mi_row < cm->mi_rows; mi_row += mi_height) { - for (mi_col = 0; mi_col < cm->mi_cols; mi_col += mi_width) { - TplDepStats *tpl_stats = - &tpl_frame->tpl_stats_ptr[mi_row * tpl_frame->stride + mi_col]; - tpl_stats->ready[rf_idx] = 0; - } - } - } - // TODO(angiebird): Clean up this part. for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) { int i; + MotionField *motion_field = vp9_motion_field_info_get_motion_field( + &cpi->motion_field_info, frame_idx, rf_idx, bsize); if (ref_frame[rf_idx] == NULL) { continue; } + vp9_motion_field_reset_mvs(motion_field); #if CHANGE_MV_SEARCH_ORDER #if !USE_PQSORT for (i = 0; i < fs_loc_sort_size; ++i) { FEATURE_SCORE_LOC *fs_loc = cpi->feature_score_loc_sort[i]; - do_motion_search(cpi, td, frame_idx, ref_frame[rf_idx], bsize, - fs_loc->mi_row, fs_loc->mi_col, rf_idx); + do_motion_search(cpi, td, motion_field, frame_idx, ref_frame[rf_idx], + bsize, fs_loc->mi_row, fs_loc->mi_col); } #else // !USE_PQSORT fs_loc_heap_size = 0; @@ -6915,8 +6915,8 @@ static void build_motion_field( FEATURE_SCORE_LOC *fs_loc; max_heap_pop(cpi->feature_score_loc_heap, &fs_loc_heap_size, &fs_loc); - do_motion_search(cpi, td, frame_idx, ref_frame[rf_idx], bsize, - fs_loc->mi_row, fs_loc->mi_col, rf_idx); + do_motion_search(cpi, td, motion_field, frame_idx, ref_frame[rf_idx], + bsize, fs_loc->mi_row, fs_loc->mi_col); add_nb_blocks_to_heap(cpi, tpl_frame, bsize, fs_loc->mi_row, fs_loc->mi_col, &fs_loc_heap_size); @@ -6925,8 +6925,8 @@ static void build_motion_field( #else // CHANGE_MV_SEARCH_ORDER for (mi_row = 0; mi_row < cm->mi_rows; mi_row += mi_height) { for (mi_col = 0; mi_col < cm->mi_cols; mi_col += mi_width) { - do_motion_search(cpi, td, frame_idx, ref_frame[rf_idx], bsize, mi_row, - mi_col, rf_idx); + do_motion_search(cpi, td, motion_field, frame_idx, ref_frame[rf_idx], + bsize, mi_row, mi_col); } } #endif // CHANGE_MV_SEARCH_ORDER @@ -7016,8 +7016,10 @@ static void mc_flow_dispenser(VP9_COMP *cpi, GF_PICTURE *gf_picture, for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) { int ref_frame_idx = gf_picture[frame_idx].ref_frame[rf_idx]; if (ref_frame_idx != -1) { - predict_mv_mode_arr(cpi, x, gf_picture, frame_idx, tpl_frame, rf_idx, - bsize); + MotionField *motion_field = vp9_motion_field_info_get_motion_field( + &cpi->motion_field_info, frame_idx, rf_idx, bsize); + predict_mv_mode_arr(cpi, x, gf_picture, motion_field, frame_idx, + tpl_frame, rf_idx, bsize); } } #endif @@ -7088,8 +7090,9 @@ static void dump_tpl_stats(const VP9_COMP *cpi, int tpl_group_frames, for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row) { for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) { if ((mi_row % mi_height) == 0 && (mi_col % mi_width) == 0) { - int_mv mv = - *get_pyramid_mv(tpl_frame, rf_idx, bsize, mi_row, mi_col); + int_mv mv = vp9_motion_field_info_get_mv(&cpi->motion_field_info, + frame_idx, rf_idx, bsize, + mi_row, mi_col); printf("%d %d %d %d\n", mi_row, mi_col, mv.as_mv.row, mv.as_mv.col); } @@ -7133,7 +7136,6 @@ static void init_tpl_buffer(VP9_COMP *cpi) { const int mi_cols = mi_cols_aligned_to_sb(cm->mi_cols); const int mi_rows = mi_cols_aligned_to_sb(cm->mi_rows); #if CONFIG_NON_GREEDY_MV - int sqr_bsize; int rf_idx; // TODO(angiebird): This probably needs further modifications to support @@ -7170,15 +7172,6 @@ static void init_tpl_buffer(VP9_COMP *cpi) { #if CONFIG_NON_GREEDY_MV for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) { - for (sqr_bsize = 0; sqr_bsize < SQUARE_BLOCK_SIZES; ++sqr_bsize) { - vpx_free(cpi->tpl_stats[frame].pyramid_mv_arr[rf_idx][sqr_bsize]); - CHECK_MEM_ERROR( - cm, cpi->tpl_stats[frame].pyramid_mv_arr[rf_idx][sqr_bsize], - vpx_calloc( - mi_rows * mi_cols * 4, - sizeof( - *cpi->tpl_stats[frame].pyramid_mv_arr[rf_idx][sqr_bsize]))); - } vpx_free(cpi->tpl_stats[frame].mv_mode_arr[rf_idx]); CHECK_MEM_ERROR( cm, cpi->tpl_stats[frame].mv_mode_arr[rf_idx], @@ -7222,10 +7215,6 @@ static void free_tpl_buffer(VP9_COMP *cpi) { #if CONFIG_NON_GREEDY_MV int rf_idx; for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) { - int sqr_bsize; - for (sqr_bsize = 0; sqr_bsize < SQUARE_BLOCK_SIZES; ++sqr_bsize) { - vpx_free(cpi->tpl_stats[frame].pyramid_mv_arr[rf_idx][sqr_bsize]); - } vpx_free(cpi->tpl_stats[frame].mv_mode_arr[rf_idx]); vpx_free(cpi->tpl_stats[frame].rd_diff_arr[rf_idx]); } diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index 7e956a6df..bf29048de 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -293,12 +293,6 @@ typedef struct TplDepStats { int ref_frame_index; int_mv mv; - -#if CONFIG_NON_GREEDY_MV - int ready[3]; - int64_t sse_arr[3]; - double feature_score; -#endif } TplDepStats; #if CONFIG_NON_GREEDY_MV @@ -321,20 +315,11 @@ typedef struct TplDepFrame { int base_qindex; #if CONFIG_NON_GREEDY_MV int lambda; - int_mv *pyramid_mv_arr[3][SQUARE_BLOCK_SIZES]; int *mv_mode_arr[3]; double *rd_diff_arr[3]; #endif } TplDepFrame; -#if CONFIG_NON_GREEDY_MV -static INLINE int_mv *get_pyramid_mv(const TplDepFrame *tpl_frame, int rf_idx, - BLOCK_SIZE bsize, int mi_row, int mi_col) { - return &tpl_frame->pyramid_mv_arr[rf_idx][get_square_block_idx(bsize)] - [mi_row * tpl_frame->stride + mi_col]; -} -#endif - #define TPL_DEP_COST_SCALE_LOG2 4 // TODO(jingning) All spatially adaptive variables should go to TileDataEnc. diff --git a/vp9/encoder/vp9_mcomp.c b/vp9/encoder/vp9_mcomp.c index b6e3090e7..ac29f36ec 100644 --- a/vp9/encoder/vp9_mcomp.c +++ b/vp9/encoder/vp9_mcomp.c @@ -2055,26 +2055,25 @@ static int64_t diamond_search_sad_new(const MACROBLOCK *x, return bestsad; } -int vp9_prepare_nb_full_mvs(const TplDepFrame *tpl_frame, int mi_row, - int mi_col, int rf_idx, BLOCK_SIZE bsize, - int_mv *nb_full_mvs) { - const int mi_width = num_8x8_blocks_wide_lookup[bsize]; - const int mi_height = num_8x8_blocks_high_lookup[bsize]; +int vp9_prepare_nb_full_mvs(const MotionField *motion_field, int mi_row, + int mi_col, int_mv *nb_full_mvs) { + const int mi_width = num_8x8_blocks_wide_lookup[motion_field->bsize]; + const int mi_height = num_8x8_blocks_high_lookup[motion_field->bsize]; const int dirs[NB_MVS_NUM][2] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } }; int nb_full_mv_num = 0; int i; + assert(mi_row % mi_height == 0); + assert(mi_col % mi_width == 0); for (i = 0; i < NB_MVS_NUM; ++i) { - int r = dirs[i][0] * mi_height; - int c = dirs[i][1] * mi_width; - if (mi_row + r >= 0 && mi_row + r < tpl_frame->mi_rows && mi_col + c >= 0 && - mi_col + c < tpl_frame->mi_cols) { - const TplDepStats *tpl_ptr = - &tpl_frame - ->tpl_stats_ptr[(mi_row + r) * tpl_frame->stride + mi_col + c]; - if (tpl_ptr->ready[rf_idx]) { - int_mv *mv = - get_pyramid_mv(tpl_frame, rf_idx, bsize, mi_row + r, mi_col + c); - nb_full_mvs[nb_full_mv_num].as_mv = get_full_mv(&mv->as_mv); + int r = dirs[i][0]; + int c = dirs[i][1]; + int brow = mi_row / mi_height + r; + int bcol = mi_col / mi_width + c; + if (brow >= 0 && brow < motion_field->block_rows && bcol >= 0 && + bcol < motion_field->block_cols) { + if (vp9_motion_field_is_mv_set(motion_field, brow, bcol)) { + int_mv mv = vp9_motion_field_get_mv(motion_field, brow, bcol); + nb_full_mvs[nb_full_mv_num].as_mv = get_full_mv(&mv.as_mv); ++nb_full_mv_num; } } diff --git a/vp9/encoder/vp9_mcomp.h b/vp9/encoder/vp9_mcomp.h index 6f460414e..0c4d8f23c 100644 --- a/vp9/encoder/vp9_mcomp.h +++ b/vp9/encoder/vp9_mcomp.h @@ -148,9 +148,8 @@ static INLINE MV get_full_mv(const MV *mv) { return out_mv; } struct TplDepFrame; -int vp9_prepare_nb_full_mvs(const struct TplDepFrame *tpl_frame, int mi_row, - int mi_col, int rf_idx, BLOCK_SIZE bsize, - int_mv *nb_full_mvs); +int vp9_prepare_nb_full_mvs(const struct MotionField *motion_field, int mi_row, + int mi_col, int_mv *nb_full_mvs); static INLINE BLOCK_SIZE get_square_block_size(BLOCK_SIZE bsize) { BLOCK_SIZE square_bsize; diff --git a/vp9/encoder/vp9_non_greedy_mv.c b/vp9/encoder/vp9_non_greedy_mv.c index 4ea06316d..1b6e64589 100644 --- a/vp9/encoder/vp9_non_greedy_mv.c +++ b/vp9/encoder/vp9_non_greedy_mv.c @@ -171,7 +171,7 @@ static int mi_size_to_block_size(int mi_bsize, int mi_num) { Status vp9_alloc_motion_field_info(MotionFieldInfo *motion_field_info, int frame_num, int mi_rows, int mi_cols) { int frame_idx, rf_idx, square_block_idx; - if (motion_field_info->allocated == 1) { + if (motion_field_info->allocated) { // TODO(angiebird): Avoid re-allocate buffer if possible vp9_free_motion_field_info(motion_field_info); } @@ -210,14 +210,21 @@ Status vp9_alloc_motion_field(MotionField *motion_field, BLOCK_SIZE bsize, motion_field->bsize = bsize; motion_field->block_rows = block_rows; motion_field->block_cols = block_cols; + motion_field->block_num = block_rows * block_cols; motion_field->mf = - vpx_calloc(block_rows * block_cols, sizeof(*motion_field->mf)); + vpx_calloc(motion_field->block_num, sizeof(*motion_field->mf)); if (motion_field->mf == NULL) { assert(0); status = STATUS_FAILED; } + motion_field->set_mv = + vpx_calloc(motion_field->block_num, sizeof(*motion_field->set_mv)); + if (motion_field->set_mv == NULL) { + assert(0); + status = STATUS_FAILED; + } motion_field->local_structure = vpx_calloc( - block_rows * block_cols, sizeof(*motion_field->local_structure)); + motion_field->block_num, sizeof(*motion_field->local_structure)); if (motion_field->local_structure == NULL) { assert(0); status = STATUS_FAILED; @@ -252,6 +259,60 @@ void vp9_free_motion_field_info(MotionFieldInfo *motion_field_info) { } } +MotionField *vp9_motion_field_info_get_motion_field( + MotionFieldInfo *motion_field_info, int frame_idx, int rf_idx, + BLOCK_SIZE bsize) { + int square_block_idx = get_square_block_idx(bsize); + assert(frame_idx < motion_field_info->frame_num); + assert(motion_field_info->allocated == 1); + return &motion_field_info + ->motion_field_array[frame_idx][rf_idx][square_block_idx]; +} + +int vp9_motion_field_is_mv_set(const MotionField *motion_field, int brow, + int bcol) { + assert(brow >= 0 && brow < motion_field->block_rows); + assert(bcol >= 0 && bcol < motion_field->block_cols); + return motion_field->set_mv[brow * motion_field->block_cols + bcol]; +} + +int_mv vp9_motion_field_get_mv(const MotionField *motion_field, int brow, + int bcol) { + assert(brow >= 0 && brow < motion_field->block_rows); + assert(bcol >= 0 && bcol < motion_field->block_cols); + return motion_field->mf[brow * motion_field->block_cols + bcol]; +} + +int_mv vp9_motion_field_mi_get_mv(const MotionField *motion_field, int mi_row, + int mi_col) { + const int mi_height = num_8x8_blocks_high_lookup[motion_field->bsize]; + const int mi_width = num_8x8_blocks_wide_lookup[motion_field->bsize]; + const int brow = mi_row / mi_height; + const int bcol = mi_col / mi_width; + assert(mi_row % mi_height == 0); + assert(mi_col % mi_width == 0); + return vp9_motion_field_get_mv(motion_field, brow, bcol); +} + +void vp9_motion_field_mi_set_mv(MotionField *motion_field, int mi_row, + int mi_col, int_mv mv) { + const int mi_height = num_8x8_blocks_high_lookup[motion_field->bsize]; + const int mi_width = num_8x8_blocks_wide_lookup[motion_field->bsize]; + const int brow = mi_row / mi_height; + const int bcol = mi_col / mi_width; + assert(mi_row % mi_height == 0); + assert(mi_col % mi_width == 0); + assert(brow >= 0 && brow < motion_field->block_rows); + assert(bcol >= 0 && bcol < motion_field->block_cols); + motion_field->mf[brow * motion_field->block_cols + bcol] = mv; + motion_field->set_mv[brow * motion_field->block_cols + bcol] = 1; +} + +void vp9_motion_field_reset_mvs(MotionField *motion_field) { + memset(motion_field->set_mv, 0, + motion_field->block_num * sizeof(*motion_field->set_mv)); +} + static int64_t log2_approximation(int64_t v) { assert(v > 0); if (v < LOG2_TABLE_SIZE) { diff --git a/vp9/encoder/vp9_non_greedy_mv.h b/vp9/encoder/vp9_non_greedy_mv.h index f095ddf41..c2bd69722 100644 --- a/vp9/encoder/vp9_non_greedy_mv.h +++ b/vp9/encoder/vp9_non_greedy_mv.h @@ -31,8 +31,10 @@ typedef struct MotionField { BLOCK_SIZE bsize; int block_rows; int block_cols; + int block_num; // block_num == block_rows * block_cols int (*local_structure)[MF_LOCAL_STRUCTURE_SIZE]; - MV *mf; + int_mv *mf; + int *set_mv; int mv_log_scale; } MotionField; @@ -104,6 +106,23 @@ void vp9_get_local_structure(const YV12_BUFFER_CONFIG *cur_frame, const vp9_variance_fn_ptr_t *fn_ptr, int rows, int cols, BLOCK_SIZE bsize, int (*M)[MF_LOCAL_STRUCTURE_SIZE]); + +MotionField *vp9_motion_field_info_get_motion_field( + MotionFieldInfo *motion_field_info, int frame_idx, int rf_idx, + BLOCK_SIZE bsize); + +void vp9_motion_field_mi_set_mv(MotionField *motion_field, int mi_row, + int mi_col, int_mv mv); + +void vp9_motion_field_reset_mvs(MotionField *motion_field); + +int_mv vp9_motion_field_get_mv(const MotionField *motion_field, int brow, + int bcol); +int_mv vp9_motion_field_mi_get_mv(const MotionField *motion_field, int mi_row, + int mi_col); +int vp9_motion_field_is_mv_set(const MotionField *motion_field, int brow, + int bcol); + #ifdef __cplusplus } // extern "C" #endif diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 57edc724a..1104c20bb 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -2500,9 +2500,10 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int gf_rf_idx = ref_frame_to_gf_rf_idx(ref); BLOCK_SIZE square_bsize = get_square_block_size(bsize); int_mv nb_full_mvs[NB_MVS_NUM]; + MotionField *motion_field = vp9_motion_field_info_get_motion_field( + &cpi->motion_field_info, gf_group_idx, gf_rf_idx, square_bsize); const int nb_full_mv_num = - vp9_prepare_nb_full_mvs(&cpi->tpl_stats[gf_group_idx], mi_row, mi_col, - gf_rf_idx, square_bsize, nb_full_mvs); + vp9_prepare_nb_full_mvs(motion_field, mi_row, mi_col, nb_full_mvs); const int lambda = (pw * ph) / 4; assert(pw * ph == lambda << 2); #else // CONFIG_NON_GREEDY_MV @@ -2673,8 +2674,7 @@ static INLINE void restore_dst_buf(MACROBLOCKD *xd, // However, once established that vector may be usable through the nearest and // near mv modes to reduce distortion in subsequent blocks and also improve // visual quality. -static int discount_newmv_test(const VP9_COMP *cpi, int this_mode, - int_mv this_mv, +static int discount_newmv_test(VP9_COMP *cpi, int this_mode, int_mv this_mv, int_mv (*mode_mv)[MAX_REF_FRAMES], int ref_frame, int mi_row, int mi_col, BLOCK_SIZE bsize) { #if CONFIG_NON_GREEDY_MV @@ -2684,6 +2684,8 @@ static int discount_newmv_test(const VP9_COMP *cpi, int this_mode, const int gf_group_idx = cpi->twopass.gf_group.index; const int gf_rf_idx = ref_frame_to_gf_rf_idx(ref_frame); const TplDepFrame tpl_frame = cpi->tpl_stats[gf_group_idx]; + const MotionField *motion_field = vp9_motion_field_info_get_motion_field( + &cpi->motion_field_info, gf_group_idx, gf_rf_idx, cpi->tpl_bsize); const int tpl_block_mi_h = num_8x8_blocks_high_lookup[cpi->tpl_bsize]; const int tpl_block_mi_w = num_8x8_blocks_wide_lookup[cpi->tpl_bsize]; const int tpl_mi_row = mi_row - (mi_row % tpl_block_mi_h); @@ -2692,8 +2694,8 @@ static int discount_newmv_test(const VP9_COMP *cpi, int this_mode, tpl_frame .mv_mode_arr[gf_rf_idx][tpl_mi_row * tpl_frame.stride + tpl_mi_col]; if (mv_mode == NEW_MV_MODE) { - int_mv tpl_new_mv = *get_pyramid_mv(&tpl_frame, gf_rf_idx, cpi->tpl_bsize, - tpl_mi_row, tpl_mi_col); + int_mv tpl_new_mv = + vp9_motion_field_mi_get_mv(motion_field, tpl_mi_row, tpl_mi_col); int row_diff = abs(tpl_new_mv.as_mv.row - this_mv.as_mv.row); int col_diff = abs(tpl_new_mv.as_mv.col - this_mv.as_mv.col); if (VPXMAX(row_diff, col_diff) <= 8) { |