1*fb1b10abSAndroid Build Coastguard Worker /*
2*fb1b10abSAndroid Build Coastguard Worker * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3*fb1b10abSAndroid Build Coastguard Worker *
4*fb1b10abSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*fb1b10abSAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*fb1b10abSAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*fb1b10abSAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*fb1b10abSAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*fb1b10abSAndroid Build Coastguard Worker */
10*fb1b10abSAndroid Build Coastguard Worker
11*fb1b10abSAndroid Build Coastguard Worker #include <assert.h>
12*fb1b10abSAndroid Build Coastguard Worker #include <math.h>
13*fb1b10abSAndroid Build Coastguard Worker #include <stdio.h>
14*fb1b10abSAndroid Build Coastguard Worker
15*fb1b10abSAndroid Build Coastguard Worker #include "./vp9_rtcd.h"
16*fb1b10abSAndroid Build Coastguard Worker
17*fb1b10abSAndroid Build Coastguard Worker #include "vpx_dsp/vpx_dsp_common.h"
18*fb1b10abSAndroid Build Coastguard Worker #include "vpx_mem/vpx_mem.h"
19*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/bitops.h"
20*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/mem.h"
21*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/system_state.h"
22*fb1b10abSAndroid Build Coastguard Worker
23*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_common.h"
24*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_entropy.h"
25*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_entropymode.h"
26*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_mvref_common.h"
27*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_pred_common.h"
28*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_quant_common.h"
29*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_reconinter.h"
30*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_reconintra.h"
31*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_seg_common.h"
32*fb1b10abSAndroid Build Coastguard Worker
33*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_cost.h"
34*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_encodemb.h"
35*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_encodemv.h"
36*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_encoder.h"
37*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_mcomp.h"
38*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_quantize.h"
39*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_ratectrl.h"
40*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_rd.h"
41*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_tokenize.h"
42*fb1b10abSAndroid Build Coastguard Worker
43*fb1b10abSAndroid Build Coastguard Worker #define RD_THRESH_POW 1.25
44*fb1b10abSAndroid Build Coastguard Worker
45*fb1b10abSAndroid Build Coastguard Worker // Factor to weigh the rate for switchable interp filters.
46*fb1b10abSAndroid Build Coastguard Worker #define SWITCHABLE_INTERP_RATE_FACTOR 1
47*fb1b10abSAndroid Build Coastguard Worker
vp9_rd_cost_reset(RD_COST * rd_cost)48*fb1b10abSAndroid Build Coastguard Worker void vp9_rd_cost_reset(RD_COST *rd_cost) {
49*fb1b10abSAndroid Build Coastguard Worker rd_cost->rate = INT_MAX;
50*fb1b10abSAndroid Build Coastguard Worker rd_cost->dist = INT64_MAX;
51*fb1b10abSAndroid Build Coastguard Worker rd_cost->rdcost = INT64_MAX;
52*fb1b10abSAndroid Build Coastguard Worker }
53*fb1b10abSAndroid Build Coastguard Worker
vp9_rd_cost_init(RD_COST * rd_cost)54*fb1b10abSAndroid Build Coastguard Worker void vp9_rd_cost_init(RD_COST *rd_cost) {
55*fb1b10abSAndroid Build Coastguard Worker rd_cost->rate = 0;
56*fb1b10abSAndroid Build Coastguard Worker rd_cost->dist = 0;
57*fb1b10abSAndroid Build Coastguard Worker rd_cost->rdcost = 0;
58*fb1b10abSAndroid Build Coastguard Worker }
59*fb1b10abSAndroid Build Coastguard Worker
vp9_calculate_rd_cost(int mult,int div,int rate,int64_t dist)60*fb1b10abSAndroid Build Coastguard Worker int64_t vp9_calculate_rd_cost(int mult, int div, int rate, int64_t dist) {
61*fb1b10abSAndroid Build Coastguard Worker assert(mult >= 0);
62*fb1b10abSAndroid Build Coastguard Worker assert(div > 0);
63*fb1b10abSAndroid Build Coastguard Worker if (rate >= 0 && dist >= 0) {
64*fb1b10abSAndroid Build Coastguard Worker return RDCOST(mult, div, rate, dist);
65*fb1b10abSAndroid Build Coastguard Worker }
66*fb1b10abSAndroid Build Coastguard Worker if (rate >= 0 && dist < 0) {
67*fb1b10abSAndroid Build Coastguard Worker return RDCOST_NEG_D(mult, div, rate, -dist);
68*fb1b10abSAndroid Build Coastguard Worker }
69*fb1b10abSAndroid Build Coastguard Worker if (rate < 0 && dist >= 0) {
70*fb1b10abSAndroid Build Coastguard Worker return RDCOST_NEG_R(mult, div, -rate, dist);
71*fb1b10abSAndroid Build Coastguard Worker }
72*fb1b10abSAndroid Build Coastguard Worker return -RDCOST(mult, div, -rate, -dist);
73*fb1b10abSAndroid Build Coastguard Worker }
74*fb1b10abSAndroid Build Coastguard Worker
vp9_rd_cost_update(int mult,int div,RD_COST * rd_cost)75*fb1b10abSAndroid Build Coastguard Worker void vp9_rd_cost_update(int mult, int div, RD_COST *rd_cost) {
76*fb1b10abSAndroid Build Coastguard Worker if (rd_cost->rate < INT_MAX && rd_cost->dist < INT64_MAX) {
77*fb1b10abSAndroid Build Coastguard Worker rd_cost->rdcost =
78*fb1b10abSAndroid Build Coastguard Worker vp9_calculate_rd_cost(mult, div, rd_cost->rate, rd_cost->dist);
79*fb1b10abSAndroid Build Coastguard Worker } else {
80*fb1b10abSAndroid Build Coastguard Worker vp9_rd_cost_reset(rd_cost);
81*fb1b10abSAndroid Build Coastguard Worker }
82*fb1b10abSAndroid Build Coastguard Worker }
83*fb1b10abSAndroid Build Coastguard Worker
84*fb1b10abSAndroid Build Coastguard Worker // The baseline rd thresholds for breaking out of the rd loop for
85*fb1b10abSAndroid Build Coastguard Worker // certain modes are assumed to be based on 8x8 blocks.
86*fb1b10abSAndroid Build Coastguard Worker // This table is used to correct for block size.
87*fb1b10abSAndroid Build Coastguard Worker // The factors here are << 2 (2 = x0.5, 32 = x8 etc).
88*fb1b10abSAndroid Build Coastguard Worker static const uint8_t rd_thresh_block_size_factor[BLOCK_SIZES] = {
89*fb1b10abSAndroid Build Coastguard Worker 2, 3, 3, 4, 6, 6, 8, 12, 12, 16, 24, 24, 32
90*fb1b10abSAndroid Build Coastguard Worker };
91*fb1b10abSAndroid Build Coastguard Worker
fill_mode_costs(VP9_COMP * cpi)92*fb1b10abSAndroid Build Coastguard Worker static void fill_mode_costs(VP9_COMP *cpi) {
93*fb1b10abSAndroid Build Coastguard Worker const FRAME_CONTEXT *const fc = cpi->common.fc;
94*fb1b10abSAndroid Build Coastguard Worker int i, j;
95*fb1b10abSAndroid Build Coastguard Worker
96*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < INTRA_MODES; ++i) {
97*fb1b10abSAndroid Build Coastguard Worker for (j = 0; j < INTRA_MODES; ++j) {
98*fb1b10abSAndroid Build Coastguard Worker vp9_cost_tokens(cpi->y_mode_costs[i][j], vp9_kf_y_mode_prob[i][j],
99*fb1b10abSAndroid Build Coastguard Worker vp9_intra_mode_tree);
100*fb1b10abSAndroid Build Coastguard Worker }
101*fb1b10abSAndroid Build Coastguard Worker }
102*fb1b10abSAndroid Build Coastguard Worker
103*fb1b10abSAndroid Build Coastguard Worker vp9_cost_tokens(cpi->mbmode_cost, fc->y_mode_prob[1], vp9_intra_mode_tree);
104*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < INTRA_MODES; ++i) {
105*fb1b10abSAndroid Build Coastguard Worker vp9_cost_tokens(cpi->intra_uv_mode_cost[KEY_FRAME][i],
106*fb1b10abSAndroid Build Coastguard Worker vp9_kf_uv_mode_prob[i], vp9_intra_mode_tree);
107*fb1b10abSAndroid Build Coastguard Worker vp9_cost_tokens(cpi->intra_uv_mode_cost[INTER_FRAME][i],
108*fb1b10abSAndroid Build Coastguard Worker fc->uv_mode_prob[i], vp9_intra_mode_tree);
109*fb1b10abSAndroid Build Coastguard Worker }
110*fb1b10abSAndroid Build Coastguard Worker
111*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) {
112*fb1b10abSAndroid Build Coastguard Worker vp9_cost_tokens(cpi->switchable_interp_costs[i],
113*fb1b10abSAndroid Build Coastguard Worker fc->switchable_interp_prob[i], vp9_switchable_interp_tree);
114*fb1b10abSAndroid Build Coastguard Worker }
115*fb1b10abSAndroid Build Coastguard Worker
116*fb1b10abSAndroid Build Coastguard Worker for (i = TX_8X8; i < TX_SIZES; ++i) {
117*fb1b10abSAndroid Build Coastguard Worker for (j = 0; j < TX_SIZE_CONTEXTS; ++j) {
118*fb1b10abSAndroid Build Coastguard Worker const vpx_prob *tx_probs = get_tx_probs(i, j, &fc->tx_probs);
119*fb1b10abSAndroid Build Coastguard Worker int k;
120*fb1b10abSAndroid Build Coastguard Worker for (k = 0; k <= i; ++k) {
121*fb1b10abSAndroid Build Coastguard Worker int cost = 0;
122*fb1b10abSAndroid Build Coastguard Worker int m;
123*fb1b10abSAndroid Build Coastguard Worker for (m = 0; m <= k - (k == i); ++m) {
124*fb1b10abSAndroid Build Coastguard Worker if (m == k)
125*fb1b10abSAndroid Build Coastguard Worker cost += vp9_cost_zero(tx_probs[m]);
126*fb1b10abSAndroid Build Coastguard Worker else
127*fb1b10abSAndroid Build Coastguard Worker cost += vp9_cost_one(tx_probs[m]);
128*fb1b10abSAndroid Build Coastguard Worker }
129*fb1b10abSAndroid Build Coastguard Worker cpi->tx_size_cost[i - 1][j][k] = cost;
130*fb1b10abSAndroid Build Coastguard Worker }
131*fb1b10abSAndroid Build Coastguard Worker }
132*fb1b10abSAndroid Build Coastguard Worker }
133*fb1b10abSAndroid Build Coastguard Worker }
134*fb1b10abSAndroid Build Coastguard Worker
fill_token_costs(vp9_coeff_cost * c,vp9_coeff_probs_model (* p)[PLANE_TYPES])135*fb1b10abSAndroid Build Coastguard Worker static void fill_token_costs(vp9_coeff_cost *c,
136*fb1b10abSAndroid Build Coastguard Worker vp9_coeff_probs_model (*p)[PLANE_TYPES]) {
137*fb1b10abSAndroid Build Coastguard Worker int i, j, k, l;
138*fb1b10abSAndroid Build Coastguard Worker TX_SIZE t;
139*fb1b10abSAndroid Build Coastguard Worker for (t = TX_4X4; t <= TX_32X32; ++t)
140*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < PLANE_TYPES; ++i)
141*fb1b10abSAndroid Build Coastguard Worker for (j = 0; j < REF_TYPES; ++j)
142*fb1b10abSAndroid Build Coastguard Worker for (k = 0; k < COEF_BANDS; ++k)
143*fb1b10abSAndroid Build Coastguard Worker for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) {
144*fb1b10abSAndroid Build Coastguard Worker vpx_prob probs[ENTROPY_NODES];
145*fb1b10abSAndroid Build Coastguard Worker vp9_model_to_full_probs(p[t][i][j][k][l], probs);
146*fb1b10abSAndroid Build Coastguard Worker vp9_cost_tokens((int *)c[t][i][j][k][0][l], probs, vp9_coef_tree);
147*fb1b10abSAndroid Build Coastguard Worker vp9_cost_tokens_skip((int *)c[t][i][j][k][1][l], probs,
148*fb1b10abSAndroid Build Coastguard Worker vp9_coef_tree);
149*fb1b10abSAndroid Build Coastguard Worker assert(c[t][i][j][k][0][l][EOB_TOKEN] ==
150*fb1b10abSAndroid Build Coastguard Worker c[t][i][j][k][1][l][EOB_TOKEN]);
151*fb1b10abSAndroid Build Coastguard Worker }
152*fb1b10abSAndroid Build Coastguard Worker }
153*fb1b10abSAndroid Build Coastguard Worker
154*fb1b10abSAndroid Build Coastguard Worker // Values are now correlated to quantizer.
155*fb1b10abSAndroid Build Coastguard Worker static int sad_per_bit16lut_8[QINDEX_RANGE];
156*fb1b10abSAndroid Build Coastguard Worker static int sad_per_bit4lut_8[QINDEX_RANGE];
157*fb1b10abSAndroid Build Coastguard Worker
158*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
159*fb1b10abSAndroid Build Coastguard Worker static int sad_per_bit16lut_10[QINDEX_RANGE];
160*fb1b10abSAndroid Build Coastguard Worker static int sad_per_bit4lut_10[QINDEX_RANGE];
161*fb1b10abSAndroid Build Coastguard Worker static int sad_per_bit16lut_12[QINDEX_RANGE];
162*fb1b10abSAndroid Build Coastguard Worker static int sad_per_bit4lut_12[QINDEX_RANGE];
163*fb1b10abSAndroid Build Coastguard Worker #endif
164*fb1b10abSAndroid Build Coastguard Worker
init_me_luts_bd(int * bit16lut,int * bit4lut,int range,vpx_bit_depth_t bit_depth)165*fb1b10abSAndroid Build Coastguard Worker static void init_me_luts_bd(int *bit16lut, int *bit4lut, int range,
166*fb1b10abSAndroid Build Coastguard Worker vpx_bit_depth_t bit_depth) {
167*fb1b10abSAndroid Build Coastguard Worker int i;
168*fb1b10abSAndroid Build Coastguard Worker // Initialize the sad lut tables using a formulaic calculation for now.
169*fb1b10abSAndroid Build Coastguard Worker // This is to make it easier to resolve the impact of experimental changes
170*fb1b10abSAndroid Build Coastguard Worker // to the quantizer tables.
171*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < range; i++) {
172*fb1b10abSAndroid Build Coastguard Worker const double q = vp9_convert_qindex_to_q(i, bit_depth);
173*fb1b10abSAndroid Build Coastguard Worker bit16lut[i] = (int)(0.0418 * q + 2.4107);
174*fb1b10abSAndroid Build Coastguard Worker bit4lut[i] = (int)(0.063 * q + 2.742);
175*fb1b10abSAndroid Build Coastguard Worker }
176*fb1b10abSAndroid Build Coastguard Worker }
177*fb1b10abSAndroid Build Coastguard Worker
vp9_init_me_luts(void)178*fb1b10abSAndroid Build Coastguard Worker void vp9_init_me_luts(void) {
179*fb1b10abSAndroid Build Coastguard Worker init_me_luts_bd(sad_per_bit16lut_8, sad_per_bit4lut_8, QINDEX_RANGE,
180*fb1b10abSAndroid Build Coastguard Worker VPX_BITS_8);
181*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
182*fb1b10abSAndroid Build Coastguard Worker init_me_luts_bd(sad_per_bit16lut_10, sad_per_bit4lut_10, QINDEX_RANGE,
183*fb1b10abSAndroid Build Coastguard Worker VPX_BITS_10);
184*fb1b10abSAndroid Build Coastguard Worker init_me_luts_bd(sad_per_bit16lut_12, sad_per_bit4lut_12, QINDEX_RANGE,
185*fb1b10abSAndroid Build Coastguard Worker VPX_BITS_12);
186*fb1b10abSAndroid Build Coastguard Worker #endif
187*fb1b10abSAndroid Build Coastguard Worker }
188*fb1b10abSAndroid Build Coastguard Worker
189*fb1b10abSAndroid Build Coastguard Worker static const int rd_boost_factor[16] = { 64, 32, 32, 32, 24, 16, 12, 12,
190*fb1b10abSAndroid Build Coastguard Worker 8, 8, 4, 4, 2, 2, 1, 0 };
191*fb1b10abSAndroid Build Coastguard Worker
192*fb1b10abSAndroid Build Coastguard Worker // Note that the element below for frame type "USE_BUF_FRAME", which indicates
193*fb1b10abSAndroid Build Coastguard Worker // that the show frame flag is set, should not be used as no real frame
194*fb1b10abSAndroid Build Coastguard Worker // is encoded so we should not reach here. However, a dummy value
195*fb1b10abSAndroid Build Coastguard Worker // is inserted here to make sure the data structure has the right number
196*fb1b10abSAndroid Build Coastguard Worker // of values assigned.
197*fb1b10abSAndroid Build Coastguard Worker static const int rd_frame_type_factor[FRAME_UPDATE_TYPES] = { 128, 144, 128,
198*fb1b10abSAndroid Build Coastguard Worker 128, 144, 144 };
199*fb1b10abSAndroid Build Coastguard Worker
200*fb1b10abSAndroid Build Coastguard Worker // Configure Vizier RD parameters.
201*fb1b10abSAndroid Build Coastguard Worker // Later this function will use passed in command line values.
vp9_init_rd_parameters(VP9_COMP * cpi)202*fb1b10abSAndroid Build Coastguard Worker void vp9_init_rd_parameters(VP9_COMP *cpi) {
203*fb1b10abSAndroid Build Coastguard Worker RD_CONTROL *const rdc = &cpi->rd_ctrl;
204*fb1b10abSAndroid Build Coastguard Worker
205*fb1b10abSAndroid Build Coastguard Worker // When |use_vizier_rc_params| is 1, we expect the rd parameters have been
206*fb1b10abSAndroid Build Coastguard Worker // initialized by the pass in values.
207*fb1b10abSAndroid Build Coastguard Worker // Be careful that parameters below are only initialized to 1, if we do not
208*fb1b10abSAndroid Build Coastguard Worker // pass values to them. It is desired to take care of each parameter when
209*fb1b10abSAndroid Build Coastguard Worker // using |use_vizier_rc_params|.
210*fb1b10abSAndroid Build Coastguard Worker if (cpi->twopass.use_vizier_rc_params) return;
211*fb1b10abSAndroid Build Coastguard Worker
212*fb1b10abSAndroid Build Coastguard Worker // Make sure this function is floating point safe.
213*fb1b10abSAndroid Build Coastguard Worker vpx_clear_system_state();
214*fb1b10abSAndroid Build Coastguard Worker
215*fb1b10abSAndroid Build Coastguard Worker rdc->rd_mult_inter_qp_fac = 1.0;
216*fb1b10abSAndroid Build Coastguard Worker rdc->rd_mult_arf_qp_fac = 1.0;
217*fb1b10abSAndroid Build Coastguard Worker rdc->rd_mult_key_qp_fac = 1.0;
218*fb1b10abSAndroid Build Coastguard Worker }
219*fb1b10abSAndroid Build Coastguard Worker
220*fb1b10abSAndroid Build Coastguard Worker // Returns the default rd multiplier for inter frames for a given qindex.
221*fb1b10abSAndroid Build Coastguard Worker // The function here is a first pass estimate based on data from
222*fb1b10abSAndroid Build Coastguard Worker // a previous Vizer run
def_inter_rd_multiplier(int qindex)223*fb1b10abSAndroid Build Coastguard Worker static double def_inter_rd_multiplier(int qindex) {
224*fb1b10abSAndroid Build Coastguard Worker return 4.15 + (0.001 * (double)qindex);
225*fb1b10abSAndroid Build Coastguard Worker }
226*fb1b10abSAndroid Build Coastguard Worker
227*fb1b10abSAndroid Build Coastguard Worker // Returns the default rd multiplier for ARF/Golden Frames for a given qindex.
228*fb1b10abSAndroid Build Coastguard Worker // The function here is a first pass estimate based on data from
229*fb1b10abSAndroid Build Coastguard Worker // a previous Vizer run
def_arf_rd_multiplier(int qindex)230*fb1b10abSAndroid Build Coastguard Worker static double def_arf_rd_multiplier(int qindex) {
231*fb1b10abSAndroid Build Coastguard Worker return 4.25 + (0.001 * (double)qindex);
232*fb1b10abSAndroid Build Coastguard Worker }
233*fb1b10abSAndroid Build Coastguard Worker
234*fb1b10abSAndroid Build Coastguard Worker // Returns the default rd multiplier for key frames for a given qindex.
235*fb1b10abSAndroid Build Coastguard Worker // The function here is a first pass estimate based on data from
236*fb1b10abSAndroid Build Coastguard Worker // a previous Vizer run
def_kf_rd_multiplier(int qindex)237*fb1b10abSAndroid Build Coastguard Worker static double def_kf_rd_multiplier(int qindex) {
238*fb1b10abSAndroid Build Coastguard Worker return 4.35 + (0.001 * (double)qindex);
239*fb1b10abSAndroid Build Coastguard Worker }
240*fb1b10abSAndroid Build Coastguard Worker
vp9_compute_rd_mult_based_on_qindex(const VP9_COMP * cpi,int qindex)241*fb1b10abSAndroid Build Coastguard Worker int vp9_compute_rd_mult_based_on_qindex(const VP9_COMP *cpi, int qindex) {
242*fb1b10abSAndroid Build Coastguard Worker const RD_CONTROL *rdc = &cpi->rd_ctrl;
243*fb1b10abSAndroid Build Coastguard Worker const int q = vp9_dc_quant(qindex, 0, cpi->common.bit_depth);
244*fb1b10abSAndroid Build Coastguard Worker // largest dc_quant is 21387, therefore rdmult should fit in int32_t
245*fb1b10abSAndroid Build Coastguard Worker int rdmult = q * q;
246*fb1b10abSAndroid Build Coastguard Worker
247*fb1b10abSAndroid Build Coastguard Worker if (cpi->ext_ratectrl.ready &&
248*fb1b10abSAndroid Build Coastguard Worker (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_RDMULT) != 0 &&
249*fb1b10abSAndroid Build Coastguard Worker cpi->ext_ratectrl.ext_rdmult != VPX_DEFAULT_RDMULT) {
250*fb1b10abSAndroid Build Coastguard Worker return cpi->ext_ratectrl.ext_rdmult;
251*fb1b10abSAndroid Build Coastguard Worker }
252*fb1b10abSAndroid Build Coastguard Worker
253*fb1b10abSAndroid Build Coastguard Worker // Make sure this function is floating point safe.
254*fb1b10abSAndroid Build Coastguard Worker vpx_clear_system_state();
255*fb1b10abSAndroid Build Coastguard Worker
256*fb1b10abSAndroid Build Coastguard Worker if (cpi->common.frame_type == KEY_FRAME) {
257*fb1b10abSAndroid Build Coastguard Worker double def_rd_q_mult = def_kf_rd_multiplier(qindex);
258*fb1b10abSAndroid Build Coastguard Worker rdmult = (int)((double)rdmult * def_rd_q_mult * rdc->rd_mult_key_qp_fac);
259*fb1b10abSAndroid Build Coastguard Worker } else if (!cpi->rc.is_src_frame_alt_ref &&
260*fb1b10abSAndroid Build Coastguard Worker (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
261*fb1b10abSAndroid Build Coastguard Worker double def_rd_q_mult = def_arf_rd_multiplier(qindex);
262*fb1b10abSAndroid Build Coastguard Worker rdmult = (int)((double)rdmult * def_rd_q_mult * rdc->rd_mult_arf_qp_fac);
263*fb1b10abSAndroid Build Coastguard Worker } else {
264*fb1b10abSAndroid Build Coastguard Worker double def_rd_q_mult = def_inter_rd_multiplier(qindex);
265*fb1b10abSAndroid Build Coastguard Worker rdmult = (int)((double)rdmult * def_rd_q_mult * rdc->rd_mult_inter_qp_fac);
266*fb1b10abSAndroid Build Coastguard Worker }
267*fb1b10abSAndroid Build Coastguard Worker
268*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
269*fb1b10abSAndroid Build Coastguard Worker switch (cpi->common.bit_depth) {
270*fb1b10abSAndroid Build Coastguard Worker case VPX_BITS_10: rdmult = ROUND_POWER_OF_TWO(rdmult, 4); break;
271*fb1b10abSAndroid Build Coastguard Worker case VPX_BITS_12: rdmult = ROUND_POWER_OF_TWO(rdmult, 8); break;
272*fb1b10abSAndroid Build Coastguard Worker default: break;
273*fb1b10abSAndroid Build Coastguard Worker }
274*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_VP9_HIGHBITDEPTH
275*fb1b10abSAndroid Build Coastguard Worker return rdmult > 0 ? rdmult : 1;
276*fb1b10abSAndroid Build Coastguard Worker }
277*fb1b10abSAndroid Build Coastguard Worker
modulate_rdmult(const VP9_COMP * cpi,int rdmult)278*fb1b10abSAndroid Build Coastguard Worker static int modulate_rdmult(const VP9_COMP *cpi, int rdmult) {
279*fb1b10abSAndroid Build Coastguard Worker int64_t rdmult_64 = rdmult;
280*fb1b10abSAndroid Build Coastguard Worker if (cpi->oxcf.pass == 2 && (cpi->common.frame_type != KEY_FRAME)) {
281*fb1b10abSAndroid Build Coastguard Worker const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
282*fb1b10abSAndroid Build Coastguard Worker const FRAME_UPDATE_TYPE frame_type = gf_group->update_type[gf_group->index];
283*fb1b10abSAndroid Build Coastguard Worker const int gfu_boost = cpi->multi_layer_arf
284*fb1b10abSAndroid Build Coastguard Worker ? gf_group->gfu_boost[gf_group->index]
285*fb1b10abSAndroid Build Coastguard Worker : cpi->rc.gfu_boost;
286*fb1b10abSAndroid Build Coastguard Worker const int boost_index = VPXMIN(15, (gfu_boost / 100));
287*fb1b10abSAndroid Build Coastguard Worker
288*fb1b10abSAndroid Build Coastguard Worker rdmult_64 = (rdmult_64 * rd_frame_type_factor[frame_type]) >> 7;
289*fb1b10abSAndroid Build Coastguard Worker rdmult_64 += ((rdmult_64 * rd_boost_factor[boost_index]) >> 7);
290*fb1b10abSAndroid Build Coastguard Worker }
291*fb1b10abSAndroid Build Coastguard Worker return (int)rdmult_64;
292*fb1b10abSAndroid Build Coastguard Worker }
293*fb1b10abSAndroid Build Coastguard Worker
vp9_compute_rd_mult(const VP9_COMP * cpi,int qindex)294*fb1b10abSAndroid Build Coastguard Worker int vp9_compute_rd_mult(const VP9_COMP *cpi, int qindex) {
295*fb1b10abSAndroid Build Coastguard Worker int rdmult = vp9_compute_rd_mult_based_on_qindex(cpi, qindex);
296*fb1b10abSAndroid Build Coastguard Worker if (cpi->ext_ratectrl.ready &&
297*fb1b10abSAndroid Build Coastguard Worker (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_RDMULT) != 0 &&
298*fb1b10abSAndroid Build Coastguard Worker cpi->ext_ratectrl.ext_rdmult != VPX_DEFAULT_RDMULT) {
299*fb1b10abSAndroid Build Coastguard Worker return cpi->ext_ratectrl.ext_rdmult;
300*fb1b10abSAndroid Build Coastguard Worker }
301*fb1b10abSAndroid Build Coastguard Worker return modulate_rdmult(cpi, rdmult);
302*fb1b10abSAndroid Build Coastguard Worker }
303*fb1b10abSAndroid Build Coastguard Worker
vp9_get_adaptive_rdmult(const VP9_COMP * cpi,double beta)304*fb1b10abSAndroid Build Coastguard Worker int vp9_get_adaptive_rdmult(const VP9_COMP *cpi, double beta) {
305*fb1b10abSAndroid Build Coastguard Worker int rdmult =
306*fb1b10abSAndroid Build Coastguard Worker vp9_compute_rd_mult_based_on_qindex(cpi, cpi->common.base_qindex);
307*fb1b10abSAndroid Build Coastguard Worker rdmult = (int)((double)rdmult / beta);
308*fb1b10abSAndroid Build Coastguard Worker rdmult = rdmult > 0 ? rdmult : 1;
309*fb1b10abSAndroid Build Coastguard Worker return modulate_rdmult(cpi, rdmult);
310*fb1b10abSAndroid Build Coastguard Worker }
311*fb1b10abSAndroid Build Coastguard Worker
compute_rd_thresh_factor(int qindex,vpx_bit_depth_t bit_depth)312*fb1b10abSAndroid Build Coastguard Worker static int compute_rd_thresh_factor(int qindex, vpx_bit_depth_t bit_depth) {
313*fb1b10abSAndroid Build Coastguard Worker double q;
314*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
315*fb1b10abSAndroid Build Coastguard Worker switch (bit_depth) {
316*fb1b10abSAndroid Build Coastguard Worker case VPX_BITS_8: q = vp9_dc_quant(qindex, 0, VPX_BITS_8) / 4.0; break;
317*fb1b10abSAndroid Build Coastguard Worker case VPX_BITS_10: q = vp9_dc_quant(qindex, 0, VPX_BITS_10) / 16.0; break;
318*fb1b10abSAndroid Build Coastguard Worker default:
319*fb1b10abSAndroid Build Coastguard Worker assert(bit_depth == VPX_BITS_12);
320*fb1b10abSAndroid Build Coastguard Worker q = vp9_dc_quant(qindex, 0, VPX_BITS_12) / 64.0;
321*fb1b10abSAndroid Build Coastguard Worker break;
322*fb1b10abSAndroid Build Coastguard Worker }
323*fb1b10abSAndroid Build Coastguard Worker #else
324*fb1b10abSAndroid Build Coastguard Worker (void)bit_depth;
325*fb1b10abSAndroid Build Coastguard Worker q = vp9_dc_quant(qindex, 0, VPX_BITS_8) / 4.0;
326*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_VP9_HIGHBITDEPTH
327*fb1b10abSAndroid Build Coastguard Worker // TODO(debargha): Adjust the function below.
328*fb1b10abSAndroid Build Coastguard Worker return VPXMAX((int)(pow(q, RD_THRESH_POW) * 5.12), 8);
329*fb1b10abSAndroid Build Coastguard Worker }
330*fb1b10abSAndroid Build Coastguard Worker
vp9_initialize_me_consts(VP9_COMP * cpi,MACROBLOCK * x,int qindex)331*fb1b10abSAndroid Build Coastguard Worker void vp9_initialize_me_consts(VP9_COMP *cpi, MACROBLOCK *x, int qindex) {
332*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
333*fb1b10abSAndroid Build Coastguard Worker switch (cpi->common.bit_depth) {
334*fb1b10abSAndroid Build Coastguard Worker case VPX_BITS_8:
335*fb1b10abSAndroid Build Coastguard Worker x->sadperbit16 = sad_per_bit16lut_8[qindex];
336*fb1b10abSAndroid Build Coastguard Worker x->sadperbit4 = sad_per_bit4lut_8[qindex];
337*fb1b10abSAndroid Build Coastguard Worker break;
338*fb1b10abSAndroid Build Coastguard Worker case VPX_BITS_10:
339*fb1b10abSAndroid Build Coastguard Worker x->sadperbit16 = sad_per_bit16lut_10[qindex];
340*fb1b10abSAndroid Build Coastguard Worker x->sadperbit4 = sad_per_bit4lut_10[qindex];
341*fb1b10abSAndroid Build Coastguard Worker break;
342*fb1b10abSAndroid Build Coastguard Worker default:
343*fb1b10abSAndroid Build Coastguard Worker assert(cpi->common.bit_depth == VPX_BITS_12);
344*fb1b10abSAndroid Build Coastguard Worker x->sadperbit16 = sad_per_bit16lut_12[qindex];
345*fb1b10abSAndroid Build Coastguard Worker x->sadperbit4 = sad_per_bit4lut_12[qindex];
346*fb1b10abSAndroid Build Coastguard Worker break;
347*fb1b10abSAndroid Build Coastguard Worker }
348*fb1b10abSAndroid Build Coastguard Worker #else
349*fb1b10abSAndroid Build Coastguard Worker (void)cpi;
350*fb1b10abSAndroid Build Coastguard Worker x->sadperbit16 = sad_per_bit16lut_8[qindex];
351*fb1b10abSAndroid Build Coastguard Worker x->sadperbit4 = sad_per_bit4lut_8[qindex];
352*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_VP9_HIGHBITDEPTH
353*fb1b10abSAndroid Build Coastguard Worker }
354*fb1b10abSAndroid Build Coastguard Worker
set_block_thresholds(const VP9_COMMON * cm,RD_OPT * rd)355*fb1b10abSAndroid Build Coastguard Worker static void set_block_thresholds(const VP9_COMMON *cm, RD_OPT *rd) {
356*fb1b10abSAndroid Build Coastguard Worker int i, bsize, segment_id;
357*fb1b10abSAndroid Build Coastguard Worker
358*fb1b10abSAndroid Build Coastguard Worker for (segment_id = 0; segment_id < MAX_SEGMENTS; ++segment_id) {
359*fb1b10abSAndroid Build Coastguard Worker const int qindex =
360*fb1b10abSAndroid Build Coastguard Worker clamp(vp9_get_qindex(&cm->seg, segment_id, cm->base_qindex) +
361*fb1b10abSAndroid Build Coastguard Worker cm->y_dc_delta_q,
362*fb1b10abSAndroid Build Coastguard Worker 0, MAXQ);
363*fb1b10abSAndroid Build Coastguard Worker const int q = compute_rd_thresh_factor(qindex, cm->bit_depth);
364*fb1b10abSAndroid Build Coastguard Worker
365*fb1b10abSAndroid Build Coastguard Worker for (bsize = 0; bsize < BLOCK_SIZES; ++bsize) {
366*fb1b10abSAndroid Build Coastguard Worker // Threshold here seems unnecessarily harsh but fine given actual
367*fb1b10abSAndroid Build Coastguard Worker // range of values used for cpi->sf.thresh_mult[].
368*fb1b10abSAndroid Build Coastguard Worker const int t = q * rd_thresh_block_size_factor[bsize];
369*fb1b10abSAndroid Build Coastguard Worker const int thresh_max = INT_MAX / t;
370*fb1b10abSAndroid Build Coastguard Worker
371*fb1b10abSAndroid Build Coastguard Worker if (bsize >= BLOCK_8X8) {
372*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < MAX_MODES; ++i)
373*fb1b10abSAndroid Build Coastguard Worker rd->threshes[segment_id][bsize][i] = rd->thresh_mult[i] < thresh_max
374*fb1b10abSAndroid Build Coastguard Worker ? rd->thresh_mult[i] * t / 4
375*fb1b10abSAndroid Build Coastguard Worker : INT_MAX;
376*fb1b10abSAndroid Build Coastguard Worker } else {
377*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < MAX_REFS; ++i)
378*fb1b10abSAndroid Build Coastguard Worker rd->threshes[segment_id][bsize][i] =
379*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult_sub8x8[i] < thresh_max
380*fb1b10abSAndroid Build Coastguard Worker ? rd->thresh_mult_sub8x8[i] * t / 4
381*fb1b10abSAndroid Build Coastguard Worker : INT_MAX;
382*fb1b10abSAndroid Build Coastguard Worker }
383*fb1b10abSAndroid Build Coastguard Worker }
384*fb1b10abSAndroid Build Coastguard Worker }
385*fb1b10abSAndroid Build Coastguard Worker }
386*fb1b10abSAndroid Build Coastguard Worker
vp9_build_inter_mode_cost(VP9_COMP * cpi)387*fb1b10abSAndroid Build Coastguard Worker void vp9_build_inter_mode_cost(VP9_COMP *cpi) {
388*fb1b10abSAndroid Build Coastguard Worker const VP9_COMMON *const cm = &cpi->common;
389*fb1b10abSAndroid Build Coastguard Worker int i;
390*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
391*fb1b10abSAndroid Build Coastguard Worker vp9_cost_tokens((int *)cpi->inter_mode_cost[i], cm->fc->inter_mode_probs[i],
392*fb1b10abSAndroid Build Coastguard Worker vp9_inter_mode_tree);
393*fb1b10abSAndroid Build Coastguard Worker }
394*fb1b10abSAndroid Build Coastguard Worker }
395*fb1b10abSAndroid Build Coastguard Worker
vp9_initialize_rd_consts(VP9_COMP * cpi)396*fb1b10abSAndroid Build Coastguard Worker void vp9_initialize_rd_consts(VP9_COMP *cpi) {
397*fb1b10abSAndroid Build Coastguard Worker VP9_COMMON *const cm = &cpi->common;
398*fb1b10abSAndroid Build Coastguard Worker MACROBLOCK *const x = &cpi->td.mb;
399*fb1b10abSAndroid Build Coastguard Worker MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
400*fb1b10abSAndroid Build Coastguard Worker RD_OPT *const rd = &cpi->rd;
401*fb1b10abSAndroid Build Coastguard Worker int i;
402*fb1b10abSAndroid Build Coastguard Worker
403*fb1b10abSAndroid Build Coastguard Worker vpx_clear_system_state();
404*fb1b10abSAndroid Build Coastguard Worker
405*fb1b10abSAndroid Build Coastguard Worker rd->RDDIV = RDDIV_BITS; // In bits (to multiply D by 128).
406*fb1b10abSAndroid Build Coastguard Worker rd->RDMULT = vp9_compute_rd_mult(cpi, cm->base_qindex + cm->y_dc_delta_q);
407*fb1b10abSAndroid Build Coastguard Worker
408*fb1b10abSAndroid Build Coastguard Worker set_error_per_bit(x, rd->RDMULT);
409*fb1b10abSAndroid Build Coastguard Worker
410*fb1b10abSAndroid Build Coastguard Worker x->select_tx_size = (cpi->sf.tx_size_search_method == USE_LARGESTALL &&
411*fb1b10abSAndroid Build Coastguard Worker cm->frame_type != KEY_FRAME)
412*fb1b10abSAndroid Build Coastguard Worker ? 0
413*fb1b10abSAndroid Build Coastguard Worker : 1;
414*fb1b10abSAndroid Build Coastguard Worker
415*fb1b10abSAndroid Build Coastguard Worker set_block_thresholds(cm, rd);
416*fb1b10abSAndroid Build Coastguard Worker set_partition_probs(cm, xd);
417*fb1b10abSAndroid Build Coastguard Worker
418*fb1b10abSAndroid Build Coastguard Worker if (cpi->oxcf.pass == 1) {
419*fb1b10abSAndroid Build Coastguard Worker if (!frame_is_intra_only(cm))
420*fb1b10abSAndroid Build Coastguard Worker vp9_build_nmv_cost_table(
421*fb1b10abSAndroid Build Coastguard Worker x->nmvjointcost,
422*fb1b10abSAndroid Build Coastguard Worker cm->allow_high_precision_mv ? x->nmvcost_hp : x->nmvcost,
423*fb1b10abSAndroid Build Coastguard Worker &cm->fc->nmvc, cm->allow_high_precision_mv);
424*fb1b10abSAndroid Build Coastguard Worker } else {
425*fb1b10abSAndroid Build Coastguard Worker if (!cpi->sf.use_nonrd_pick_mode || cm->frame_type == KEY_FRAME)
426*fb1b10abSAndroid Build Coastguard Worker fill_token_costs(x->token_costs, cm->fc->coef_probs);
427*fb1b10abSAndroid Build Coastguard Worker
428*fb1b10abSAndroid Build Coastguard Worker if (cpi->sf.partition_search_type != VAR_BASED_PARTITION ||
429*fb1b10abSAndroid Build Coastguard Worker cm->frame_type == KEY_FRAME) {
430*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < PARTITION_CONTEXTS; ++i)
431*fb1b10abSAndroid Build Coastguard Worker vp9_cost_tokens(cpi->partition_cost[i], get_partition_probs(xd, i),
432*fb1b10abSAndroid Build Coastguard Worker vp9_partition_tree);
433*fb1b10abSAndroid Build Coastguard Worker }
434*fb1b10abSAndroid Build Coastguard Worker
435*fb1b10abSAndroid Build Coastguard Worker if (!cpi->sf.use_nonrd_pick_mode || (cm->current_video_frame & 0x07) == 1 ||
436*fb1b10abSAndroid Build Coastguard Worker cm->frame_type == KEY_FRAME) {
437*fb1b10abSAndroid Build Coastguard Worker fill_mode_costs(cpi);
438*fb1b10abSAndroid Build Coastguard Worker
439*fb1b10abSAndroid Build Coastguard Worker if (!frame_is_intra_only(cm)) {
440*fb1b10abSAndroid Build Coastguard Worker vp9_build_nmv_cost_table(
441*fb1b10abSAndroid Build Coastguard Worker x->nmvjointcost,
442*fb1b10abSAndroid Build Coastguard Worker cm->allow_high_precision_mv ? x->nmvcost_hp : x->nmvcost,
443*fb1b10abSAndroid Build Coastguard Worker &cm->fc->nmvc, cm->allow_high_precision_mv);
444*fb1b10abSAndroid Build Coastguard Worker vp9_build_inter_mode_cost(cpi);
445*fb1b10abSAndroid Build Coastguard Worker }
446*fb1b10abSAndroid Build Coastguard Worker }
447*fb1b10abSAndroid Build Coastguard Worker }
448*fb1b10abSAndroid Build Coastguard Worker }
449*fb1b10abSAndroid Build Coastguard Worker
450*fb1b10abSAndroid Build Coastguard Worker // NOTE: The tables below must be of the same size.
451*fb1b10abSAndroid Build Coastguard Worker
452*fb1b10abSAndroid Build Coastguard Worker // The functions described below are sampled at the four most significant
453*fb1b10abSAndroid Build Coastguard Worker // bits of x^2 + 8 / 256.
454*fb1b10abSAndroid Build Coastguard Worker
455*fb1b10abSAndroid Build Coastguard Worker // Normalized rate:
456*fb1b10abSAndroid Build Coastguard Worker // This table models the rate for a Laplacian source with given variance
457*fb1b10abSAndroid Build Coastguard Worker // when quantized with a uniform quantizer with given stepsize. The
458*fb1b10abSAndroid Build Coastguard Worker // closed form expression is:
459*fb1b10abSAndroid Build Coastguard Worker // Rn(x) = H(sqrt(r)) + sqrt(r)*[1 + H(r)/(1 - r)],
460*fb1b10abSAndroid Build Coastguard Worker // where r = exp(-sqrt(2) * x) and x = qpstep / sqrt(variance),
461*fb1b10abSAndroid Build Coastguard Worker // and H(x) is the binary entropy function.
462*fb1b10abSAndroid Build Coastguard Worker static const int rate_tab_q10[] = {
463*fb1b10abSAndroid Build Coastguard Worker 65536, 6086, 5574, 5275, 5063, 4899, 4764, 4651, 4553, 4389, 4255, 4142, 4044,
464*fb1b10abSAndroid Build Coastguard Worker 3958, 3881, 3811, 3748, 3635, 3538, 3453, 3376, 3307, 3244, 3186, 3133, 3037,
465*fb1b10abSAndroid Build Coastguard Worker 2952, 2877, 2809, 2747, 2690, 2638, 2589, 2501, 2423, 2353, 2290, 2232, 2179,
466*fb1b10abSAndroid Build Coastguard Worker 2130, 2084, 2001, 1928, 1862, 1802, 1748, 1698, 1651, 1608, 1530, 1460, 1398,
467*fb1b10abSAndroid Build Coastguard Worker 1342, 1290, 1243, 1199, 1159, 1086, 1021, 963, 911, 864, 821, 781, 745,
468*fb1b10abSAndroid Build Coastguard Worker 680, 623, 574, 530, 490, 455, 424, 395, 345, 304, 269, 239, 213,
469*fb1b10abSAndroid Build Coastguard Worker 190, 171, 154, 126, 104, 87, 73, 61, 52, 44, 38, 28, 21,
470*fb1b10abSAndroid Build Coastguard Worker 16, 12, 10, 8, 6, 5, 3, 2, 1, 1, 1, 0, 0,
471*fb1b10abSAndroid Build Coastguard Worker };
472*fb1b10abSAndroid Build Coastguard Worker
473*fb1b10abSAndroid Build Coastguard Worker // Normalized distortion:
474*fb1b10abSAndroid Build Coastguard Worker // This table models the normalized distortion for a Laplacian source
475*fb1b10abSAndroid Build Coastguard Worker // with given variance when quantized with a uniform quantizer
476*fb1b10abSAndroid Build Coastguard Worker // with given stepsize. The closed form expression is:
477*fb1b10abSAndroid Build Coastguard Worker // Dn(x) = 1 - 1/sqrt(2) * x / sinh(x/sqrt(2))
478*fb1b10abSAndroid Build Coastguard Worker // where x = qpstep / sqrt(variance).
479*fb1b10abSAndroid Build Coastguard Worker // Note the actual distortion is Dn * variance.
480*fb1b10abSAndroid Build Coastguard Worker static const int dist_tab_q10[] = {
481*fb1b10abSAndroid Build Coastguard Worker 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5, 5,
482*fb1b10abSAndroid Build Coastguard Worker 6, 7, 7, 8, 9, 11, 12, 13, 15, 16, 17, 18, 21,
483*fb1b10abSAndroid Build Coastguard Worker 24, 26, 29, 31, 34, 36, 39, 44, 49, 54, 59, 64, 69,
484*fb1b10abSAndroid Build Coastguard Worker 73, 78, 88, 97, 106, 115, 124, 133, 142, 151, 167, 184, 200,
485*fb1b10abSAndroid Build Coastguard Worker 215, 231, 245, 260, 274, 301, 327, 351, 375, 397, 418, 439, 458,
486*fb1b10abSAndroid Build Coastguard Worker 495, 528, 559, 587, 613, 637, 659, 680, 717, 749, 777, 801, 823,
487*fb1b10abSAndroid Build Coastguard Worker 842, 859, 874, 899, 919, 936, 949, 960, 969, 977, 983, 994, 1001,
488*fb1b10abSAndroid Build Coastguard Worker 1006, 1010, 1013, 1015, 1017, 1018, 1020, 1022, 1022, 1023, 1023, 1023, 1024,
489*fb1b10abSAndroid Build Coastguard Worker };
490*fb1b10abSAndroid Build Coastguard Worker static const int xsq_iq_q10[] = {
491*fb1b10abSAndroid Build Coastguard Worker 0, 4, 8, 12, 16, 20, 24, 28, 32,
492*fb1b10abSAndroid Build Coastguard Worker 40, 48, 56, 64, 72, 80, 88, 96, 112,
493*fb1b10abSAndroid Build Coastguard Worker 128, 144, 160, 176, 192, 208, 224, 256, 288,
494*fb1b10abSAndroid Build Coastguard Worker 320, 352, 384, 416, 448, 480, 544, 608, 672,
495*fb1b10abSAndroid Build Coastguard Worker 736, 800, 864, 928, 992, 1120, 1248, 1376, 1504,
496*fb1b10abSAndroid Build Coastguard Worker 1632, 1760, 1888, 2016, 2272, 2528, 2784, 3040, 3296,
497*fb1b10abSAndroid Build Coastguard Worker 3552, 3808, 4064, 4576, 5088, 5600, 6112, 6624, 7136,
498*fb1b10abSAndroid Build Coastguard Worker 7648, 8160, 9184, 10208, 11232, 12256, 13280, 14304, 15328,
499*fb1b10abSAndroid Build Coastguard Worker 16352, 18400, 20448, 22496, 24544, 26592, 28640, 30688, 32736,
500*fb1b10abSAndroid Build Coastguard Worker 36832, 40928, 45024, 49120, 53216, 57312, 61408, 65504, 73696,
501*fb1b10abSAndroid Build Coastguard Worker 81888, 90080, 98272, 106464, 114656, 122848, 131040, 147424, 163808,
502*fb1b10abSAndroid Build Coastguard Worker 180192, 196576, 212960, 229344, 245728,
503*fb1b10abSAndroid Build Coastguard Worker };
504*fb1b10abSAndroid Build Coastguard Worker
model_rd_norm(int xsq_q10,int * r_q10,int * d_q10)505*fb1b10abSAndroid Build Coastguard Worker static void model_rd_norm(int xsq_q10, int *r_q10, int *d_q10) {
506*fb1b10abSAndroid Build Coastguard Worker const int tmp = (xsq_q10 >> 2) + 8;
507*fb1b10abSAndroid Build Coastguard Worker const int k = get_msb(tmp) - 3;
508*fb1b10abSAndroid Build Coastguard Worker const int xq = (k << 3) + ((tmp >> k) & 0x7);
509*fb1b10abSAndroid Build Coastguard Worker const int one_q10 = 1 << 10;
510*fb1b10abSAndroid Build Coastguard Worker const int a_q10 = ((xsq_q10 - xsq_iq_q10[xq]) << 10) >> (2 + k);
511*fb1b10abSAndroid Build Coastguard Worker const int b_q10 = one_q10 - a_q10;
512*fb1b10abSAndroid Build Coastguard Worker *r_q10 = (rate_tab_q10[xq] * b_q10 + rate_tab_q10[xq + 1] * a_q10) >> 10;
513*fb1b10abSAndroid Build Coastguard Worker *d_q10 = (dist_tab_q10[xq] * b_q10 + dist_tab_q10[xq + 1] * a_q10) >> 10;
514*fb1b10abSAndroid Build Coastguard Worker }
515*fb1b10abSAndroid Build Coastguard Worker
516*fb1b10abSAndroid Build Coastguard Worker static const uint32_t MAX_XSQ_Q10 = 245727;
517*fb1b10abSAndroid Build Coastguard Worker
vp9_model_rd_from_var_lapndz(unsigned int var,unsigned int n_log2,unsigned int qstep,int * rate,int64_t * dist)518*fb1b10abSAndroid Build Coastguard Worker void vp9_model_rd_from_var_lapndz(unsigned int var, unsigned int n_log2,
519*fb1b10abSAndroid Build Coastguard Worker unsigned int qstep, int *rate,
520*fb1b10abSAndroid Build Coastguard Worker int64_t *dist) {
521*fb1b10abSAndroid Build Coastguard Worker // This function models the rate and distortion for a Laplacian
522*fb1b10abSAndroid Build Coastguard Worker // source with given variance when quantized with a uniform quantizer
523*fb1b10abSAndroid Build Coastguard Worker // with given stepsize. The closed form expressions are in:
524*fb1b10abSAndroid Build Coastguard Worker // Hang and Chen, "Source Model for transform video coder and its
525*fb1b10abSAndroid Build Coastguard Worker // application - Part I: Fundamental Theory", IEEE Trans. Circ.
526*fb1b10abSAndroid Build Coastguard Worker // Sys. for Video Tech., April 1997.
527*fb1b10abSAndroid Build Coastguard Worker if (var == 0) {
528*fb1b10abSAndroid Build Coastguard Worker *rate = 0;
529*fb1b10abSAndroid Build Coastguard Worker *dist = 0;
530*fb1b10abSAndroid Build Coastguard Worker } else {
531*fb1b10abSAndroid Build Coastguard Worker int d_q10, r_q10;
532*fb1b10abSAndroid Build Coastguard Worker const uint64_t xsq_q10_64 =
533*fb1b10abSAndroid Build Coastguard Worker (((uint64_t)qstep * qstep << (n_log2 + 10)) + (var >> 1)) / var;
534*fb1b10abSAndroid Build Coastguard Worker const int xsq_q10 = (int)VPXMIN(xsq_q10_64, MAX_XSQ_Q10);
535*fb1b10abSAndroid Build Coastguard Worker model_rd_norm(xsq_q10, &r_q10, &d_q10);
536*fb1b10abSAndroid Build Coastguard Worker *rate = ROUND_POWER_OF_TWO(r_q10 << n_log2, 10 - VP9_PROB_COST_SHIFT);
537*fb1b10abSAndroid Build Coastguard Worker *dist = (var * (int64_t)d_q10 + 512) >> 10;
538*fb1b10abSAndroid Build Coastguard Worker }
539*fb1b10abSAndroid Build Coastguard Worker }
540*fb1b10abSAndroid Build Coastguard Worker
541*fb1b10abSAndroid Build Coastguard Worker // Disable gcc 12.2 false positive warning.
542*fb1b10abSAndroid Build Coastguard Worker // warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
543*fb1b10abSAndroid Build Coastguard Worker #if defined(__GNUC__) && !defined(__clang__)
544*fb1b10abSAndroid Build Coastguard Worker #pragma GCC diagnostic push
545*fb1b10abSAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wstringop-overflow"
546*fb1b10abSAndroid Build Coastguard Worker #endif
vp9_get_entropy_contexts(BLOCK_SIZE bsize,TX_SIZE tx_size,const struct macroblockd_plane * pd,ENTROPY_CONTEXT t_above[16],ENTROPY_CONTEXT t_left[16])547*fb1b10abSAndroid Build Coastguard Worker void vp9_get_entropy_contexts(BLOCK_SIZE bsize, TX_SIZE tx_size,
548*fb1b10abSAndroid Build Coastguard Worker const struct macroblockd_plane *pd,
549*fb1b10abSAndroid Build Coastguard Worker ENTROPY_CONTEXT t_above[16],
550*fb1b10abSAndroid Build Coastguard Worker ENTROPY_CONTEXT t_left[16]) {
551*fb1b10abSAndroid Build Coastguard Worker const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
552*fb1b10abSAndroid Build Coastguard Worker const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize];
553*fb1b10abSAndroid Build Coastguard Worker const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize];
554*fb1b10abSAndroid Build Coastguard Worker const ENTROPY_CONTEXT *const above = pd->above_context;
555*fb1b10abSAndroid Build Coastguard Worker const ENTROPY_CONTEXT *const left = pd->left_context;
556*fb1b10abSAndroid Build Coastguard Worker
557*fb1b10abSAndroid Build Coastguard Worker int i;
558*fb1b10abSAndroid Build Coastguard Worker switch (tx_size) {
559*fb1b10abSAndroid Build Coastguard Worker case TX_4X4:
560*fb1b10abSAndroid Build Coastguard Worker memcpy(t_above, above, sizeof(ENTROPY_CONTEXT) * num_4x4_w);
561*fb1b10abSAndroid Build Coastguard Worker memcpy(t_left, left, sizeof(ENTROPY_CONTEXT) * num_4x4_h);
562*fb1b10abSAndroid Build Coastguard Worker break;
563*fb1b10abSAndroid Build Coastguard Worker case TX_8X8:
564*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < num_4x4_w; i += 2)
565*fb1b10abSAndroid Build Coastguard Worker t_above[i] = !!*(const uint16_t *)&above[i];
566*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < num_4x4_h; i += 2)
567*fb1b10abSAndroid Build Coastguard Worker t_left[i] = !!*(const uint16_t *)&left[i];
568*fb1b10abSAndroid Build Coastguard Worker break;
569*fb1b10abSAndroid Build Coastguard Worker case TX_16X16:
570*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < num_4x4_w; i += 4)
571*fb1b10abSAndroid Build Coastguard Worker t_above[i] = !!*(const uint32_t *)&above[i];
572*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < num_4x4_h; i += 4)
573*fb1b10abSAndroid Build Coastguard Worker t_left[i] = !!*(const uint32_t *)&left[i];
574*fb1b10abSAndroid Build Coastguard Worker break;
575*fb1b10abSAndroid Build Coastguard Worker default:
576*fb1b10abSAndroid Build Coastguard Worker assert(tx_size == TX_32X32);
577*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < num_4x4_w; i += 8)
578*fb1b10abSAndroid Build Coastguard Worker t_above[i] = !!*(const uint64_t *)&above[i];
579*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < num_4x4_h; i += 8)
580*fb1b10abSAndroid Build Coastguard Worker t_left[i] = !!*(const uint64_t *)&left[i];
581*fb1b10abSAndroid Build Coastguard Worker break;
582*fb1b10abSAndroid Build Coastguard Worker }
583*fb1b10abSAndroid Build Coastguard Worker }
584*fb1b10abSAndroid Build Coastguard Worker #if defined(__GNUC__) && !defined(__clang__)
585*fb1b10abSAndroid Build Coastguard Worker #pragma GCC diagnostic pop
586*fb1b10abSAndroid Build Coastguard Worker #endif
587*fb1b10abSAndroid Build Coastguard Worker
vp9_mv_pred(VP9_COMP * cpi,MACROBLOCK * x,uint8_t * ref_y_buffer,int ref_y_stride,int ref_frame,BLOCK_SIZE block_size)588*fb1b10abSAndroid Build Coastguard Worker void vp9_mv_pred(VP9_COMP *cpi, MACROBLOCK *x, uint8_t *ref_y_buffer,
589*fb1b10abSAndroid Build Coastguard Worker int ref_y_stride, int ref_frame, BLOCK_SIZE block_size) {
590*fb1b10abSAndroid Build Coastguard Worker int i;
591*fb1b10abSAndroid Build Coastguard Worker int zero_seen = 0;
592*fb1b10abSAndroid Build Coastguard Worker int best_index = 0;
593*fb1b10abSAndroid Build Coastguard Worker int best_sad = INT_MAX;
594*fb1b10abSAndroid Build Coastguard Worker int this_sad = INT_MAX;
595*fb1b10abSAndroid Build Coastguard Worker int max_mv = 0;
596*fb1b10abSAndroid Build Coastguard Worker int near_same_nearest;
597*fb1b10abSAndroid Build Coastguard Worker uint8_t *src_y_ptr = x->plane[0].src.buf;
598*fb1b10abSAndroid Build Coastguard Worker uint8_t *ref_y_ptr;
599*fb1b10abSAndroid Build Coastguard Worker const int num_mv_refs =
600*fb1b10abSAndroid Build Coastguard Worker MAX_MV_REF_CANDIDATES + (block_size < x->max_partition_size);
601*fb1b10abSAndroid Build Coastguard Worker
602*fb1b10abSAndroid Build Coastguard Worker MV pred_mv[3];
603*fb1b10abSAndroid Build Coastguard Worker pred_mv[0] = x->mbmi_ext->ref_mvs[ref_frame][0].as_mv;
604*fb1b10abSAndroid Build Coastguard Worker pred_mv[1] = x->mbmi_ext->ref_mvs[ref_frame][1].as_mv;
605*fb1b10abSAndroid Build Coastguard Worker pred_mv[2] = x->pred_mv[ref_frame];
606*fb1b10abSAndroid Build Coastguard Worker assert(num_mv_refs <= (int)(sizeof(pred_mv) / sizeof(pred_mv[0])));
607*fb1b10abSAndroid Build Coastguard Worker
608*fb1b10abSAndroid Build Coastguard Worker near_same_nearest = x->mbmi_ext->ref_mvs[ref_frame][0].as_int ==
609*fb1b10abSAndroid Build Coastguard Worker x->mbmi_ext->ref_mvs[ref_frame][1].as_int;
610*fb1b10abSAndroid Build Coastguard Worker
611*fb1b10abSAndroid Build Coastguard Worker // Get the sad for each candidate reference mv.
612*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < num_mv_refs; ++i) {
613*fb1b10abSAndroid Build Coastguard Worker const MV *this_mv = &pred_mv[i];
614*fb1b10abSAndroid Build Coastguard Worker int fp_row, fp_col;
615*fb1b10abSAndroid Build Coastguard Worker if (this_mv->row == INT16_MAX || this_mv->col == INT16_MAX) continue;
616*fb1b10abSAndroid Build Coastguard Worker if (i == 1 && near_same_nearest) continue;
617*fb1b10abSAndroid Build Coastguard Worker fp_row = (this_mv->row + 3 + (this_mv->row >= 0)) >> 3;
618*fb1b10abSAndroid Build Coastguard Worker fp_col = (this_mv->col + 3 + (this_mv->col >= 0)) >> 3;
619*fb1b10abSAndroid Build Coastguard Worker max_mv = VPXMAX(max_mv, VPXMAX(abs(this_mv->row), abs(this_mv->col)) >> 3);
620*fb1b10abSAndroid Build Coastguard Worker
621*fb1b10abSAndroid Build Coastguard Worker if (fp_row == 0 && fp_col == 0 && zero_seen) continue;
622*fb1b10abSAndroid Build Coastguard Worker zero_seen |= (fp_row == 0 && fp_col == 0);
623*fb1b10abSAndroid Build Coastguard Worker
624*fb1b10abSAndroid Build Coastguard Worker ref_y_ptr = &ref_y_buffer[ref_y_stride * fp_row + fp_col];
625*fb1b10abSAndroid Build Coastguard Worker // Find sad for current vector.
626*fb1b10abSAndroid Build Coastguard Worker this_sad = cpi->fn_ptr[block_size].sdf(src_y_ptr, x->plane[0].src.stride,
627*fb1b10abSAndroid Build Coastguard Worker ref_y_ptr, ref_y_stride);
628*fb1b10abSAndroid Build Coastguard Worker // Note if it is the best so far.
629*fb1b10abSAndroid Build Coastguard Worker if (this_sad < best_sad) {
630*fb1b10abSAndroid Build Coastguard Worker best_sad = this_sad;
631*fb1b10abSAndroid Build Coastguard Worker best_index = i;
632*fb1b10abSAndroid Build Coastguard Worker }
633*fb1b10abSAndroid Build Coastguard Worker }
634*fb1b10abSAndroid Build Coastguard Worker
635*fb1b10abSAndroid Build Coastguard Worker // Note the index of the mv that worked best in the reference list.
636*fb1b10abSAndroid Build Coastguard Worker x->mv_best_ref_index[ref_frame] = best_index;
637*fb1b10abSAndroid Build Coastguard Worker x->max_mv_context[ref_frame] = max_mv;
638*fb1b10abSAndroid Build Coastguard Worker x->pred_mv_sad[ref_frame] = best_sad;
639*fb1b10abSAndroid Build Coastguard Worker }
640*fb1b10abSAndroid Build Coastguard Worker
vp9_setup_pred_block(const MACROBLOCKD * xd,struct buf_2d dst[MAX_MB_PLANE],const YV12_BUFFER_CONFIG * src,int mi_row,int mi_col,const struct scale_factors * scale,const struct scale_factors * scale_uv)641*fb1b10abSAndroid Build Coastguard Worker void vp9_setup_pred_block(const MACROBLOCKD *xd,
642*fb1b10abSAndroid Build Coastguard Worker struct buf_2d dst[MAX_MB_PLANE],
643*fb1b10abSAndroid Build Coastguard Worker const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col,
644*fb1b10abSAndroid Build Coastguard Worker const struct scale_factors *scale,
645*fb1b10abSAndroid Build Coastguard Worker const struct scale_factors *scale_uv) {
646*fb1b10abSAndroid Build Coastguard Worker int i;
647*fb1b10abSAndroid Build Coastguard Worker
648*fb1b10abSAndroid Build Coastguard Worker dst[0].buf = src->y_buffer;
649*fb1b10abSAndroid Build Coastguard Worker dst[0].stride = src->y_stride;
650*fb1b10abSAndroid Build Coastguard Worker dst[1].buf = src->u_buffer;
651*fb1b10abSAndroid Build Coastguard Worker dst[2].buf = src->v_buffer;
652*fb1b10abSAndroid Build Coastguard Worker dst[1].stride = dst[2].stride = src->uv_stride;
653*fb1b10abSAndroid Build Coastguard Worker
654*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < MAX_MB_PLANE; ++i) {
655*fb1b10abSAndroid Build Coastguard Worker setup_pred_plane(dst + i, dst[i].buf, dst[i].stride, mi_row, mi_col,
656*fb1b10abSAndroid Build Coastguard Worker i ? scale_uv : scale, xd->plane[i].subsampling_x,
657*fb1b10abSAndroid Build Coastguard Worker xd->plane[i].subsampling_y);
658*fb1b10abSAndroid Build Coastguard Worker }
659*fb1b10abSAndroid Build Coastguard Worker }
660*fb1b10abSAndroid Build Coastguard Worker
vp9_raster_block_offset(BLOCK_SIZE plane_bsize,int raster_block,int stride)661*fb1b10abSAndroid Build Coastguard Worker int vp9_raster_block_offset(BLOCK_SIZE plane_bsize, int raster_block,
662*fb1b10abSAndroid Build Coastguard Worker int stride) {
663*fb1b10abSAndroid Build Coastguard Worker const int bw = b_width_log2_lookup[plane_bsize];
664*fb1b10abSAndroid Build Coastguard Worker const int y = 4 * (raster_block >> bw);
665*fb1b10abSAndroid Build Coastguard Worker const int x = 4 * (raster_block & ((1 << bw) - 1));
666*fb1b10abSAndroid Build Coastguard Worker return y * stride + x;
667*fb1b10abSAndroid Build Coastguard Worker }
668*fb1b10abSAndroid Build Coastguard Worker
vp9_raster_block_offset_int16(BLOCK_SIZE plane_bsize,int raster_block,int16_t * base)669*fb1b10abSAndroid Build Coastguard Worker int16_t *vp9_raster_block_offset_int16(BLOCK_SIZE plane_bsize, int raster_block,
670*fb1b10abSAndroid Build Coastguard Worker int16_t *base) {
671*fb1b10abSAndroid Build Coastguard Worker const int stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
672*fb1b10abSAndroid Build Coastguard Worker return base + vp9_raster_block_offset(plane_bsize, raster_block, stride);
673*fb1b10abSAndroid Build Coastguard Worker }
674*fb1b10abSAndroid Build Coastguard Worker
vp9_get_scaled_ref_frame(const VP9_COMP * cpi,int ref_frame)675*fb1b10abSAndroid Build Coastguard Worker YV12_BUFFER_CONFIG *vp9_get_scaled_ref_frame(const VP9_COMP *cpi,
676*fb1b10abSAndroid Build Coastguard Worker int ref_frame) {
677*fb1b10abSAndroid Build Coastguard Worker const VP9_COMMON *const cm = &cpi->common;
678*fb1b10abSAndroid Build Coastguard Worker const int scaled_idx = cpi->scaled_ref_idx[ref_frame - 1];
679*fb1b10abSAndroid Build Coastguard Worker const int ref_idx = get_ref_frame_buf_idx(cpi, ref_frame);
680*fb1b10abSAndroid Build Coastguard Worker assert(ref_frame >= LAST_FRAME && ref_frame <= ALTREF_FRAME);
681*fb1b10abSAndroid Build Coastguard Worker return (scaled_idx != ref_idx && scaled_idx != INVALID_IDX)
682*fb1b10abSAndroid Build Coastguard Worker ? &cm->buffer_pool->frame_bufs[scaled_idx].buf
683*fb1b10abSAndroid Build Coastguard Worker : NULL;
684*fb1b10abSAndroid Build Coastguard Worker }
685*fb1b10abSAndroid Build Coastguard Worker
vp9_get_switchable_rate(const VP9_COMP * cpi,const MACROBLOCKD * const xd)686*fb1b10abSAndroid Build Coastguard Worker int vp9_get_switchable_rate(const VP9_COMP *cpi, const MACROBLOCKD *const xd) {
687*fb1b10abSAndroid Build Coastguard Worker const MODE_INFO *const mi = xd->mi[0];
688*fb1b10abSAndroid Build Coastguard Worker const int ctx = get_pred_context_switchable_interp(xd);
689*fb1b10abSAndroid Build Coastguard Worker return SWITCHABLE_INTERP_RATE_FACTOR *
690*fb1b10abSAndroid Build Coastguard Worker cpi->switchable_interp_costs[ctx][mi->interp_filter];
691*fb1b10abSAndroid Build Coastguard Worker }
692*fb1b10abSAndroid Build Coastguard Worker
vp9_set_rd_speed_thresholds(VP9_COMP * cpi)693*fb1b10abSAndroid Build Coastguard Worker void vp9_set_rd_speed_thresholds(VP9_COMP *cpi) {
694*fb1b10abSAndroid Build Coastguard Worker int i;
695*fb1b10abSAndroid Build Coastguard Worker RD_OPT *const rd = &cpi->rd;
696*fb1b10abSAndroid Build Coastguard Worker SPEED_FEATURES *const sf = &cpi->sf;
697*fb1b10abSAndroid Build Coastguard Worker
698*fb1b10abSAndroid Build Coastguard Worker // Set baseline threshold values.
699*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < MAX_MODES; ++i)
700*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[i] = cpi->oxcf.mode == BEST ? -500 : 0;
701*fb1b10abSAndroid Build Coastguard Worker
702*fb1b10abSAndroid Build Coastguard Worker if (sf->adaptive_rd_thresh) {
703*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_NEARESTMV] = 300;
704*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_NEARESTG] = 300;
705*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_NEARESTA] = 300;
706*fb1b10abSAndroid Build Coastguard Worker } else {
707*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_NEARESTMV] = 0;
708*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_NEARESTG] = 0;
709*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_NEARESTA] = 0;
710*fb1b10abSAndroid Build Coastguard Worker }
711*fb1b10abSAndroid Build Coastguard Worker
712*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_DC] += 1000;
713*fb1b10abSAndroid Build Coastguard Worker
714*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_NEWMV] += 1000;
715*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_NEWA] += 1000;
716*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_NEWG] += 1000;
717*fb1b10abSAndroid Build Coastguard Worker
718*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_NEARMV] += 1000;
719*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_NEARA] += 1000;
720*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_COMP_NEARESTLA] += 1000;
721*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_COMP_NEARESTGA] += 1000;
722*fb1b10abSAndroid Build Coastguard Worker
723*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_TM] += 1000;
724*fb1b10abSAndroid Build Coastguard Worker
725*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_COMP_NEARLA] += 1500;
726*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_COMP_NEWLA] += 2000;
727*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_NEARG] += 1000;
728*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_COMP_NEARGA] += 1500;
729*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_COMP_NEWGA] += 2000;
730*fb1b10abSAndroid Build Coastguard Worker
731*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_ZEROMV] += 2000;
732*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_ZEROG] += 2000;
733*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_ZEROA] += 2000;
734*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_COMP_ZEROLA] += 2500;
735*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_COMP_ZEROGA] += 2500;
736*fb1b10abSAndroid Build Coastguard Worker
737*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_H_PRED] += 2000;
738*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_V_PRED] += 2000;
739*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_D45_PRED] += 2500;
740*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_D135_PRED] += 2500;
741*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_D117_PRED] += 2500;
742*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_D153_PRED] += 2500;
743*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_D207_PRED] += 2500;
744*fb1b10abSAndroid Build Coastguard Worker rd->thresh_mult[THR_D63_PRED] += 2500;
745*fb1b10abSAndroid Build Coastguard Worker }
746*fb1b10abSAndroid Build Coastguard Worker
vp9_set_rd_speed_thresholds_sub8x8(VP9_COMP * cpi)747*fb1b10abSAndroid Build Coastguard Worker void vp9_set_rd_speed_thresholds_sub8x8(VP9_COMP *cpi) {
748*fb1b10abSAndroid Build Coastguard Worker static const int thresh_mult[2][MAX_REFS] = {
749*fb1b10abSAndroid Build Coastguard Worker { 2500, 2500, 2500, 4500, 4500, 2500 },
750*fb1b10abSAndroid Build Coastguard Worker { 2000, 2000, 2000, 4000, 4000, 2000 }
751*fb1b10abSAndroid Build Coastguard Worker };
752*fb1b10abSAndroid Build Coastguard Worker RD_OPT *const rd = &cpi->rd;
753*fb1b10abSAndroid Build Coastguard Worker const int idx = cpi->oxcf.mode == BEST;
754*fb1b10abSAndroid Build Coastguard Worker memcpy(rd->thresh_mult_sub8x8, thresh_mult[idx], sizeof(thresh_mult[idx]));
755*fb1b10abSAndroid Build Coastguard Worker }
756*fb1b10abSAndroid Build Coastguard Worker
vp9_update_rd_thresh_fact(int (* factor_buf)[MAX_MODES],int rd_thresh,int bsize,int best_mode_index)757*fb1b10abSAndroid Build Coastguard Worker void vp9_update_rd_thresh_fact(int (*factor_buf)[MAX_MODES], int rd_thresh,
758*fb1b10abSAndroid Build Coastguard Worker int bsize, int best_mode_index) {
759*fb1b10abSAndroid Build Coastguard Worker if (rd_thresh > 0) {
760*fb1b10abSAndroid Build Coastguard Worker const int top_mode = bsize < BLOCK_8X8 ? MAX_REFS : MAX_MODES;
761*fb1b10abSAndroid Build Coastguard Worker int mode;
762*fb1b10abSAndroid Build Coastguard Worker for (mode = 0; mode < top_mode; ++mode) {
763*fb1b10abSAndroid Build Coastguard Worker const BLOCK_SIZE min_size = VPXMAX(bsize - 1, BLOCK_4X4);
764*fb1b10abSAndroid Build Coastguard Worker const BLOCK_SIZE max_size = VPXMIN(bsize + 2, BLOCK_64X64);
765*fb1b10abSAndroid Build Coastguard Worker BLOCK_SIZE bs;
766*fb1b10abSAndroid Build Coastguard Worker for (bs = min_size; bs <= max_size; ++bs) {
767*fb1b10abSAndroid Build Coastguard Worker int *const fact = &factor_buf[bs][mode];
768*fb1b10abSAndroid Build Coastguard Worker if (mode == best_mode_index) {
769*fb1b10abSAndroid Build Coastguard Worker *fact -= (*fact >> 4);
770*fb1b10abSAndroid Build Coastguard Worker } else {
771*fb1b10abSAndroid Build Coastguard Worker *fact = VPXMIN(*fact + RD_THRESH_INC, rd_thresh * RD_THRESH_MAX_FACT);
772*fb1b10abSAndroid Build Coastguard Worker }
773*fb1b10abSAndroid Build Coastguard Worker }
774*fb1b10abSAndroid Build Coastguard Worker }
775*fb1b10abSAndroid Build Coastguard Worker }
776*fb1b10abSAndroid Build Coastguard Worker }
777*fb1b10abSAndroid Build Coastguard Worker
vp9_get_intra_cost_penalty(const VP9_COMP * const cpi,BLOCK_SIZE bsize,int qindex,int qdelta)778*fb1b10abSAndroid Build Coastguard Worker int vp9_get_intra_cost_penalty(const VP9_COMP *const cpi, BLOCK_SIZE bsize,
779*fb1b10abSAndroid Build Coastguard Worker int qindex, int qdelta) {
780*fb1b10abSAndroid Build Coastguard Worker // Reduce the intra cost penalty for small blocks (<=16x16).
781*fb1b10abSAndroid Build Coastguard Worker int reduction_fac =
782*fb1b10abSAndroid Build Coastguard Worker (bsize <= BLOCK_16X16) ? ((bsize <= BLOCK_8X8) ? 4 : 2) : 0;
783*fb1b10abSAndroid Build Coastguard Worker
784*fb1b10abSAndroid Build Coastguard Worker if (cpi->noise_estimate.enabled && cpi->noise_estimate.level == kHigh)
785*fb1b10abSAndroid Build Coastguard Worker // Don't reduce intra cost penalty if estimated noise level is high.
786*fb1b10abSAndroid Build Coastguard Worker reduction_fac = 0;
787*fb1b10abSAndroid Build Coastguard Worker
788*fb1b10abSAndroid Build Coastguard Worker // Always use VPX_BITS_8 as input here because the penalty is applied
789*fb1b10abSAndroid Build Coastguard Worker // to rate not distortion so we want a consistent penalty for all bit
790*fb1b10abSAndroid Build Coastguard Worker // depths. If the actual bit depth were passed in here then the value
791*fb1b10abSAndroid Build Coastguard Worker // retured by vp9_dc_quant() would scale with the bit depth and we would
792*fb1b10abSAndroid Build Coastguard Worker // then need to apply inverse scaling to correct back to a bit depth
793*fb1b10abSAndroid Build Coastguard Worker // independent rate penalty.
794*fb1b10abSAndroid Build Coastguard Worker return (20 * vp9_dc_quant(qindex, qdelta, VPX_BITS_8)) >> reduction_fac;
795*fb1b10abSAndroid Build Coastguard Worker }
796