1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12 #include <limits.h>
13
14 #include "av1/common/reconintra.h"
15
16 #include "av1/encoder/encoder.h"
17 #include "av1/encoder/speed_features.h"
18 #include "av1/encoder/rdopt.h"
19
20 #include "aom_dsp/aom_dsp_common.h"
21
22 #define MAX_MESH_SPEED 5 // Max speed setting for mesh motion method
23 // Max speed setting for tx domain evaluation
24 #define MAX_TX_DOMAIN_EVAL_SPEED 5
25 static MESH_PATTERN
26 good_quality_mesh_patterns[MAX_MESH_SPEED + 1][MAX_MESH_STEP] = {
27 { { 64, 8 }, { 28, 4 }, { 15, 1 }, { 7, 1 } },
28 { { 64, 8 }, { 28, 4 }, { 15, 1 }, { 7, 1 } },
29 { { 64, 8 }, { 14, 2 }, { 7, 1 }, { 7, 1 } },
30 { { 64, 16 }, { 24, 8 }, { 12, 4 }, { 7, 1 } },
31 { { 64, 16 }, { 24, 8 }, { 12, 4 }, { 7, 1 } },
32 { { 64, 16 }, { 24, 8 }, { 12, 4 }, { 7, 1 } },
33 };
34
35 // TODO(huisu@google.com): These settings are pretty relaxed, tune them for
36 // each speed setting
37 static MESH_PATTERN intrabc_mesh_patterns[MAX_MESH_SPEED + 1][MAX_MESH_STEP] = {
38 { { 256, 1 }, { 256, 1 }, { 0, 0 }, { 0, 0 } },
39 { { 256, 1 }, { 256, 1 }, { 0, 0 }, { 0, 0 } },
40 { { 64, 1 }, { 64, 1 }, { 0, 0 }, { 0, 0 } },
41 { { 64, 1 }, { 64, 1 }, { 0, 0 }, { 0, 0 } },
42 { { 64, 4 }, { 16, 1 }, { 0, 0 }, { 0, 0 } },
43 { { 64, 4 }, { 16, 1 }, { 0, 0 }, { 0, 0 } },
44 };
45
46 // Threshold values to be used for pruning the txfm_domain_distortion
47 // based on block MSE
48 // Index 0: Default mode evaluation, Winner mode processing is not
49 // applicable (Eg : IntraBc). Index 1: Mode evaluation.
50 // Index 2: Winner mode evaluation. Index 1 and 2 are applicable when
51 // enable_winner_mode_for_use_tx_domain_dist speed feature is ON
52 // TODO(any): Experiment the threshold logic based on variance metric
53 static unsigned int tx_domain_dist_thresholds[3][MODE_EVAL_TYPES] = {
54 { UINT_MAX, UINT_MAX, UINT_MAX }, { 22026, 22026, 22026 }, { 0, 0, 0 }
55 };
56
57 // Transform domain distortion type to be used for default, mode and winner mode
58 // evaluation Index 0: Default mode evaluation, Winner mode processing is not
59 // applicable (Eg : IntraBc). Index 1: Mode evaluation. Index 2: Winner mode
60 // evaluation. Index 1 and 2 are applicable when
61 // enable_winner_mode_for_use_tx_domain_dist speed feature is ON
62 static unsigned int tx_domain_dist_types[3][MODE_EVAL_TYPES] = { { 0, 2, 0 },
63 { 1, 2, 0 },
64 { 2, 2, 0 } };
65
66 // Threshold values to be used for disabling coeff RD-optimization
67 // based on block MSE / qstep^2.
68 // TODO(any): Experiment the threshold logic based on variance metric.
69 // For each row, the indices are as follows.
70 // Index 0: Default mode evaluation, Winner mode processing is not applicable
71 // (Eg : IntraBc)
72 // Index 1: Mode evaluation.
73 // Index 2: Winner mode evaluation.
74 // Index 1 and 2 are applicable when enable_winner_mode_for_coeff_opt speed
75 // feature is ON
76 // There are 6 levels with increasing speed, mapping to vertical indices.
77 static unsigned int coeff_opt_dist_thresholds[6][MODE_EVAL_TYPES] = {
78 { UINT_MAX, UINT_MAX, UINT_MAX },
79 { 3200, 250, UINT_MAX },
80 { 1728, 142, UINT_MAX },
81 { 864, 142, UINT_MAX },
82 { 432, 86, UINT_MAX },
83 { 216, 86, UINT_MAX }
84 };
85
86 // Transform size to be used for default, mode and winner mode evaluation
87 // Index 0: Default mode evaluation, Winner mode processing is not applicable
88 // (Eg : IntraBc) Index 1: Mode evaluation. Index 2: Winner mode evaluation.
89 // Index 1 and 2 are applicable when enable_winner_mode_for_tx_size_srch speed
90 // feature is ON
91 static TX_SIZE_SEARCH_METHOD tx_size_search_methods[3][MODE_EVAL_TYPES] = {
92 { USE_FULL_RD, USE_LARGESTALL, USE_FULL_RD },
93 { USE_FAST_RD, USE_LARGESTALL, USE_FULL_RD },
94 { USE_LARGESTALL, USE_LARGESTALL, USE_FULL_RD }
95 };
96
97 // Predict transform skip levels to be used for default, mode and winner mode
98 // evaluation. Index 0: Default mode evaluation, Winner mode processing is not
99 // applicable. Index 1: Mode evaluation, Index 2: Winner mode evaluation
100 // Values indicate the aggressiveness of skip flag prediction.
101 // 0 : no early skip prediction
102 // 1 : conservative early skip prediction using DCT_DCT
103 // 2 : early skip prediction based on SSE
104 static unsigned int predict_skip_levels[3][MODE_EVAL_TYPES] = { { 0, 0, 0 },
105 { 1, 1, 1 },
106 { 1, 2, 1 } };
107
108 // Intra only frames, golden frames (except alt ref overlays) and
109 // alt ref frames tend to be coded at a higher than ambient quality
frame_is_boosted(const AV1_COMP * cpi)110 static int frame_is_boosted(const AV1_COMP *cpi) {
111 return frame_is_kf_gf_arf(cpi);
112 }
113
dim_to_size(int dim)114 static BLOCK_SIZE dim_to_size(int dim) {
115 switch (dim) {
116 case 4: return BLOCK_4X4;
117 case 8: return BLOCK_8X8;
118 case 16: return BLOCK_16X16;
119 case 32: return BLOCK_32X32;
120 case 64: return BLOCK_64X64;
121 case 128: return BLOCK_128X128;
122 default: assert(0); return 0;
123 }
124 }
125
set_good_speed_feature_framesize_dependent(const AV1_COMP * const cpi,SPEED_FEATURES * const sf,int speed)126 static void set_good_speed_feature_framesize_dependent(
127 const AV1_COMP *const cpi, SPEED_FEATURES *const sf, int speed) {
128 const AV1_COMMON *const cm = &cpi->common;
129 const int is_720p_or_larger = AOMMIN(cm->width, cm->height) >= 720;
130 const int is_480p_or_larger = AOMMIN(cm->width, cm->height) >= 480;
131 const int is_4k_or_larger = AOMMIN(cm->width, cm->height) >= 2160;
132
133 if (is_480p_or_larger) {
134 sf->part_sf.use_square_partition_only_threshold = BLOCK_128X128;
135 if (is_720p_or_larger)
136 sf->part_sf.auto_max_partition_based_on_simple_motion = ADAPT_PRED;
137 else
138 sf->part_sf.auto_max_partition_based_on_simple_motion = RELAXED_PRED;
139 } else {
140 sf->part_sf.use_square_partition_only_threshold = BLOCK_64X64;
141 sf->part_sf.auto_max_partition_based_on_simple_motion = DIRECT_PRED;
142 }
143
144 if (is_4k_or_larger) {
145 sf->part_sf.default_min_partition_size = BLOCK_8X8;
146 }
147
148 // TODO(huisu@google.com): train models for 720P and above.
149 if (!is_720p_or_larger) {
150 sf->part_sf.ml_partition_search_breakout_thresh[0] = 200; // BLOCK_8X8
151 sf->part_sf.ml_partition_search_breakout_thresh[1] = 250; // BLOCK_16X16
152 sf->part_sf.ml_partition_search_breakout_thresh[2] = 300; // BLOCK_32X32
153 sf->part_sf.ml_partition_search_breakout_thresh[3] = 500; // BLOCK_64X64
154 sf->part_sf.ml_partition_search_breakout_thresh[4] = -1; // BLOCK_128X128
155 sf->part_sf.ml_early_term_after_part_split_level = 1;
156 }
157
158 if (speed >= 1) {
159 if (is_720p_or_larger) {
160 sf->part_sf.use_square_partition_only_threshold = BLOCK_128X128;
161 } else if (is_480p_or_larger) {
162 sf->part_sf.use_square_partition_only_threshold = BLOCK_64X64;
163 } else {
164 sf->part_sf.use_square_partition_only_threshold = BLOCK_32X32;
165 }
166
167 if (!is_720p_or_larger) {
168 sf->part_sf.ml_partition_search_breakout_thresh[0] = 200; // BLOCK_8X8
169 sf->part_sf.ml_partition_search_breakout_thresh[1] = 250; // BLOCK_16X16
170 sf->part_sf.ml_partition_search_breakout_thresh[2] = 300; // BLOCK_32X32
171 sf->part_sf.ml_partition_search_breakout_thresh[3] = 300; // BLOCK_64X64
172 sf->part_sf.ml_partition_search_breakout_thresh[4] = -1; // BLOCK_128X128
173 }
174 sf->part_sf.ml_early_term_after_part_split_level = 2;
175 }
176
177 if (speed >= 2) {
178 if (is_720p_or_larger) {
179 sf->part_sf.use_square_partition_only_threshold = BLOCK_64X64;
180 } else if (is_480p_or_larger) {
181 sf->part_sf.use_square_partition_only_threshold = BLOCK_32X32;
182 } else {
183 sf->part_sf.use_square_partition_only_threshold = BLOCK_32X32;
184 }
185
186 if (is_720p_or_larger) {
187 sf->part_sf.partition_search_breakout_dist_thr = (1 << 24);
188 sf->part_sf.partition_search_breakout_rate_thr = 120;
189 } else {
190 sf->part_sf.partition_search_breakout_dist_thr = (1 << 22);
191 sf->part_sf.partition_search_breakout_rate_thr = 100;
192 }
193
194 if (is_720p_or_larger) {
195 sf->inter_sf.prune_obmc_prob_thresh = 16;
196 } else {
197 sf->inter_sf.prune_obmc_prob_thresh = 8;
198 }
199
200 if (is_480p_or_larger) {
201 sf->tx_sf.tx_type_search.prune_tx_type_using_stats = 1;
202 }
203 }
204
205 if (speed >= 3) {
206 sf->part_sf.ml_early_term_after_part_split_level = 0;
207
208 if (is_720p_or_larger) {
209 sf->part_sf.partition_search_breakout_dist_thr = (1 << 25);
210 sf->part_sf.partition_search_breakout_rate_thr = 200;
211 } else {
212 sf->part_sf.max_intra_bsize = BLOCK_32X32;
213 sf->part_sf.partition_search_breakout_dist_thr = (1 << 23);
214 sf->part_sf.partition_search_breakout_rate_thr = 120;
215 }
216 }
217
218 if (speed >= 4) {
219 if (is_720p_or_larger) {
220 sf->part_sf.partition_search_breakout_dist_thr = (1 << 26);
221 } else {
222 sf->part_sf.partition_search_breakout_dist_thr = (1 << 24);
223 }
224
225 if (is_480p_or_larger) {
226 sf->tx_sf.tx_type_search.prune_tx_type_using_stats = 2;
227 }
228
229 sf->inter_sf.prune_obmc_prob_thresh = 16;
230 }
231
232 if (speed >= 5) {
233 if (is_720p_or_larger) {
234 sf->inter_sf.prune_warped_prob_thresh = 16;
235 } else if (is_480p_or_larger) {
236 sf->inter_sf.prune_warped_prob_thresh = 8;
237 }
238 }
239 }
240
set_rt_speed_feature_framesize_dependent(const AV1_COMP * const cpi,SPEED_FEATURES * const sf,int speed)241 static void set_rt_speed_feature_framesize_dependent(const AV1_COMP *const cpi,
242 SPEED_FEATURES *const sf,
243 int speed) {
244 const AV1_COMMON *const cm = &cpi->common;
245 const int is_720p_or_larger = AOMMIN(cm->width, cm->height) >= 720;
246 const int is_480p_or_larger = AOMMIN(cm->width, cm->height) >= 480;
247 const int is_360p_or_larger = AOMMIN(cm->width, cm->height) >= 360;
248
249 (void)is_720p_or_larger; // Not used so far
250
251 if (!is_360p_or_larger) {
252 if (speed >= 6) sf->rt_sf.force_tx_search_off = 1;
253 if (speed >= 8) {
254 sf->rt_sf.use_modeled_non_rd_cost = 0;
255 sf->rt_sf.use_nonrd_filter_search = 0;
256 }
257 }
258 if (is_360p_or_larger) {
259 if (speed >= 7) {
260 sf->interp_sf.disable_filter_search_var_thresh = 0;
261 }
262 }
263 if (!is_480p_or_larger) {
264 if (speed == 7) {
265 sf->rt_sf.nonrd_check_partition_merge_mode = 2;
266 }
267 if (speed >= 8) {
268 sf->mv_sf.subpel_search_method = SUBPEL_TREE;
269
270 sf->rt_sf.estimate_motion_for_var_based_partition = 1;
271 }
272 }
273 }
274
set_good_speed_features_framesize_independent(const AV1_COMP * const cpi,SPEED_FEATURES * const sf,int speed)275 static void set_good_speed_features_framesize_independent(
276 const AV1_COMP *const cpi, SPEED_FEATURES *const sf, int speed) {
277 const AV1_COMMON *const cm = &cpi->common;
278 const GF_GROUP *const gf_group = &cpi->gf_group;
279 const int boosted = frame_is_boosted(cpi);
280 const int is_boosted_arf2_bwd_type =
281 boosted || gf_group->update_type[gf_group->index] == INTNL_ARF_UPDATE;
282 const int allow_screen_content_tools =
283 cm->features.allow_screen_content_tools;
284 if (!cpi->oxcf.large_scale_tile) {
285 sf->hl_sf.high_precision_mv_usage = LAST_MV_DATA;
286 }
287
288 // Speed 0 for all speed features that give neutral coding performance change.
289 sf->gm_sf.gm_disable_recode = 1;
290 sf->gm_sf.gm_search_type = GM_REDUCED_REF_SEARCH_SKIP_L2_L3;
291
292 sf->part_sf.less_rectangular_check_level = 1;
293 sf->part_sf.ml_prune_4_partition = 1;
294 sf->part_sf.ml_prune_ab_partition = 1;
295 sf->part_sf.ml_prune_rect_partition = 1;
296 sf->part_sf.prune_ext_partition_types_search_level = 1;
297 sf->part_sf.simple_motion_search_prune_rect = 1;
298
299 sf->inter_sf.disable_wedge_search_edge_thresh = 0;
300 sf->inter_sf.disable_wedge_search_var_thresh = 0;
301 // TODO(debargha): Test, tweak and turn on either 1 or 2
302 sf->inter_sf.inter_mode_rd_model_estimation = 1;
303 sf->inter_sf.model_based_post_interp_filter_breakout = 1;
304 sf->inter_sf.prune_compound_using_single_ref = 1;
305 sf->inter_sf.prune_mode_search_simple_translation = 1;
306 sf->inter_sf.prune_motion_mode_level = 1;
307 sf->inter_sf.prune_ref_frame_for_rect_partitions =
308 (boosted || (allow_screen_content_tools))
309 ? 0
310 : (is_boosted_arf2_bwd_type ? 1 : 2);
311 sf->inter_sf.prune_wedge_pred_diff_based = 1;
312 sf->inter_sf.reduce_inter_modes = 1;
313 sf->inter_sf.selective_ref_frame = 1;
314 sf->inter_sf.use_dist_wtd_comp_flag = DIST_WTD_COMP_SKIP_MV_SEARCH;
315
316 sf->interp_sf.cb_pred_filter_search = 0;
317 sf->interp_sf.use_fast_interpolation_filter_search = 1;
318
319 sf->intra_sf.intra_pruning_with_hog = 1;
320 sf->intra_sf.intra_pruning_with_hog_thresh = -1.2f;
321
322 sf->tx_sf.adaptive_txb_search_level = 1;
323 sf->tx_sf.intra_tx_size_search_init_depth_sqr = 1;
324 sf->tx_sf.model_based_prune_tx_search_level = 1;
325 sf->tx_sf.tx_type_search.use_reduced_intra_txset = 1;
326
327 sf->rt_sf.use_nonrd_pick_mode = 0;
328 sf->rt_sf.use_real_time_ref_set = 0;
329
330 if (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION)
331 sf->mv_sf.exhaustive_searches_thresh = (1 << 24);
332 else
333 sf->mv_sf.exhaustive_searches_thresh = (1 << 25);
334
335 sf->rd_sf.perform_coeff_opt = 1;
336
337 if (speed >= 1) {
338 sf->gm_sf.disable_adaptive_warp_error_thresh = 0;
339 sf->gm_sf.gm_search_type = GM_REDUCED_REF_SEARCH_SKIP_L2_L3_ARF2;
340 sf->gm_sf.prune_ref_frame_for_gm_search = boosted ? 0 : 1;
341
342 sf->part_sf.intra_cnn_split = 1;
343 sf->part_sf.simple_motion_search_early_term_none = 1;
344 // TODO(Venkat): Clean-up frame type dependency for
345 // simple_motion_search_split in partition search function and set the
346 // speed feature accordingly
347 sf->part_sf.simple_motion_search_split = allow_screen_content_tools ? 1 : 2;
348
349 sf->mv_sf.exhaustive_searches_thresh <<= 1;
350 sf->mv_sf.obmc_full_pixel_search_level = 1;
351 sf->mv_sf.use_accurate_subpel_search = USE_4_TAPS;
352
353 sf->inter_sf.disable_interinter_wedge_newmv_search = boosted ? 0 : 1;
354 sf->inter_sf.prune_comp_search_by_single_result = boosted ? 2 : 1;
355 sf->inter_sf.prune_comp_type_by_comp_avg = 1;
356 sf->inter_sf.prune_comp_type_by_model_rd = boosted ? 0 : 1;
357 sf->inter_sf.prune_motion_mode_level = 2;
358 sf->inter_sf.prune_ref_frame_for_rect_partitions =
359 (frame_is_intra_only(&cpi->common) || (allow_screen_content_tools))
360 ? 0
361 : (boosted ? 1 : 2);
362 sf->inter_sf.reduce_inter_modes = boosted ? 1 : 2;
363 sf->inter_sf.reuse_inter_intra_mode = 1;
364 sf->inter_sf.selective_ref_frame = 2;
365 sf->inter_sf.skip_repeated_newmv = 1;
366
367 sf->interp_sf.cb_pred_filter_search = 0;
368 sf->interp_sf.use_interp_filter = 1;
369 sf->intra_sf.prune_palette_search_level = 1;
370
371 sf->tx_sf.adaptive_txb_search_level = 2;
372 sf->tx_sf.inter_tx_size_search_init_depth_rect = 1;
373 sf->tx_sf.inter_tx_size_search_init_depth_sqr = 1;
374 sf->tx_sf.intra_tx_size_search_init_depth_rect = 1;
375 sf->tx_sf.model_based_prune_tx_search_level = 0;
376 sf->tx_sf.tx_type_search.ml_tx_split_thresh = 4000;
377 sf->tx_sf.tx_type_search.prune_mode = PRUNE_2D_FAST;
378 sf->tx_sf.tx_type_search.skip_tx_search = 1;
379 sf->tx_sf.use_intra_txb_hash = 1;
380
381 sf->rd_sf.perform_coeff_opt = boosted ? 2 : 3;
382 sf->rd_sf.tx_domain_dist_level = boosted ? 1 : 2;
383 sf->rd_sf.tx_domain_dist_thres_level = 1;
384
385 sf->lpf_sf.cdef_pick_method = CDEF_FAST_SEARCH_LVL1;
386 sf->lpf_sf.dual_sgr_penalty_level = 1;
387 sf->lpf_sf.enable_sgr_ep_pruning = 1;
388
389 // TODO(any, yunqing): move this feature to speed 0.
390 sf->tpl_sf.skip_alike_starting_mv = 1;
391 }
392
393 if (speed >= 2) {
394 sf->gm_sf.gm_erroradv_type = GM_ERRORADV_TR_2;
395
396 sf->part_sf.allow_partition_search_skip = 1;
397
398 sf->mv_sf.auto_mv_step_size = 1;
399 sf->mv_sf.subpel_iters_per_step = 1;
400
401 // TODO(chiyotsai@google.com): We can get 10% speed up if we move
402 // adaptive_rd_thresh to speed 1. But currently it performs poorly on some
403 // clips (e.g. 5% loss on dinner_1080p). We need to examine the sequence a
404 // bit more closely to figure out why.
405 sf->inter_sf.adaptive_rd_thresh = 1;
406 sf->inter_sf.comp_inter_joint_search_thresh = BLOCK_SIZES_ALL;
407 sf->inter_sf.disable_interinter_wedge_newmv_search = 1;
408 sf->inter_sf.disable_wedge_search_edge_thresh = 0;
409 sf->inter_sf.disable_wedge_search_var_thresh = 100;
410 sf->inter_sf.fast_interintra_wedge_search = 1;
411 sf->inter_sf.fast_wedge_sign_estimate = 1;
412 sf->inter_sf.prune_comp_search_by_single_result = boosted ? 4 : 1;
413 sf->inter_sf.prune_compound_using_neighbors = 1;
414 sf->inter_sf.prune_comp_type_by_comp_avg = 2;
415 sf->inter_sf.prune_warp_using_wmtype = 1;
416 sf->inter_sf.selective_ref_frame = 3;
417 sf->inter_sf.use_dist_wtd_comp_flag = DIST_WTD_COMP_DISABLED;
418
419 // TODO(Sachin): Enable/Enhance this speed feature for speed 2 & 3
420 sf->interp_sf.adaptive_interp_filter_search = 1;
421 sf->interp_sf.disable_dual_filter = 1;
422 sf->interp_sf.disable_filter_search_var_thresh = 100;
423
424 sf->intra_sf.disable_smooth_intra =
425 !frame_is_intra_only(&cpi->common) || (cpi->rc.frames_to_key != 1);
426
427 sf->rd_sf.perform_coeff_opt = is_boosted_arf2_bwd_type ? 3 : 4;
428
429 sf->lpf_sf.prune_wiener_based_on_src_var = 1;
430 sf->lpf_sf.prune_sgr_based_on_wiener = !allow_screen_content_tools;
431 }
432
433 if (speed >= 3) {
434 sf->hl_sf.high_precision_mv_usage = CURRENT_Q;
435 sf->hl_sf.recode_loop = ALLOW_RECODE_KFARFGF;
436
437 sf->gm_sf.gm_search_type = GM_DISABLE_SEARCH;
438
439 sf->part_sf.less_rectangular_check_level = 2;
440 sf->part_sf.simple_motion_search_prune_agg = 1;
441 sf->part_sf.prune_4_partition_using_split_info =
442 !allow_screen_content_tools;
443
444 // adaptive_motion_search breaks encoder multi-thread tests.
445 // The values in x->pred_mv[] differ for single and multi-thread cases.
446 // See aomedia:1778.
447 // sf->mv_sf.adaptive_motion_search = 1;
448 sf->mv_sf.full_pixel_search_level = 1;
449 sf->mv_sf.subpel_search_method = SUBPEL_TREE_PRUNED;
450 sf->mv_sf.use_accurate_subpel_search = USE_2_TAPS;
451 sf->mv_sf.search_method = DIAMOND;
452
453 sf->inter_sf.disable_sb_level_mv_cost_upd = 1;
454 // TODO(yunqing): evaluate this speed feature for speed 1 & 2, and combine
455 // it with cpi->sf.disable_wedge_search_var_thresh.
456 sf->inter_sf.disable_wedge_interintra_search = 1;
457 // TODO(any): Experiment with the early exit mechanism for speeds 0, 1 and 2
458 // and clean-up the speed feature
459 sf->inter_sf.perform_best_rd_based_gating_for_chroma = 1;
460 sf->inter_sf.prune_inter_modes_based_on_tpl = boosted ? 0 : 1;
461 sf->inter_sf.prune_comp_search_by_single_result = boosted ? 4 : 2;
462 sf->inter_sf.prune_motion_mode_level = boosted ? 2 : 3;
463 sf->inter_sf.selective_ref_frame = 4;
464 sf->inter_sf.skip_repeated_ref_mv = 1;
465 sf->inter_sf.skip_repeated_full_newmv = 1;
466 if (cpi->oxcf.enable_smooth_interintra)
467 sf->inter_sf.disable_smooth_interintra = boosted ? 0 : 1;
468 sf->inter_sf.reuse_compound_type_decision = 1;
469 sf->inter_sf.txfm_rd_gate_level = (boosted || allow_screen_content_tools)
470 ? 0
471 : (is_boosted_arf2_bwd_type ? 1 : 2);
472
473 sf->intra_sf.prune_palette_search_level = 2;
474
475 sf->tpl_sf.skip_alike_starting_mv = 2;
476 sf->tpl_sf.prune_intra_modes = 1;
477 sf->tpl_sf.reduce_first_step_size = 6;
478
479 sf->tx_sf.adaptive_txb_search_level = boosted ? 2 : 3;
480 sf->tx_sf.tx_type_search.use_skip_flag_prediction =
481 allow_screen_content_tools ? 1 : 2;
482
483 // TODO(any): Refactor the code related to following winner mode speed
484 // features
485 sf->winner_mode_sf.enable_winner_mode_for_coeff_opt = 1;
486 // TODO(any): Experiment with this speed feature by enabling for key frames
487 sf->winner_mode_sf.enable_winner_mode_for_tx_size_srch =
488 frame_is_intra_only(&cpi->common) ? 0 : 1;
489 sf->winner_mode_sf.enable_winner_mode_for_use_tx_domain_dist =
490 !allow_screen_content_tools;
491 sf->winner_mode_sf.motion_mode_for_winner_cand =
492 boosted
493 ? 0
494 : gf_group->update_type[gf_group->index] == INTNL_ARF_UPDATE ? 1
495 : 2;
496
497 // TODO(any): evaluate if these lpf features can be moved to speed 2.
498 sf->lpf_sf.prune_sgr_based_on_wiener = allow_screen_content_tools ? 0 : 2;
499 sf->lpf_sf.disable_loop_restoration_chroma =
500 (boosted || allow_screen_content_tools) ? 0 : 1;
501 sf->lpf_sf.reduce_wiener_window_size = !boosted;
502 sf->lpf_sf.prune_wiener_based_on_src_var = 2;
503
504 sf->hl_sf.second_alt_ref_filtering = 0;
505 }
506
507 if (speed >= 4) {
508 sf->mv_sf.subpel_search_method = SUBPEL_TREE_PRUNED_MORE;
509
510 sf->part_sf.simple_motion_search_prune_agg = 2;
511 sf->part_sf.prune_ab_partition_using_split_info =
512 !allow_screen_content_tools;
513
514 sf->inter_sf.adaptive_mode_search = 1;
515 sf->inter_sf.alt_ref_search_fp = 1;
516 sf->inter_sf.prune_ref_mv_idx_search = 1;
517 sf->inter_sf.txfm_rd_gate_level =
518 (boosted || allow_screen_content_tools) ? 0 : 3;
519
520 sf->inter_sf.prune_inter_modes_based_on_tpl = boosted ? 0 : 2;
521 sf->inter_sf.prune_compound_using_neighbors = 2;
522 sf->inter_sf.disable_smooth_interintra = 1;
523
524 sf->interp_sf.cb_pred_filter_search = 1;
525 sf->interp_sf.skip_sharp_interp_filter_search = 1;
526 sf->interp_sf.use_interp_filter = 2;
527 sf->interp_sf.adaptive_interp_filter_search = 2;
528
529 sf->intra_sf.intra_uv_mode_mask[TX_16X16] = UV_INTRA_DC_H_V_CFL;
530 sf->intra_sf.intra_uv_mode_mask[TX_32X32] = UV_INTRA_DC_H_V_CFL;
531 sf->intra_sf.intra_uv_mode_mask[TX_64X64] = UV_INTRA_DC_H_V_CFL;
532 sf->intra_sf.intra_y_mode_mask[TX_16X16] = INTRA_DC_H_V;
533 sf->intra_sf.intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V;
534 sf->intra_sf.intra_y_mode_mask[TX_64X64] = INTRA_DC_H_V;
535 // TODO(any): Experiment with this speed feature set to 2 for higher quality
536 // presets as well
537 sf->intra_sf.skip_intra_in_interframe = 2;
538
539 sf->tx_sf.tx_type_search.enable_winner_mode_tx_type_pruning = 1;
540 sf->tx_sf.tx_type_search.fast_intra_tx_type_search = 1;
541 sf->tx_sf.tx_type_search.prune_mode = PRUNE_2D_MORE;
542 sf->tx_sf.tx_type_search.prune_tx_type_est_rd = 1;
543 // TODO(any): Experiment with enabling of this speed feature as hash state
544 // is reset during winner mode processing
545 sf->tx_sf.use_intra_txb_hash = 0;
546
547 sf->rd_sf.perform_coeff_opt = is_boosted_arf2_bwd_type ? 3 : 5;
548 sf->rd_sf.tx_domain_dist_thres_level = 2;
549
550 // TODO(any): Extend multi-winner mode processing support for inter frames
551 sf->winner_mode_sf.enable_multiwinner_mode_process =
552 frame_is_intra_only(&cpi->common) ? 1 : 0;
553 sf->winner_mode_sf.enable_winner_mode_for_tx_size_srch = 1;
554
555 sf->lpf_sf.cdef_pick_method = allow_screen_content_tools
556 ? CDEF_FAST_SEARCH_LVL1
557 : CDEF_FAST_SEARCH_LVL2;
558
559 // TODO(any): The following features have no impact on quality and speed,
560 // and are disabled.
561 // sf->part_sf.partition_search_breakout_rate_thr = 300;
562 // sf->interp_sf.disable_filter_search_var_thresh = 200;
563 // sf->rd_sf.use_fast_coef_costing = 1;
564
565 // TODO(any): The following features give really bad quality/speed trade
566 // off. Needs to be re-worked.
567 // sf->mv_sf.search_method = BIGDIA;
568 // sf->inter_sf.adaptive_rd_thresh = 4;
569 // sf->rd_sf.tx_domain_dist_level = 2;
570 // sf->rt_sf.mode_search_skip_flags =
571 // (cm->current_frame.frame_type == KEY_FRAME)
572 // ? 0
573 // : FLAG_SKIP_INTRA_DIRMISMATCH | FLAG_SKIP_INTRA_BESTINTER |
574 // FLAG_SKIP_COMP_BESTINTRA | FLAG_SKIP_INTRA_LOWVAR |
575 // FLAG_EARLY_TERMINATE;
576 }
577
578 if (speed >= 5) {
579 sf->part_sf.simple_motion_search_prune_agg = 3;
580 sf->part_sf.ext_partition_eval_thresh =
581 allow_screen_content_tools ? BLOCK_8X8 : BLOCK_16X16;
582
583 sf->inter_sf.prune_inter_modes_based_on_tpl = boosted ? 0 : 3;
584 sf->inter_sf.disable_interinter_wedge = 1;
585 sf->inter_sf.disable_obmc = 1;
586 sf->inter_sf.disable_onesided_comp = 1;
587 sf->inter_sf.txfm_rd_gate_level =
588 (boosted || allow_screen_content_tools) ? 0 : 4;
589 sf->inter_sf.prune_inter_modes_if_skippable = 1;
590
591 sf->lpf_sf.lpf_pick = LPF_PICK_FROM_FULL_IMAGE_NON_DUAL;
592 sf->lpf_sf.disable_lr_filter = 1;
593
594 sf->mv_sf.simple_motion_subpel_force_stop = QUARTER_PEL;
595 sf->mv_sf.prune_mesh_search = 1;
596 sf->mv_sf.reduce_search_range = 1;
597
598 sf->tpl_sf.subpel_force_stop = QUARTER_PEL;
599 }
600
601 if (speed >= 6) {
602 }
603 }
604
605 // TODO(kyslov): now this is very similar to
606 // set_good_speed_features_framesize_independent
607 // except it sets non-rd flag on speed8. This function will likely
608 // be modified in the future with RT-specific speed features
set_rt_speed_features_framesize_independent(AV1_COMP * cpi,SPEED_FEATURES * sf,int speed)609 static void set_rt_speed_features_framesize_independent(AV1_COMP *cpi,
610 SPEED_FEATURES *sf,
611 int speed) {
612 AV1_COMMON *const cm = &cpi->common;
613 const int boosted = frame_is_boosted(cpi);
614
615 // Speed 0 for all speed features that give neutral coding performance change.
616 sf->gm_sf.gm_disable_recode = 1;
617 sf->gm_sf.gm_search_type = GM_REDUCED_REF_SEARCH_SKIP_L2_L3;
618
619 sf->part_sf.less_rectangular_check_level = 1;
620 sf->part_sf.ml_prune_4_partition = 1;
621 sf->part_sf.ml_prune_ab_partition = 1;
622 sf->part_sf.ml_prune_rect_partition = 1;
623 sf->part_sf.prune_ext_partition_types_search_level = 1;
624
625 // TODO(debargha): Test, tweak and turn on either 1 or 2
626 sf->inter_sf.inter_mode_rd_model_estimation = 0;
627 sf->inter_sf.disable_wedge_search_edge_thresh = 0;
628 sf->inter_sf.disable_wedge_search_var_thresh = 0;
629 sf->inter_sf.model_based_post_interp_filter_breakout = 1;
630 sf->inter_sf.prune_compound_using_single_ref = 0;
631 sf->inter_sf.prune_mode_search_simple_translation = 1;
632 sf->inter_sf.prune_motion_mode_level = 1;
633 sf->inter_sf.prune_ref_frame_for_rect_partitions = !boosted;
634 sf->inter_sf.prune_wedge_pred_diff_based = 1;
635 sf->inter_sf.reduce_inter_modes = 1;
636 sf->inter_sf.selective_ref_frame = 1;
637 sf->inter_sf.use_dist_wtd_comp_flag = DIST_WTD_COMP_SKIP_MV_SEARCH;
638
639 sf->interp_sf.cb_pred_filter_search = 0;
640 sf->interp_sf.use_fast_interpolation_filter_search = 1;
641
642 sf->intra_sf.intra_pruning_with_hog = 1;
643 sf->intra_sf.intra_pruning_with_hog_thresh = -1.2f;
644
645 sf->mv_sf.full_pixel_search_level = 1;
646 sf->mv_sf.exhaustive_searches_thresh = INT_MAX;
647
648 sf->rt_sf.check_intra_pred_nonrd = 1;
649 sf->rt_sf.estimate_motion_for_var_based_partition = 1;
650 sf->rt_sf.hybrid_intra_pickmode = 0;
651 sf->rt_sf.nonrd_prune_ref_frame_search = 0;
652 sf->rt_sf.reuse_inter_pred_nonrd = 0;
653 sf->rt_sf.use_comp_ref_nonrd = 1;
654 sf->rt_sf.use_nonrd_filter_search = 1;
655 sf->rt_sf.use_nonrd_pick_mode = 0;
656 sf->rt_sf.use_real_time_ref_set = 0;
657 sf->tx_sf.adaptive_txb_search_level = 1;
658 sf->tx_sf.intra_tx_size_search_init_depth_sqr = 1;
659 sf->tx_sf.model_based_prune_tx_search_level = 1;
660 sf->tx_sf.tx_type_search.use_reduced_intra_txset = 1;
661
662 if (speed >= 1) {
663 sf->gm_sf.gm_erroradv_type = GM_ERRORADV_TR_1;
664 sf->gm_sf.gm_search_type = GM_REDUCED_REF_SEARCH_SKIP_L2_L3_ARF2;
665
666 sf->part_sf.prune_ext_partition_types_search_level = 2;
667 sf->part_sf.simple_motion_search_prune_rect = 1;
668
669 sf->mv_sf.obmc_full_pixel_search_level = 1;
670 sf->mv_sf.use_accurate_subpel_search = USE_4_TAPS;
671
672 sf->inter_sf.prune_comp_search_by_single_result = 1;
673 sf->inter_sf.reuse_inter_intra_mode = 1;
674 sf->inter_sf.selective_ref_frame = 2;
675 sf->inter_sf.skip_repeated_newmv = 1;
676 sf->inter_sf.disable_wedge_search_var_thresh = 0;
677 sf->inter_sf.disable_wedge_search_edge_thresh = 0;
678 sf->inter_sf.prune_comp_type_by_comp_avg = 1;
679 sf->inter_sf.prune_motion_mode_level = 2;
680 sf->inter_sf.prune_single_motion_modes_by_simple_trans = 1;
681
682 sf->interp_sf.cb_pred_filter_search = 1;
683 sf->interp_sf.use_interp_filter = 1;
684
685 sf->tx_sf.adaptive_txb_search_level = 2;
686 sf->tx_sf.intra_tx_size_search_init_depth_rect = 1;
687 sf->tx_sf.tx_size_search_lgr_block = 1;
688 sf->tx_sf.tx_type_search.ml_tx_split_thresh = 4000;
689 sf->tx_sf.tx_type_search.skip_tx_search = 1;
690 sf->tx_sf.use_intra_txb_hash = 1;
691
692 sf->rd_sf.optimize_b_precheck = 1;
693 sf->rd_sf.tx_domain_dist_level = boosted ? 0 : 1;
694 sf->rd_sf.tx_domain_dist_thres_level = 1;
695
696 sf->lpf_sf.dual_sgr_penalty_level = 1;
697 }
698
699 if (speed >= 2) {
700 sf->gm_sf.gm_erroradv_type = GM_ERRORADV_TR_2;
701
702 sf->part_sf.allow_partition_search_skip = 1;
703 sf->part_sf.partition_search_breakout_rate_thr = 80;
704
705 sf->mv_sf.auto_mv_step_size = 1;
706 sf->mv_sf.subpel_iters_per_step = 1;
707
708 sf->inter_sf.adaptive_rd_thresh = 1;
709 sf->inter_sf.comp_inter_joint_search_thresh = BLOCK_SIZES_ALL;
710 sf->inter_sf.disable_wedge_search_edge_thresh = 0;
711 sf->inter_sf.disable_wedge_search_var_thresh = 100;
712 sf->inter_sf.fast_wedge_sign_estimate = 1;
713 sf->inter_sf.prune_comp_type_by_comp_avg = 2;
714 sf->inter_sf.selective_ref_frame = 3;
715 sf->inter_sf.use_dist_wtd_comp_flag = DIST_WTD_COMP_DISABLED;
716
717 sf->interp_sf.adaptive_interp_filter_search = 1;
718 sf->interp_sf.cb_pred_filter_search = 0;
719 sf->interp_sf.disable_dual_filter = 1;
720 sf->interp_sf.disable_filter_search_var_thresh = 100;
721
722 sf->tx_sf.inter_tx_size_search_init_depth_rect = 1;
723 sf->tx_sf.inter_tx_size_search_init_depth_sqr = 1;
724 sf->tx_sf.model_based_prune_tx_search_level = 0;
725
726 sf->lpf_sf.cdef_pick_method = CDEF_FAST_SEARCH_LVL1;
727 }
728
729 if (speed >= 3) {
730 sf->hl_sf.recode_loop = ALLOW_RECODE_KFARFGF;
731
732 sf->gm_sf.gm_search_type = GM_DISABLE_SEARCH;
733
734 sf->part_sf.less_rectangular_check_level = 2;
735
736 sf->mv_sf.use_accurate_subpel_search = USE_2_TAPS;
737 // adaptive_motion_search breaks encoder multi-thread tests.
738 // The values in x->pred_mv[] differ for single and multi-thread cases.
739 // See aomedia:1778.
740 // sf->mv_sf.adaptive_motion_search = 1;
741
742 sf->inter_sf.adaptive_rd_thresh = 2;
743 sf->inter_sf.disable_sb_level_mv_cost_upd = 1;
744 // TODO(yunqing): evaluate this speed feature for speed 1 & 2, and combine
745 // it with cpi->sf.disable_wedge_search_var_thresh.
746 sf->inter_sf.disable_wedge_interintra_search = 1;
747 sf->inter_sf.prune_comp_search_by_single_result = 2;
748 sf->inter_sf.prune_motion_mode_level = boosted ? 2 : 3;
749 sf->inter_sf.prune_warp_using_wmtype = 1;
750 sf->inter_sf.selective_ref_frame = 4;
751
752 sf->tx_sf.tx_type_search.prune_mode = PRUNE_2D_FAST;
753
754 sf->rd_sf.tx_domain_dist_level = 1;
755
756 sf->winner_mode_sf.tx_size_search_level = boosted ? 0 : 2;
757 }
758
759 if (speed >= 4) {
760 sf->mv_sf.subpel_search_method = SUBPEL_TREE_PRUNED;
761
762 sf->inter_sf.adaptive_mode_search = 1;
763 sf->inter_sf.alt_ref_search_fp = 1;
764
765 sf->interp_sf.skip_sharp_interp_filter_search = 1;
766
767 sf->tx_sf.tx_type_search.fast_inter_tx_type_search = 1;
768 sf->tx_sf.tx_type_search.fast_intra_tx_type_search = 1;
769 sf->tx_sf.use_intra_txb_hash = 0;
770
771 sf->rd_sf.use_mb_rd_hash = 0;
772
773 sf->winner_mode_sf.tx_size_search_level = frame_is_intra_only(cm) ? 0 : 2;
774 }
775
776 if (speed >= 5) {
777 sf->hl_sf.recode_loop = ALLOW_RECODE_KFMAXBW;
778
779 sf->inter_sf.adaptive_rd_thresh = 4;
780 sf->interp_sf.disable_filter_search_var_thresh = 200;
781
782 sf->rd_sf.use_fast_coef_costing = 1;
783 sf->rd_sf.tx_domain_dist_level = 2;
784 sf->rd_sf.tx_domain_dist_thres_level = 2;
785 sf->winner_mode_sf.tx_size_search_level = 1;
786
787 sf->rt_sf.mode_search_skip_flags =
788 (cm->current_frame.frame_type == KEY_FRAME)
789 ? 0
790 : FLAG_SKIP_INTRA_DIRMISMATCH | FLAG_SKIP_INTRA_BESTINTER |
791 FLAG_SKIP_COMP_BESTINTRA | FLAG_SKIP_INTRA_LOWVAR |
792 FLAG_EARLY_TERMINATE;
793 sf->hl_sf.frame_parameter_update = 0;
794
795 sf->part_sf.default_max_partition_size = BLOCK_128X128;
796 sf->part_sf.default_min_partition_size = BLOCK_8X8;
797 sf->part_sf.max_intra_bsize = BLOCK_32X32;
798 sf->part_sf.partition_search_breakout_rate_thr = 500;
799 sf->part_sf.partition_search_type = VAR_BASED_PARTITION;
800 sf->part_sf.adjust_var_based_rd_partitioning = 2;
801
802 sf->mv_sf.search_method = FAST_DIAMOND;
803 sf->mv_sf.subpel_force_stop = QUARTER_PEL;
804 sf->mv_sf.use_fullpel_costlist = 1;
805 sf->mv_sf.subpel_search_method = SUBPEL_TREE_PRUNED_MORE;
806
807 sf->inter_sf.adaptive_mode_search = 2;
808 sf->inter_sf.inter_mode_rd_model_estimation = 2;
809
810 for (int i = 0; i < TX_SIZES; ++i) {
811 sf->intra_sf.intra_y_mode_mask[i] = INTRA_DC;
812 sf->intra_sf.intra_uv_mode_mask[i] = UV_INTRA_DC_CFL;
813 }
814
815 sf->tx_sf.tx_type_search.prune_mode = PRUNE_2D_MORE;
816 sf->tx_sf.use_inter_txb_hash = 0;
817 sf->tx_sf.refine_fast_tx_search_results = 0;
818
819 sf->rd_sf.optimize_coefficients = NO_TRELLIS_OPT;
820 sf->rd_sf.simple_model_rd_from_var = 1;
821
822 sf->lpf_sf.cdef_pick_method = CDEF_PICK_FROM_Q;
823 sf->lpf_sf.lpf_pick = LPF_PICK_FROM_Q;
824
825 sf->rt_sf.mode_search_skip_flags |= FLAG_SKIP_INTRA_DIRMISMATCH;
826 sf->rt_sf.num_inter_modes_for_tx_search = 5;
827 sf->rt_sf.skip_interp_filter_search = 1;
828 sf->rt_sf.use_comp_ref_nonrd = 0;
829 sf->rt_sf.use_real_time_ref_set = 1;
830 sf->rt_sf.use_simple_rd_model = 1;
831 }
832
833 if (speed >= 6) {
834 sf->part_sf.adjust_var_based_rd_partitioning = 1;
835 }
836
837 if (speed >= 7) {
838 sf->hl_sf.frame_parameter_update = 0;
839
840 sf->part_sf.default_max_partition_size = BLOCK_128X128;
841 sf->part_sf.default_min_partition_size = BLOCK_8X8;
842 sf->part_sf.partition_search_type = VAR_BASED_PARTITION;
843
844 sf->mv_sf.search_method = FAST_DIAMOND;
845 sf->mv_sf.subpel_force_stop = QUARTER_PEL;
846 sf->mv_sf.subpel_search_method = SUBPEL_TREE_PRUNED;
847
848 sf->inter_sf.inter_mode_rd_model_estimation = 2;
849
850 sf->lpf_sf.cdef_pick_method = CDEF_PICK_FROM_Q;
851 sf->lpf_sf.lpf_pick = LPF_PICK_FROM_Q;
852
853 sf->rt_sf.mode_search_skip_flags |= FLAG_SKIP_INTRA_DIRMISMATCH;
854 sf->rt_sf.nonrd_prune_ref_frame_search = 1;
855 sf->rt_sf.reuse_inter_pred_nonrd = 0;
856 sf->rt_sf.short_circuit_low_temp_var = 0;
857 sf->rt_sf.skip_interp_filter_search = 0;
858 sf->rt_sf.use_comp_ref_nonrd = 0;
859 sf->rt_sf.use_nonrd_altref_frame = 1;
860 sf->rt_sf.use_nonrd_pick_mode = 1;
861 sf->rt_sf.nonrd_check_partition_merge_mode = 1;
862 sf->rt_sf.nonrd_check_partition_split = 0;
863 sf->rt_sf.hybrid_intra_pickmode = 1;
864 }
865
866 if (speed >= 8) {
867 sf->rt_sf.estimate_motion_for_var_based_partition = 0;
868 sf->rt_sf.short_circuit_low_temp_var = 1;
869 sf->rt_sf.reuse_inter_pred_nonrd = 1;
870 sf->rt_sf.use_nonrd_altref_frame = 0;
871 sf->rt_sf.nonrd_prune_ref_frame_search = 2;
872 sf->rt_sf.nonrd_check_partition_merge_mode = 0;
873 sf->rt_sf.nonrd_check_partition_split = 0;
874 sf->rt_sf.use_modeled_non_rd_cost = 1;
875 sf->rt_sf.source_metrics_sb_nonrd = 1;
876 sf->interp_sf.cb_pred_filter_search = 1;
877 }
878 }
879
init_hl_sf(HIGH_LEVEL_SPEED_FEATURES * hl_sf)880 static AOM_INLINE void init_hl_sf(HIGH_LEVEL_SPEED_FEATURES *hl_sf) {
881 // best quality defaults
882 hl_sf->frame_parameter_update = 1;
883 hl_sf->recode_loop = ALLOW_RECODE;
884 hl_sf->disable_overlay_frames = 0;
885 hl_sf->adaptive_overlay_encoding = 1;
886 // Recode loop tolerance %.
887 hl_sf->recode_tolerance = 25;
888 hl_sf->high_precision_mv_usage = CURRENT_Q;
889 hl_sf->second_alt_ref_filtering = 1;
890 }
891
init_tpl_sf(TPL_SPEED_FEATURES * tpl_sf)892 static AOM_INLINE void init_tpl_sf(TPL_SPEED_FEATURES *tpl_sf) {
893 tpl_sf->prune_intra_modes = 0;
894 tpl_sf->reduce_first_step_size = 0;
895 tpl_sf->skip_alike_starting_mv = 0;
896 tpl_sf->subpel_force_stop = EIGHTH_PEL;
897 }
898
init_gm_sf(GLOBAL_MOTION_SPEED_FEATURES * gm_sf)899 static AOM_INLINE void init_gm_sf(GLOBAL_MOTION_SPEED_FEATURES *gm_sf) {
900 gm_sf->gm_erroradv_type = GM_ERRORADV_TR_0;
901 gm_sf->disable_adaptive_warp_error_thresh = 1;
902 gm_sf->selective_ref_gm = 1;
903 gm_sf->gm_search_type = GM_FULL_SEARCH;
904 gm_sf->gm_disable_recode = 0;
905 gm_sf->prune_ref_frame_for_gm_search = 0;
906 }
907
init_part_sf(PARTITION_SPEED_FEATURES * part_sf)908 static AOM_INLINE void init_part_sf(PARTITION_SPEED_FEATURES *part_sf) {
909 part_sf->partition_search_type = SEARCH_PARTITION;
910 part_sf->less_rectangular_check_level = 0;
911 part_sf->use_square_partition_only_threshold = BLOCK_128X128;
912 part_sf->auto_max_partition_based_on_simple_motion = NOT_IN_USE;
913 part_sf->auto_min_partition_based_on_simple_motion = 0;
914 part_sf->default_max_partition_size = BLOCK_LARGEST;
915 part_sf->default_min_partition_size = BLOCK_4X4;
916 part_sf->adjust_var_based_rd_partitioning = 0;
917 part_sf->allow_partition_search_skip = 0;
918 part_sf->max_intra_bsize = BLOCK_LARGEST;
919 // This setting only takes effect when partition_search_type is set
920 // to FIXED_PARTITION.
921 part_sf->always_this_block_size = BLOCK_16X16;
922 // Recode loop tolerance %.
923 part_sf->partition_search_breakout_dist_thr = 0;
924 part_sf->partition_search_breakout_rate_thr = 0;
925 part_sf->prune_ext_partition_types_search_level = 0;
926 part_sf->ml_prune_rect_partition = 0;
927 part_sf->ml_prune_ab_partition = 0;
928 part_sf->ml_prune_4_partition = 0;
929 part_sf->ml_early_term_after_part_split_level = 0;
930 for (int i = 0; i < PARTITION_BLOCK_SIZES; ++i) {
931 part_sf->ml_partition_search_breakout_thresh[i] =
932 -1; // -1 means not enabled.
933 }
934 part_sf->simple_motion_search_prune_agg = 0;
935 part_sf->simple_motion_search_split = 0;
936 part_sf->simple_motion_search_prune_rect = 0;
937 part_sf->simple_motion_search_early_term_none = 0;
938 part_sf->intra_cnn_split = 0;
939 part_sf->ext_partition_eval_thresh = BLOCK_8X8;
940 part_sf->prune_4_partition_using_split_info = 0;
941 part_sf->prune_ab_partition_using_split_info = 0;
942 }
943
init_mv_sf(MV_SPEED_FEATURES * mv_sf)944 static AOM_INLINE void init_mv_sf(MV_SPEED_FEATURES *mv_sf) {
945 mv_sf->full_pixel_search_level = 0;
946 mv_sf->adaptive_motion_search = 0;
947 mv_sf->auto_mv_step_size = 0;
948 mv_sf->exhaustive_searches_thresh = 0;
949 mv_sf->obmc_full_pixel_search_level = 0;
950 mv_sf->prune_mesh_search = 0;
951 mv_sf->reduce_search_range = 0;
952 mv_sf->search_method = NSTEP;
953 mv_sf->simple_motion_subpel_force_stop = EIGHTH_PEL;
954 mv_sf->subpel_force_stop = EIGHTH_PEL;
955 mv_sf->subpel_iters_per_step = 2;
956 mv_sf->subpel_search_method = SUBPEL_TREE;
957 mv_sf->use_accurate_subpel_search = USE_8_TAPS;
958 mv_sf->use_fullpel_costlist = 0;
959 }
960
init_inter_sf(INTER_MODE_SPEED_FEATURES * inter_sf)961 static AOM_INLINE void init_inter_sf(INTER_MODE_SPEED_FEATURES *inter_sf) {
962 inter_sf->comp_inter_joint_search_thresh = BLOCK_4X4;
963 inter_sf->adaptive_rd_thresh = 0;
964 inter_sf->model_based_post_interp_filter_breakout = 0;
965 inter_sf->reduce_inter_modes = 0;
966 inter_sf->adaptive_mode_search = 0;
967 inter_sf->alt_ref_search_fp = 0;
968 inter_sf->selective_ref_frame = 0;
969 inter_sf->prune_ref_frame_for_rect_partitions = 0;
970 inter_sf->disable_wedge_search_edge_thresh = 0;
971 inter_sf->disable_wedge_search_var_thresh = 0;
972 inter_sf->fast_wedge_sign_estimate = 0;
973 inter_sf->prune_wedge_pred_diff_based = 0;
974 inter_sf->use_dist_wtd_comp_flag = DIST_WTD_COMP_ENABLED;
975 inter_sf->reuse_inter_intra_mode = 0;
976 inter_sf->disable_sb_level_coeff_cost_upd = 0;
977 inter_sf->disable_sb_level_mv_cost_upd = 0;
978 inter_sf->prune_inter_modes_based_on_tpl = 0;
979 inter_sf->prune_comp_search_by_single_result = 0;
980 inter_sf->skip_repeated_ref_mv = 0;
981 inter_sf->skip_repeated_newmv = 0;
982 inter_sf->skip_repeated_full_newmv = 0;
983 inter_sf->prune_single_motion_modes_by_simple_trans = 0;
984 inter_sf->inter_mode_rd_model_estimation = 0;
985 inter_sf->prune_compound_using_single_ref = 0;
986 inter_sf->prune_compound_using_neighbors = 0;
987 inter_sf->disable_onesided_comp = 0;
988 inter_sf->prune_mode_search_simple_translation = 0;
989 inter_sf->prune_comp_type_by_comp_avg = 0;
990 inter_sf->disable_interinter_wedge_newmv_search = 0;
991 inter_sf->enable_interinter_diffwtd_newmv_search = 0;
992 inter_sf->disable_smooth_interintra = 0;
993 inter_sf->prune_motion_mode_level = 0;
994 inter_sf->prune_warp_using_wmtype = 0;
995 inter_sf->disable_wedge_interintra_search = 0;
996 inter_sf->fast_interintra_wedge_search = 0;
997 inter_sf->prune_comp_type_by_model_rd = 0;
998 inter_sf->perform_best_rd_based_gating_for_chroma = 0;
999 inter_sf->prune_obmc_prob_thresh = 0;
1000 inter_sf->disable_obmc = 0;
1001 inter_sf->disable_interinter_wedge = 0;
1002 inter_sf->prune_ref_mv_idx_search = 0;
1003 inter_sf->prune_warped_prob_thresh = 0;
1004 inter_sf->reuse_compound_type_decision = 0;
1005 inter_sf->txfm_rd_gate_level = 0;
1006 inter_sf->prune_inter_modes_if_skippable = 0;
1007 }
1008
init_interp_sf(INTERP_FILTER_SPEED_FEATURES * interp_sf)1009 static AOM_INLINE void init_interp_sf(INTERP_FILTER_SPEED_FEATURES *interp_sf) {
1010 interp_sf->disable_filter_search_var_thresh = 0;
1011 interp_sf->adaptive_interp_filter_search = 0;
1012 interp_sf->use_fast_interpolation_filter_search = 0;
1013 interp_sf->disable_dual_filter = 0;
1014 interp_sf->use_interp_filter = 0;
1015 interp_sf->skip_sharp_interp_filter_search = 0;
1016 }
1017
init_intra_sf(INTRA_MODE_SPEED_FEATURES * intra_sf)1018 static AOM_INLINE void init_intra_sf(INTRA_MODE_SPEED_FEATURES *intra_sf) {
1019 intra_sf->skip_intra_in_interframe = 1;
1020 intra_sf->intra_pruning_with_hog = 0;
1021 intra_sf->src_var_thresh_intra_skip = 1;
1022 intra_sf->prune_palette_search_level = 0;
1023
1024 for (int i = 0; i < TX_SIZES; i++) {
1025 intra_sf->intra_y_mode_mask[i] = INTRA_ALL;
1026 intra_sf->intra_uv_mode_mask[i] = UV_INTRA_ALL;
1027 }
1028 intra_sf->disable_smooth_intra = 0;
1029 }
1030
init_tx_sf(TX_SPEED_FEATURES * tx_sf)1031 static AOM_INLINE void init_tx_sf(TX_SPEED_FEATURES *tx_sf) {
1032 tx_sf->inter_tx_size_search_init_depth_sqr = 0;
1033 tx_sf->inter_tx_size_search_init_depth_rect = 0;
1034 tx_sf->intra_tx_size_search_init_depth_rect = 0;
1035 tx_sf->intra_tx_size_search_init_depth_sqr = 0;
1036 tx_sf->tx_size_search_lgr_block = 0;
1037 tx_sf->model_based_prune_tx_search_level = 0;
1038 tx_sf->tx_type_search.prune_mode = PRUNE_2D_ACCURATE;
1039 tx_sf->tx_type_search.ml_tx_split_thresh = 8500;
1040 tx_sf->tx_type_search.use_skip_flag_prediction = 1;
1041 tx_sf->tx_type_search.use_reduced_intra_txset = 0;
1042 tx_sf->tx_type_search.fast_intra_tx_type_search = 0;
1043 tx_sf->tx_type_search.fast_inter_tx_type_search = 0;
1044 tx_sf->tx_type_search.skip_tx_search = 0;
1045 tx_sf->tx_type_search.prune_tx_type_using_stats = 0;
1046 tx_sf->tx_type_search.prune_tx_type_est_rd = 0;
1047 tx_sf->tx_type_search.enable_winner_mode_tx_type_pruning = 0;
1048 tx_sf->txb_split_cap = 1;
1049 tx_sf->adaptive_txb_search_level = 0;
1050 tx_sf->use_intra_txb_hash = 0;
1051 tx_sf->use_inter_txb_hash = 1;
1052 tx_sf->refine_fast_tx_search_results = 1;
1053 }
1054
init_rd_sf(RD_CALC_SPEED_FEATURES * rd_sf,const AV1_COMP * cpi)1055 static AOM_INLINE void init_rd_sf(RD_CALC_SPEED_FEATURES *rd_sf,
1056 const AV1_COMP *cpi) {
1057 if (cpi->oxcf.disable_trellis_quant == 3) {
1058 rd_sf->optimize_coefficients = !is_lossless_requested(&cpi->oxcf)
1059 ? NO_ESTIMATE_YRD_TRELLIS_OPT
1060 : NO_TRELLIS_OPT;
1061 } else if (cpi->oxcf.disable_trellis_quant == 2) {
1062 rd_sf->optimize_coefficients = !is_lossless_requested(&cpi->oxcf)
1063 ? FINAL_PASS_TRELLIS_OPT
1064 : NO_TRELLIS_OPT;
1065 } else if (cpi->oxcf.disable_trellis_quant == 0) {
1066 if (is_lossless_requested(&cpi->oxcf)) {
1067 rd_sf->optimize_coefficients = NO_TRELLIS_OPT;
1068 } else {
1069 rd_sf->optimize_coefficients = FULL_TRELLIS_OPT;
1070 }
1071 } else if (cpi->oxcf.disable_trellis_quant == 1) {
1072 rd_sf->optimize_coefficients = NO_TRELLIS_OPT;
1073 } else {
1074 assert(0 && "Invalid disable_trellis_quant value");
1075 }
1076 // TODO(sarahparker) Pair this with a speed setting once experiments are done
1077 rd_sf->trellis_eob_fast = 0;
1078 rd_sf->use_mb_rd_hash = 1;
1079 rd_sf->optimize_b_precheck = 0;
1080 rd_sf->use_fast_coef_costing = 0;
1081 rd_sf->simple_model_rd_from_var = 0;
1082 rd_sf->tx_domain_dist_level = 0;
1083 rd_sf->tx_domain_dist_thres_level = 0;
1084 rd_sf->use_hash_based_trellis = 0;
1085 rd_sf->perform_coeff_opt = 0;
1086 }
1087
init_winner_mode_sf(WINNER_MODE_SPEED_FEATURES * winner_mode_sf)1088 static AOM_INLINE void init_winner_mode_sf(
1089 WINNER_MODE_SPEED_FEATURES *winner_mode_sf) {
1090 winner_mode_sf->motion_mode_for_winner_cand = 0;
1091 // Set this at the appropriate speed levels
1092 winner_mode_sf->tx_size_search_level = USE_FULL_RD;
1093 winner_mode_sf->enable_winner_mode_for_coeff_opt = 0;
1094 winner_mode_sf->enable_winner_mode_for_tx_size_srch = 0;
1095 winner_mode_sf->enable_winner_mode_for_use_tx_domain_dist = 0;
1096 winner_mode_sf->enable_multiwinner_mode_process = 0;
1097 }
1098
init_lpf_sf(LOOP_FILTER_SPEED_FEATURES * lpf_sf)1099 static AOM_INLINE void init_lpf_sf(LOOP_FILTER_SPEED_FEATURES *lpf_sf) {
1100 lpf_sf->disable_loop_restoration_chroma = 0;
1101 lpf_sf->prune_wiener_based_on_src_var = 0;
1102 lpf_sf->prune_sgr_based_on_wiener = 0;
1103 lpf_sf->enable_sgr_ep_pruning = 0;
1104 lpf_sf->reduce_wiener_window_size = 0;
1105 lpf_sf->lpf_pick = LPF_PICK_FROM_FULL_IMAGE;
1106 lpf_sf->cdef_pick_method = CDEF_FULL_SEARCH;
1107 // Set decoder side speed feature to use less dual sgr modes
1108 lpf_sf->dual_sgr_penalty_level = 0;
1109 lpf_sf->disable_lr_filter = 0;
1110 }
1111
init_rt_sf(REAL_TIME_SPEED_FEATURES * rt_sf)1112 static AOM_INLINE void init_rt_sf(REAL_TIME_SPEED_FEATURES *rt_sf) {
1113 rt_sf->mode_search_skip_flags = 0;
1114 rt_sf->skip_interp_filter_search = 0;
1115 rt_sf->force_tx_search_off = 0;
1116 rt_sf->num_inter_modes_for_tx_search = INT_MAX;
1117 rt_sf->use_simple_rd_model = 0;
1118 rt_sf->nonrd_check_partition_merge_mode = 0;
1119 rt_sf->nonrd_check_partition_split = 0;
1120 }
1121
av1_set_speed_features_framesize_dependent(AV1_COMP * cpi,int speed)1122 void av1_set_speed_features_framesize_dependent(AV1_COMP *cpi, int speed) {
1123 SPEED_FEATURES *const sf = &cpi->sf;
1124 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
1125
1126 if (oxcf->mode == GOOD) {
1127 set_good_speed_feature_framesize_dependent(cpi, sf, speed);
1128 } else if (oxcf->mode == REALTIME) {
1129 set_rt_speed_feature_framesize_dependent(cpi, sf, speed);
1130 }
1131
1132 // This is only used in motion vector unit test.
1133 if (cpi->oxcf.motion_vector_unit_test == 1)
1134 cpi->mv_search_params.find_fractional_mv_step = av1_return_max_sub_pixel_mv;
1135 else if (cpi->oxcf.motion_vector_unit_test == 2)
1136 cpi->mv_search_params.find_fractional_mv_step = av1_return_min_sub_pixel_mv;
1137
1138 MACROBLOCK *const x = &cpi->td.mb;
1139 AV1_COMMON *const cm = &cpi->common;
1140 x->min_partition_size = AOMMAX(sf->part_sf.default_min_partition_size,
1141 dim_to_size(cpi->oxcf.min_partition_size));
1142 x->max_partition_size = AOMMIN(sf->part_sf.default_max_partition_size,
1143 dim_to_size(cpi->oxcf.max_partition_size));
1144 x->min_partition_size = AOMMIN(x->min_partition_size, cm->seq_params.sb_size);
1145 x->max_partition_size = AOMMIN(x->max_partition_size, cm->seq_params.sb_size);
1146 }
1147
av1_set_speed_features_framesize_independent(AV1_COMP * cpi,int speed)1148 void av1_set_speed_features_framesize_independent(AV1_COMP *cpi, int speed) {
1149 AV1_COMMON *const cm = &cpi->common;
1150 SPEED_FEATURES *const sf = &cpi->sf;
1151 MACROBLOCK *const x = &cpi->td.mb;
1152 WinnerModeParams *const winner_mode_params = &cpi->winner_mode_params;
1153 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
1154 int i;
1155
1156 init_hl_sf(&sf->hl_sf);
1157 init_tpl_sf(&sf->tpl_sf);
1158 init_gm_sf(&sf->gm_sf);
1159 init_part_sf(&sf->part_sf);
1160 init_mv_sf(&sf->mv_sf);
1161 init_inter_sf(&sf->inter_sf);
1162 init_interp_sf(&sf->interp_sf);
1163 init_intra_sf(&sf->intra_sf);
1164 init_tx_sf(&sf->tx_sf);
1165 init_rd_sf(&sf->rd_sf, cpi);
1166 init_winner_mode_sf(&sf->winner_mode_sf);
1167 init_lpf_sf(&sf->lpf_sf);
1168 init_rt_sf(&sf->rt_sf);
1169
1170 if (oxcf->mode == GOOD)
1171 set_good_speed_features_framesize_independent(cpi, sf, speed);
1172 else if (oxcf->mode == REALTIME)
1173 set_rt_speed_features_framesize_independent(cpi, sf, speed);
1174
1175 if (!cpi->seq_params_locked) {
1176 cpi->common.seq_params.enable_dual_filter &=
1177 !sf->interp_sf.disable_dual_filter;
1178 cpi->common.seq_params.enable_restoration &= !sf->lpf_sf.disable_lr_filter;
1179 }
1180
1181 // sf->part_sf.partition_search_breakout_dist_thr is set assuming max 64x64
1182 // blocks. Normalise this if the blocks are bigger.
1183 if (MAX_SB_SIZE_LOG2 > 6) {
1184 sf->part_sf.partition_search_breakout_dist_thr <<=
1185 2 * (MAX_SB_SIZE_LOG2 - 6);
1186 }
1187
1188 const int mesh_speed = AOMMIN(speed, MAX_MESH_SPEED);
1189 for (i = 0; i < MAX_MESH_STEP; ++i) {
1190 sf->mv_sf.mesh_patterns[i].range =
1191 good_quality_mesh_patterns[mesh_speed][i].range;
1192 sf->mv_sf.mesh_patterns[i].interval =
1193 good_quality_mesh_patterns[mesh_speed][i].interval;
1194 }
1195
1196 // Update the mesh pattern of exhaustive motion search for intraBC
1197 // Though intraBC mesh pattern is populated for all frame types, it is used
1198 // only for intra frames of screen contents
1199 for (i = 0; i < MAX_MESH_STEP; ++i) {
1200 sf->mv_sf.intrabc_mesh_patterns[i].range =
1201 intrabc_mesh_patterns[mesh_speed][i].range;
1202 sf->mv_sf.intrabc_mesh_patterns[i].interval =
1203 intrabc_mesh_patterns[mesh_speed][i].interval;
1204 }
1205
1206 // Slow quant, dct and trellis not worthwhile for first pass
1207 // so make sure they are always turned off.
1208 if (is_stat_generation_stage(cpi))
1209 sf->rd_sf.optimize_coefficients = NO_TRELLIS_OPT;
1210
1211 // No recode or trellis for 1 pass.
1212 if (oxcf->pass == 0) sf->hl_sf.recode_loop = DISALLOW_RECODE;
1213
1214 MotionVectorSearchParams *const mv_search_params = &cpi->mv_search_params;
1215 if (sf->mv_sf.subpel_search_method == SUBPEL_TREE) {
1216 mv_search_params->find_fractional_mv_step = av1_find_best_sub_pixel_tree;
1217 } else if (sf->mv_sf.subpel_search_method == SUBPEL_TREE_PRUNED) {
1218 mv_search_params->find_fractional_mv_step =
1219 av1_find_best_sub_pixel_tree_pruned;
1220 } else if (sf->mv_sf.subpel_search_method == SUBPEL_TREE_PRUNED_MORE) {
1221 mv_search_params->find_fractional_mv_step =
1222 av1_find_best_sub_pixel_tree_pruned_more;
1223 } else if (sf->mv_sf.subpel_search_method == SUBPEL_TREE_PRUNED_EVENMORE) {
1224 mv_search_params->find_fractional_mv_step =
1225 av1_find_best_sub_pixel_tree_pruned_evenmore;
1226 }
1227
1228 x->min_partition_size = AOMMAX(sf->part_sf.default_min_partition_size,
1229 dim_to_size(cpi->oxcf.min_partition_size));
1230 x->max_partition_size = AOMMIN(sf->part_sf.default_max_partition_size,
1231 dim_to_size(cpi->oxcf.max_partition_size));
1232 x->min_partition_size = AOMMIN(x->min_partition_size, cm->seq_params.sb_size);
1233 x->max_partition_size = AOMMIN(x->max_partition_size, cm->seq_params.sb_size);
1234
1235 // This is only used in motion vector unit test.
1236 if (cpi->oxcf.motion_vector_unit_test == 1)
1237 mv_search_params->find_fractional_mv_step = av1_return_max_sub_pixel_mv;
1238 else if (cpi->oxcf.motion_vector_unit_test == 2)
1239 mv_search_params->find_fractional_mv_step = av1_return_min_sub_pixel_mv;
1240
1241 // assert ensures that tx_domain_dist_level is accessed correctly
1242 assert(cpi->sf.rd_sf.tx_domain_dist_thres_level >= 0 &&
1243 cpi->sf.rd_sf.tx_domain_dist_thres_level < 3);
1244 memcpy(winner_mode_params->tx_domain_dist_threshold,
1245 tx_domain_dist_thresholds[cpi->sf.rd_sf.tx_domain_dist_thres_level],
1246 sizeof(winner_mode_params->tx_domain_dist_threshold));
1247
1248 assert(cpi->sf.rd_sf.tx_domain_dist_level >= 0 &&
1249 cpi->sf.rd_sf.tx_domain_dist_level < 3);
1250 memcpy(winner_mode_params->use_transform_domain_distortion,
1251 tx_domain_dist_types[cpi->sf.rd_sf.tx_domain_dist_level],
1252 sizeof(winner_mode_params->use_transform_domain_distortion));
1253
1254 // assert ensures that coeff_opt_dist_thresholds is accessed correctly
1255 assert(cpi->sf.rd_sf.perform_coeff_opt >= 0 &&
1256 cpi->sf.rd_sf.perform_coeff_opt < 6);
1257 memcpy(winner_mode_params->coeff_opt_dist_threshold,
1258 coeff_opt_dist_thresholds[cpi->sf.rd_sf.perform_coeff_opt],
1259 sizeof(winner_mode_params->coeff_opt_dist_threshold));
1260
1261 // assert ensures that predict_skip_levels is accessed correctly
1262 assert(cpi->sf.tx_sf.tx_type_search.use_skip_flag_prediction >= 0 &&
1263 cpi->sf.tx_sf.tx_type_search.use_skip_flag_prediction < 3);
1264 memcpy(winner_mode_params->predict_skip_level,
1265 predict_skip_levels[cpi->sf.tx_sf.tx_type_search
1266 .use_skip_flag_prediction],
1267 sizeof(winner_mode_params->predict_skip_level));
1268
1269 // assert ensures that tx_size_search_level is accessed correctly
1270 assert(cpi->sf.winner_mode_sf.tx_size_search_level >= 0 &&
1271 cpi->sf.winner_mode_sf.tx_size_search_level < 3);
1272 memcpy(winner_mode_params->tx_size_search_methods,
1273 tx_size_search_methods[cpi->sf.winner_mode_sf.tx_size_search_level],
1274 sizeof(winner_mode_params->tx_size_search_methods));
1275
1276 if (cpi->oxcf.row_mt == 1 && (cpi->oxcf.max_threads > 1)) {
1277 if (sf->inter_sf.inter_mode_rd_model_estimation == 1) {
1278 // Revert to type 2
1279 sf->inter_sf.inter_mode_rd_model_estimation = 2;
1280 }
1281 }
1282 }
1283
1284 // Override some speed features based on qindex
av1_set_speed_features_qindex_dependent(AV1_COMP * cpi,int speed)1285 void av1_set_speed_features_qindex_dependent(AV1_COMP *cpi, int speed) {
1286 AV1_COMMON *const cm = &cpi->common;
1287 SPEED_FEATURES *const sf = &cpi->sf;
1288 WinnerModeParams *const winner_mode_params = &cpi->winner_mode_params;
1289 const int boosted = frame_is_boosted(cpi);
1290 const int is_720p_or_larger = AOMMIN(cm->width, cm->height) >= 720;
1291 if (is_720p_or_larger && cpi->oxcf.mode == GOOD && speed == 0) {
1292 if (cm->quant_params.base_qindex <= 80) {
1293 sf->rd_sf.perform_coeff_opt = 2;
1294 memcpy(winner_mode_params->coeff_opt_dist_threshold,
1295 coeff_opt_dist_thresholds[sf->rd_sf.perform_coeff_opt],
1296 sizeof(winner_mode_params->coeff_opt_dist_threshold));
1297 sf->part_sf.simple_motion_search_split =
1298 cm->features.allow_screen_content_tools ? 1 : 2;
1299 sf->tx_sf.inter_tx_size_search_init_depth_rect = 1;
1300 sf->tx_sf.inter_tx_size_search_init_depth_sqr = 1;
1301 sf->tx_sf.intra_tx_size_search_init_depth_rect = 1;
1302 }
1303 }
1304
1305 if (cpi->oxcf.mode == GOOD && speed >= 3) {
1306 // Disable extended partitions for lower quantizers
1307 if (cm->quant_params.base_qindex <= 100 &&
1308 !cm->features.allow_screen_content_tools && !boosted) {
1309 sf->part_sf.ext_partition_eval_thresh = BLOCK_128X128;
1310 }
1311 }
1312
1313 if (cpi->oxcf.mode == GOOD && speed >= 4) {
1314 // Disable extended partitions for lower quantizers
1315 const int qindex_thresh = boosted ? 80 : 120;
1316 if (cm->quant_params.base_qindex <= qindex_thresh &&
1317 !cm->features.allow_screen_content_tools &&
1318 !frame_is_intra_only(&cpi->common)) {
1319 sf->part_sf.ext_partition_eval_thresh = BLOCK_128X128;
1320 }
1321 }
1322 }
1323