1/*
2 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <limits.h>
12
13#include "vp9/encoder/vp9_onyx_int.h"
14#include "vp9/encoder/vp9_speed_features.h"
15
16#define ALL_INTRA_MODES ((1 << DC_PRED) | \
17                         (1 << V_PRED) | (1 << H_PRED) | \
18                         (1 << D45_PRED) | (1 << D135_PRED) | \
19                         (1 << D117_PRED) | (1 << D153_PRED) | \
20                         (1 << D207_PRED) | (1 << D63_PRED) | \
21                         (1 << TM_PRED))
22#define INTRA_DC_ONLY   (1 << DC_PRED)
23#define INTRA_DC_TM     ((1 << TM_PRED) | (1 << DC_PRED))
24#define INTRA_DC_H_V    ((1 << DC_PRED) | (1 << V_PRED) | (1 << H_PRED))
25#define INTRA_DC_TM_H_V (INTRA_DC_TM | (1 << V_PRED) | (1 << H_PRED))
26
27// Masks for partially or completely disabling split mode
28#define DISABLE_ALL_INTER_SPLIT   ((1 << THR_COMP_GA) | \
29                                   (1 << THR_COMP_LA) | \
30                                   (1 << THR_ALTR) | \
31                                   (1 << THR_GOLD) | \
32                                   (1 << THR_LAST))
33
34#define DISABLE_ALL_SPLIT         ((1 << THR_INTRA) | DISABLE_ALL_INTER_SPLIT)
35
36#define DISABLE_COMPOUND_SPLIT    ((1 << THR_COMP_GA) | (1 << THR_COMP_LA))
37
38#define LAST_AND_INTRA_SPLIT_ONLY ((1 << THR_COMP_GA) | \
39                                   (1 << THR_COMP_LA) | \
40                                   (1 << THR_ALTR) | \
41                                   (1 << THR_GOLD))
42
43static void set_good_speed_feature(VP9_COMP *cpi,
44                                   VP9_COMMON *cm,
45                                   SPEED_FEATURES *sf,
46                                   int speed) {
47  int i;
48  sf->adaptive_rd_thresh = 1;
49  sf->recode_loop = ((speed < 1) ? ALLOW_RECODE : ALLOW_RECODE_KFMAXBW);
50  sf->allow_skip_recode = 1;
51
52  if (speed >= 1) {
53    sf->use_square_partition_only = !frame_is_intra_only(cm);
54    sf->less_rectangular_check  = 1;
55    sf->tx_size_search_method = vp9_frame_is_boosted(cpi)
56      ? USE_FULL_RD : USE_LARGESTALL;
57
58    if (MIN(cm->width, cm->height) >= 720)
59      sf->disable_split_mask = cm->show_frame ?
60        DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT;
61    else
62      sf->disable_split_mask = DISABLE_COMPOUND_SPLIT;
63    sf->use_rd_breakout = 1;
64    sf->adaptive_motion_search = 1;
65    sf->auto_mv_step_size = 1;
66    sf->adaptive_rd_thresh = 2;
67    sf->subpel_iters_per_step = 1;
68    sf->mode_skip_start = 10;
69    sf->adaptive_pred_interp_filter = 1;
70
71    sf->recode_loop = ALLOW_RECODE_KFARFGF;
72    sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V;
73    sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC_H_V;
74    sf->intra_y_mode_mask[TX_16X16] = INTRA_DC_H_V;
75    sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
76  }
77  // Additions or changes from speed 1 for speed >= 2.
78  if (speed >= 2) {
79    sf->tx_size_search_method = vp9_frame_is_boosted(cpi)
80      ? USE_FULL_RD : USE_LARGESTALL;
81
82    if (MIN(cm->width, cm->height) >= 720)
83      sf->disable_split_mask = cm->show_frame ?
84        DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT;
85    else
86      sf->disable_split_mask = LAST_AND_INTRA_SPLIT_ONLY;
87
88    sf->adaptive_pred_interp_filter = 2;
89
90    sf->reference_masking = 1;
91    sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH |
92                                 FLAG_SKIP_INTRA_BESTINTER |
93                                 FLAG_SKIP_COMP_BESTINTRA |
94                                 FLAG_SKIP_INTRA_LOWVAR;
95    sf->disable_filter_search_var_thresh = 100;
96    sf->comp_inter_joint_search_thresh = BLOCK_SIZES;
97
98    sf->auto_min_max_partition_size = RELAXED_NEIGHBORING_MIN_MAX;
99    sf->use_lastframe_partitioning = LAST_FRAME_PARTITION_LOW_MOTION;
100    sf->adjust_partitioning_from_last_frame = 1;
101    sf->last_partitioning_redo_frequency = 3;
102  }
103  // Additions or changes for speed 3 and above
104  if (speed >= 3) {
105    if (MIN(cm->width, cm->height) >= 720)
106      sf->disable_split_mask = DISABLE_ALL_SPLIT;
107    else
108      sf->disable_split_mask = DISABLE_ALL_INTER_SPLIT;
109
110    sf->recode_loop = ALLOW_RECODE_KFMAXBW;
111
112    sf->adaptive_rd_thresh = 3;
113    sf->mode_skip_start = 6;
114    sf->use_fast_coef_updates = 2;
115    sf->use_fast_coef_costing = 1;
116  }
117  // Additions or changes for speed 3 and above
118  if (speed >= 4) {
119    sf->use_square_partition_only = 1;
120    sf->tx_size_search_method = USE_LARGESTALL;
121    sf->disable_split_mask = DISABLE_ALL_SPLIT;
122
123    sf->adaptive_rd_thresh = 4;
124
125    // Add a couple more skip flags
126    sf->mode_search_skip_flags |= FLAG_SKIP_COMP_REFMISMATCH |
127                                  FLAG_EARLY_TERMINATE;
128
129    sf->disable_filter_search_var_thresh = 200;
130
131    sf->use_lastframe_partitioning = LAST_FRAME_PARTITION_ALL;
132    sf->use_lp32x32fdct = 1;
133  }
134  if (speed >= 5) {
135    sf->partition_search_type = FIXED_PARTITION;
136    sf->optimize_coefficients = 0;
137    sf->search_method = HEX;
138    sf->disable_filter_search_var_thresh = 500;
139    for (i = 0; i < TX_SIZES; i++) {
140      sf->intra_y_mode_mask[i] = INTRA_DC_ONLY;
141      sf->intra_uv_mode_mask[i] = INTRA_DC_ONLY;
142    }
143    cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED;
144  }
145}
146
147static void set_rt_speed_feature(VP9_COMMON *cm,
148                                 SPEED_FEATURES *sf,
149                                 int speed) {
150  sf->static_segmentation = 0;
151  sf->adaptive_rd_thresh = 1;
152  sf->encode_breakout_thresh = 1;
153  sf->use_fast_coef_costing = 1;
154
155  if (speed == 1) {
156    sf->use_square_partition_only = !frame_is_intra_only(cm);
157    sf->less_rectangular_check = 1;
158    sf->tx_size_search_method =
159        frame_is_intra_only(cm) ? USE_FULL_RD : USE_LARGESTALL;
160
161    if (MIN(cm->width, cm->height) >= 720)
162      sf->disable_split_mask = cm->show_frame ?
163        DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT;
164    else
165      sf->disable_split_mask = DISABLE_COMPOUND_SPLIT;
166
167    sf->use_rd_breakout = 1;
168    sf->adaptive_motion_search = 1;
169    sf->adaptive_pred_interp_filter = 1;
170    sf->auto_mv_step_size = 1;
171    sf->adaptive_rd_thresh = 2;
172    sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V;
173    sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC_H_V;
174    sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
175    sf->encode_breakout_thresh = 8;
176  }
177  if (speed >= 2) {
178    sf->use_square_partition_only = !frame_is_intra_only(cm);
179    sf->less_rectangular_check = 1;
180    sf->tx_size_search_method =
181        frame_is_intra_only(cm) ? USE_FULL_RD : USE_LARGESTALL;
182
183    if (MIN(cm->width, cm->height) >= 720)
184      sf->disable_split_mask = cm->show_frame ?
185        DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT;
186    else
187      sf->disable_split_mask = LAST_AND_INTRA_SPLIT_ONLY;
188
189    sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH
190        | FLAG_SKIP_INTRA_BESTINTER | FLAG_SKIP_COMP_BESTINTRA
191        | FLAG_SKIP_INTRA_LOWVAR;
192
193    sf->use_rd_breakout = 1;
194    sf->adaptive_motion_search = 1;
195    sf->adaptive_pred_interp_filter = 2;
196    sf->auto_mv_step_size = 1;
197    sf->reference_masking = 1;
198
199    sf->disable_filter_search_var_thresh = 50;
200    sf->comp_inter_joint_search_thresh = BLOCK_SIZES;
201
202    sf->auto_min_max_partition_size = RELAXED_NEIGHBORING_MIN_MAX;
203    sf->use_lastframe_partitioning = LAST_FRAME_PARTITION_LOW_MOTION;
204    sf->adjust_partitioning_from_last_frame = 1;
205    sf->last_partitioning_redo_frequency = 3;
206
207    sf->adaptive_rd_thresh = 2;
208    sf->use_lp32x32fdct = 1;
209    sf->mode_skip_start = 11;
210    sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V;
211    sf->intra_y_mode_mask[TX_16X16] = INTRA_DC_H_V;
212    sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC_H_V;
213    sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
214    sf->encode_breakout_thresh = 200;
215  }
216  if (speed >= 3) {
217    sf->use_square_partition_only = 1;
218    sf->disable_filter_search_var_thresh = 100;
219    sf->use_lastframe_partitioning = LAST_FRAME_PARTITION_ALL;
220    sf->use_uv_intra_rd_estimate = 1;
221    sf->skip_encode_sb = 1;
222    sf->subpel_iters_per_step = 1;
223    sf->use_fast_coef_updates = 2;
224    sf->adaptive_rd_thresh = 4;
225    sf->mode_skip_start = 6;
226    sf->allow_skip_recode = 0;
227    sf->optimize_coefficients = 0;
228    sf->disable_split_mask = DISABLE_ALL_SPLIT;
229    sf->lpf_pick = LPF_PICK_FROM_Q;
230    sf->encode_breakout_thresh = 700;
231  }
232  if (speed >= 4) {
233    int i;
234    sf->last_partitioning_redo_frequency = 4;
235    sf->adaptive_rd_thresh = 5;
236    sf->use_fast_coef_costing = 0;
237    sf->auto_min_max_partition_size = STRICT_NEIGHBORING_MIN_MAX;
238    sf->adjust_partitioning_from_last_frame =
239        cm->last_frame_type != cm->frame_type || (0 ==
240        (cm->current_video_frame + 1) % sf->last_partitioning_redo_frequency);
241    sf->subpel_force_stop = 1;
242    for (i = 0; i < TX_SIZES; i++) {
243      sf->intra_y_mode_mask[i] = INTRA_DC_H_V;
244      sf->intra_uv_mode_mask[i] = INTRA_DC_ONLY;
245    }
246    sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_ONLY;
247    sf->frame_parameter_update = 0;
248    sf->encode_breakout_thresh = 1000;
249    sf->search_method = FAST_HEX;
250    sf->disable_inter_mode_mask[BLOCK_32X32] = 1 << INTER_OFFSET(ZEROMV);
251    sf->disable_inter_mode_mask[BLOCK_32X64] = ~(1 << INTER_OFFSET(NEARESTMV));
252    sf->disable_inter_mode_mask[BLOCK_64X32] = ~(1 << INTER_OFFSET(NEARESTMV));
253    sf->disable_inter_mode_mask[BLOCK_64X64] = ~(1 << INTER_OFFSET(NEARESTMV));
254    sf->max_intra_bsize = BLOCK_32X32;
255    sf->allow_skip_recode = 1;
256  }
257  if (speed >= 5) {
258    sf->max_partition_size = BLOCK_32X32;
259    sf->min_partition_size = BLOCK_8X8;
260    sf->partition_check =
261        (cm->current_video_frame % sf->last_partitioning_redo_frequency == 1);
262    sf->force_frame_boost = cm->frame_type == KEY_FRAME ||
263        (cm->current_video_frame %
264            (sf->last_partitioning_redo_frequency << 1) == 1);
265    sf->max_delta_qindex = (cm->frame_type == KEY_FRAME) ? 20 : 15;
266    sf->partition_search_type = REFERENCE_PARTITION;
267    sf->use_nonrd_pick_mode = 1;
268    sf->search_method = FAST_DIAMOND;
269    sf->allow_skip_recode = 0;
270  }
271  if (speed >= 6) {
272    sf->partition_search_type = VAR_BASED_FIXED_PARTITION;
273    sf->use_nonrd_pick_mode = 1;
274    sf->search_method = FAST_DIAMOND;
275  }
276  if (speed >= 7) {
277    int i;
278    for (i = 0; i < BLOCK_SIZES; ++i)
279      sf->disable_inter_mode_mask[i] = 14;    // only search NEARESTMV (0)
280  }
281}
282
283void vp9_set_speed_features(VP9_COMP *cpi) {
284  SPEED_FEATURES *const sf = &cpi->sf;
285  VP9_COMMON *const cm = &cpi->common;
286  const int speed = cpi->speed < 0 ? -cpi->speed : cpi->speed;
287  int i;
288
289  // best quality defaults
290  sf->frame_parameter_update = 1;
291  sf->search_method = NSTEP;
292  sf->recode_loop = ALLOW_RECODE;
293  sf->subpel_search_method = SUBPEL_TREE;
294  sf->subpel_iters_per_step = 2;
295  sf->subpel_force_stop = 0;
296  sf->optimize_coefficients = !cpi->oxcf.lossless;
297  sf->reduce_first_step_size = 0;
298  sf->auto_mv_step_size = 0;
299  sf->max_step_search_steps = MAX_MVSEARCH_STEPS;
300  sf->comp_inter_joint_search_thresh = BLOCK_4X4;
301  sf->adaptive_rd_thresh = 0;
302  sf->use_lastframe_partitioning = LAST_FRAME_PARTITION_OFF;
303  sf->tx_size_search_method = USE_FULL_RD;
304  sf->use_lp32x32fdct = 0;
305  sf->adaptive_motion_search = 0;
306  sf->adaptive_pred_interp_filter = 0;
307  sf->reference_masking = 0;
308  sf->partition_search_type = SEARCH_PARTITION;
309  sf->less_rectangular_check = 0;
310  sf->use_square_partition_only = 0;
311  sf->auto_min_max_partition_size = NOT_IN_USE;
312  sf->max_partition_size = BLOCK_64X64;
313  sf->min_partition_size = BLOCK_4X4;
314  sf->adjust_partitioning_from_last_frame = 0;
315  sf->last_partitioning_redo_frequency = 4;
316  sf->disable_split_mask = 0;
317  sf->mode_search_skip_flags = 0;
318  sf->force_frame_boost = 0;
319  sf->max_delta_qindex = 0;
320  sf->disable_split_var_thresh = 0;
321  sf->disable_filter_search_var_thresh = 0;
322  for (i = 0; i < TX_SIZES; i++) {
323    sf->intra_y_mode_mask[i] = ALL_INTRA_MODES;
324    sf->intra_uv_mode_mask[i] = ALL_INTRA_MODES;
325  }
326  sf->use_rd_breakout = 0;
327  sf->skip_encode_sb = 0;
328  sf->use_uv_intra_rd_estimate = 0;
329  sf->allow_skip_recode = 0;
330  sf->lpf_pick = LPF_PICK_FROM_FULL_IMAGE;
331  sf->use_fast_coef_updates = 0;
332  sf->use_fast_coef_costing = 0;
333  sf->mode_skip_start = MAX_MODES;  // Mode index at which mode skip mask set
334  sf->use_nonrd_pick_mode = 0;
335  sf->encode_breakout_thresh = 0;
336  for (i = 0; i < BLOCK_SIZES; ++i)
337    sf->disable_inter_mode_mask[i] = 0;
338  sf->max_intra_bsize = BLOCK_64X64;
339  // This setting only takes effect when partition_search_type is set
340  // to FIXED_PARTITION.
341  sf->always_this_block_size = BLOCK_16X16;
342
343  // Recode loop tolerence %.
344  sf->recode_tolerance = 25;
345
346  switch (cpi->oxcf.mode) {
347    case MODE_BESTQUALITY:
348    case MODE_SECONDPASS_BEST:  // This is the best quality mode.
349      cpi->diamond_search_sad = vp9_full_range_search;
350      break;
351    case MODE_FIRSTPASS:
352    case MODE_GOODQUALITY:
353    case MODE_SECONDPASS:
354      set_good_speed_feature(cpi, cm, sf, speed);
355      break;
356    case MODE_REALTIME:
357      set_rt_speed_feature(cm, sf, speed);
358      break;
359  }
360
361  // Slow quant, dct and trellis not worthwhile for first pass
362  // so make sure they are always turned off.
363  if (cpi->pass == 1) {
364    sf->optimize_coefficients = 0;
365  }
366
367  // No recode for 1 pass.
368  if (cpi->pass == 0) {
369    sf->recode_loop = DISALLOW_RECODE;
370    sf->optimize_coefficients = 0;
371  }
372
373  if (cpi->sf.subpel_search_method == SUBPEL_TREE) {
374    cpi->find_fractional_mv_step = vp9_find_best_sub_pixel_tree;
375    cpi->find_fractional_mv_step_comp = vp9_find_best_sub_pixel_comp_tree;
376  }
377
378  cpi->mb.optimize = cpi->sf.optimize_coefficients == 1 && cpi->pass != 1;
379
380  if (cpi->encode_breakout && cpi->oxcf.mode == MODE_REALTIME &&
381      sf->encode_breakout_thresh > cpi->encode_breakout)
382    cpi->encode_breakout = sf->encode_breakout_thresh;
383
384  if (sf->disable_split_mask == DISABLE_ALL_SPLIT)
385    sf->adaptive_pred_interp_filter = 0;
386
387  if (!cpi->oxcf.frame_periodic_boost) {
388    sf->max_delta_qindex = 0;
389  }
390}
391