ref: 2d4eeae1c8adf31d60c2243286c130c85db7f17d
parent: 86db847ab8d17d465f2839c2e5223eb8af1885c8
author: Angie Chiang <angiebird@google.com>
date: Wed Oct 10 13:43:22 EDT 2018
Change mv search order according to feature_score Sort the feature_score in descending order. Do mv search from the block with higher score to the block with lower score Change-Id: I47a87cd66ea3e40d8c8fc55a7517ab8aa10fdb94
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -2361,6 +2361,11 @@
if (cpi->sf.enable_tpl_model) {
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
+ CHECK_MEM_ERROR(
+ cm, cpi->feature_score_loc_arr,
+ vpx_calloc(mi_rows * mi_cols, sizeof(*cpi->feature_score_loc_arr)));
+#endif
// TODO(jingning): Reduce the actual memory use for tpl model build up.
for (frame = 0; frame < MAX_ARF_GOP_SIZE; ++frame) {
CHECK_MEM_ERROR(cm, cpi->tpl_stats[frame].tpl_stats_ptr,
@@ -2577,6 +2582,9 @@
vp9_denoiser_free(&(cpi->denoiser));
#endif
+#if CONFIG_NON_GREEDY_MV
+ vpx_free(cpi->feature_score_loc_arr);
+#endif
for (frame = 0; frame < MAX_ARF_GOP_SIZE; ++frame) {
vpx_free(cpi->tpl_stats[frame].tpl_stats_ptr);
cpi->tpl_stats[frame].is_valid = 0;
@@ -5947,6 +5955,20 @@
tpl_stats->mv.as_int = best_mv.as_int;
}
+#if CONFIG_NON_GREEDY_MV
+int compare_feature_score(const void *a, const void *b) {
+ const FEATURE_SCORE_LOC *aa = (const FEATURE_SCORE_LOC *)a;
+ const FEATURE_SCORE_LOC *bb = (const FEATURE_SCORE_LOC *)b;
+ if (aa->feature_score < bb->feature_score) {
+ return 1;
+ } else if (aa->feature_score > bb->feature_score) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
+#endif
+
void mc_flow_dispenser(VP9_COMP *cpi, GF_PICTURE *gf_picture, int frame_idx,
BLOCK_SIZE bsize) {
TplDepFrame *tpl_frame = &cpi->tpl_stats[frame_idx];
@@ -5979,6 +6001,8 @@
int64_t recon_error, sse;
#if CONFIG_NON_GREEDY_MV
int rf_idx;
+ int fs_loc_arr_size;
+ int i;
#endif
// Setup scaling factor
@@ -6024,6 +6048,7 @@
#if CONFIG_NON_GREEDY_MV
tpl_frame->lambda = 250;
+ fs_loc_arr_size = 0;
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) {
const int mb_y_offset =
@@ -6032,37 +6057,46 @@
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[fs_loc_arr_size];
tpl_stats->feature_score = get_feature_score(
xd->cur_buf->y_buffer + mb_y_offset, xd->cur_buf->y_stride, bw, bh);
+ fs_loc->feature_score = tpl_stats->feature_score;
+ fs_loc->mi_row = mi_row;
+ fs_loc->mi_col = mi_col;
+ ++fs_loc_arr_size;
}
}
+ qsort(cpi->feature_score_loc_arr, fs_loc_arr_size,
+ sizeof(*cpi->feature_score_loc_arr), compare_feature_score);
+
for (rf_idx = 0; rf_idx < 3; ++rf_idx) {
tpl_frame->mv_dist_sum[rf_idx] = 0;
tpl_frame->mv_cost_sum[rf_idx] = 0;
}
- 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) {
- const int mb_y_offset =
- mi_row * MI_SIZE * xd->cur_buf->y_stride + mi_col * MI_SIZE;
- TplDepStats *tpl_stats =
- &tpl_frame->tpl_stats_ptr[mi_row * tpl_frame->stride + mi_col];
+ for (i = 0; i < fs_loc_arr_size; ++i) {
+ int mb_y_offset;
+ TplDepStats *tpl_stats;
+ mi_row = cpi->feature_score_loc_arr[i].mi_row;
+ mi_col = cpi->feature_score_loc_arr[i].mi_col;
- set_mv_limits(cm, x, mi_row, mi_col);
+ mb_y_offset = mi_row * MI_SIZE * xd->cur_buf->y_stride + mi_col * MI_SIZE;
+ tpl_stats = &tpl_frame->tpl_stats_ptr[mi_row * tpl_frame->stride + mi_col];
- for (rf_idx = 0; rf_idx < 3; ++rf_idx) {
- if (ref_frame[rf_idx] == NULL) {
- tpl_stats->ready[rf_idx] = 0;
- continue;
- } else {
- tpl_stats->ready[rf_idx] = 1;
- }
- motion_compensated_prediction(
- cpi, td, frame_idx, xd->cur_buf->y_buffer + mb_y_offset,
- ref_frame[rf_idx]->y_buffer + mb_y_offset, xd->cur_buf->y_stride,
- bsize, mi_row, mi_col, tpl_stats, rf_idx);
+ set_mv_limits(cm, x, mi_row, mi_col);
+
+ for (rf_idx = 0; rf_idx < 3; ++rf_idx) {
+ if (ref_frame[rf_idx] == NULL) {
+ tpl_stats->ready[rf_idx] = 0;
+ continue;
+ } else {
+ tpl_stats->ready[rf_idx] = 1;
}
+ motion_compensated_prediction(
+ cpi, td, frame_idx, xd->cur_buf->y_buffer + mb_y_offset,
+ ref_frame[rf_idx]->y_buffer + mb_y_offset, xd->cur_buf->y_stride,
+ bsize, mi_row, mi_col, tpl_stats, rf_idx);
}
}
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -503,6 +503,13 @@
// Maximum operating frame buffer size needed for a GOP using ARF reference.
#define MAX_ARF_GOP_SIZE (2 * MAX_LAG_BUFFERS)
+#if CONFIG_NON_GREEDY_MV
+typedef struct FEATURE_SCORE_LOC {
+ double feature_score;
+ int mi_row;
+ int mi_col;
+} FEATURE_SCORE_LOC;
+#endif
typedef struct VP9_COMP {
QUANTS quants;
@@ -530,6 +537,9 @@
TplDepFrame tpl_stats[MAX_ARF_GOP_SIZE];
YV12_BUFFER_CONFIG *tpl_recon_frames[REF_FRAMES];
EncFrameBuf enc_frame_buf[REF_FRAMES];
+#if CONFIG_NON_GREEDY_MV
+ FEATURE_SCORE_LOC *feature_score_loc_arr;
+#endif
TileDataEnc *tile_data;
int allocated_tiles; // Keep track of memory allocated for tiles.