ref: 7b5553e139887a4b11e293aafe9efa3da3a53121
parent: 319c93f20d87cc06d7506f1e3ae67152400a52e4
author: Jingning Han <jingning@google.com>
date: Tue Jul 31 05:43:17 EDT 2018
Use mesh full pixel motion search to build the source ARF Append mesh search to the diamond shape search to refine the full pixel motion estimation for source ARF generation. It improves the average compression performance. Speed 0 avg PSNR overall PSNR SSIM mid -0.18% -0.18% -0.22% hd -0.25% -0.23% -0.36% nflx2k -0.22% -0.23% -0.37% Speed 1 avg PSNR overall PSNR SSIM mid -0.10% -0.08% -0.11% hd -0.25% -0.27% -0.38% nflx2k -0.20% -0.20% -0.34% The additional encoding time is close to the sample noise range. For bus_cif at 1000 kbps, the speed 0 encoding time goes from 83.0 s -> 83.6 s. Change-Id: I48647f50ec3e8f7ae4550a4bde831f569f46ecf3
--- a/vp9/encoder/vp9_mcomp.c
+++ b/vp9/encoder/vp9_mcomp.c
@@ -2186,6 +2186,8 @@
const SEARCH_METHODS method = (SEARCH_METHODS)search_method;
vp9_variance_fn_ptr_t *fn_ptr = &cpi->fn_ptr[bsize];
int var = 0;
+ int run_mesh_search = (method == MESH);
+
if (cost_list) {
cost_list[0] = INT_MAX;
cost_list[1] = INT_MAX;
@@ -2216,29 +2218,32 @@
fn_ptr, 1, ref_mv, tmp_mv);
break;
default:
- assert(method == NSTEP);
+ assert(method == NSTEP || method == MESH);
var = full_pixel_diamond(cpi, x, mvp_full, step_param, error_per_bit,
MAX_MVSEARCH_STEPS - 1 - step_param, 1,
cost_list, fn_ptr, ref_mv, tmp_mv);
- // Should we allow a follow on exhaustive search?
- if ((sf->exhaustive_searches_thresh < INT_MAX) &&
- !cpi->rc.is_src_frame_alt_ref) {
- int64_t exhuastive_thr = sf->exhaustive_searches_thresh;
- exhuastive_thr >>=
- 8 - (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]);
+ // Should we allow a follow on exhaustive search, in regular rd search
+ // mode.
+ if (run_mesh_search == 0) {
+ if ((sf->exhaustive_searches_thresh < INT_MAX) &&
+ !cpi->rc.is_src_frame_alt_ref) {
+ int64_t exhuastive_thr = sf->exhaustive_searches_thresh;
+ exhuastive_thr >>=
+ 8 - (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]);
+ if (var > exhuastive_thr) run_mesh_search = 1;
+ }
+ }
- // Threshold variance for an exhaustive full search.
- if (var > exhuastive_thr) {
- int var_ex;
- MV tmp_mv_ex;
- var_ex = full_pixel_exhaustive(cpi, x, tmp_mv, error_per_bit,
- cost_list, fn_ptr, ref_mv, &tmp_mv_ex);
+ if (run_mesh_search) {
+ int var_ex;
+ MV tmp_mv_ex;
+ var_ex = full_pixel_exhaustive(cpi, x, tmp_mv, error_per_bit, cost_list,
+ fn_ptr, ref_mv, &tmp_mv_ex);
- if (var_ex < var) {
- var = var_ex;
- *tmp_mv = tmp_mv_ex;
- }
+ if (var_ex < var) {
+ var = var_ex;
+ *tmp_mv = tmp_mv_ex;
}
}
break;
--- a/vp9/encoder/vp9_speed_features.c
+++ b/vp9/encoder/vp9_speed_features.c
@@ -201,15 +201,16 @@
if (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) {
sf->exhaustive_searches_thresh = (1 << 22);
- for (i = 0; i < MAX_MESH_STEP; ++i) {
- int mesh_density_level = 0;
- sf->mesh_patterns[i].range =
- good_quality_mesh_patterns[mesh_density_level][i].range;
- sf->mesh_patterns[i].interval =
- good_quality_mesh_patterns[mesh_density_level][i].interval;
- }
} else {
sf->exhaustive_searches_thresh = INT_MAX;
+ }
+
+ for (i = 0; i < MAX_MESH_STEP; ++i) {
+ const int mesh_density_level = 0;
+ sf->mesh_patterns[i].range =
+ good_quality_mesh_patterns[mesh_density_level][i].range;
+ sf->mesh_patterns[i].interval =
+ good_quality_mesh_patterns[mesh_density_level][i].interval;
}
if (speed >= 1) {
--- a/vp9/encoder/vp9_speed_features.h
+++ b/vp9/encoder/vp9_speed_features.h
@@ -57,7 +57,8 @@
BIGDIA = 3,
SQUARE = 4,
FAST_HEX = 5,
- FAST_DIAMOND = 6
+ FAST_DIAMOND = 6,
+ MESH = 7
} SEARCH_METHODS;
typedef enum {
--- a/vp9/encoder/vp9_temporal_filter.c
+++ b/vp9/encoder/vp9_temporal_filter.c
@@ -230,7 +230,7 @@
MACROBLOCK *const x = &td->mb;
MACROBLOCKD *const xd = &x->e_mbd;
MV_SPEED_FEATURES *const mv_sf = &cpi->sf.mv;
- const SEARCH_METHODS search_method = NSTEP;
+ const SEARCH_METHODS search_method = MESH;
int step_param;
int sadpb = x->sadperbit16;
uint32_t bestsme = UINT_MAX;