aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vp9/encoder/vp9_encoder.c171
-rw-r--r--vp9/encoder/vp9_encoder.h15
-rw-r--r--vp9/encoder/vp9_mcomp.c31
-rw-r--r--vp9/encoder/vp9_mcomp.h5
-rw-r--r--vp9/encoder/vp9_non_greedy_mv.c67
-rw-r--r--vp9/encoder/vp9_non_greedy_mv.h21
-rw-r--r--vp9/encoder/vp9_rdopt.c14
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) {