blob: 5a59e2dcf258615932053680ba52bb8945b3db6f [file] [log] [blame]
Jingning Han3ee6db62015-08-05 19:00:31 -07001/*
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 <assert.h>
12#include <math.h>
13
14#include "./vp10_rtcd.h"
15#include "./vpx_dsp_rtcd.h"
16
Johannc5f11912015-08-31 14:36:35 -070017#include "vpx_dsp/vpx_dsp_common.h"
Jingning Han3ee6db62015-08-05 19:00:31 -070018#include "vpx_mem/vpx_mem.h"
19#include "vpx_ports/mem.h"
Jingning Han3acfe462015-08-12 09:20:31 -070020#include "vpx_ports/system_state.h"
Jingning Han3ee6db62015-08-05 19:00:31 -070021
Jingning Han54d66ef2015-08-06 21:14:07 -070022#include "vp10/common/common.h"
23#include "vp10/common/entropy.h"
24#include "vp10/common/entropymode.h"
25#include "vp10/common/idct.h"
26#include "vp10/common/mvref_common.h"
27#include "vp10/common/pred_common.h"
28#include "vp10/common/quant_common.h"
29#include "vp10/common/reconinter.h"
30#include "vp10/common/reconintra.h"
31#include "vp10/common/scan.h"
32#include "vp10/common/seg_common.h"
Jingning Han3ee6db62015-08-05 19:00:31 -070033
Jingning Han54d66ef2015-08-06 21:14:07 -070034#include "vp10/encoder/cost.h"
35#include "vp10/encoder/encodemb.h"
36#include "vp10/encoder/encodemv.h"
37#include "vp10/encoder/encoder.h"
Angie Chiang96baa732015-11-18 15:17:18 -080038#include "vp10/encoder/hybrid_fwd_txfm.h"
Jingning Han54d66ef2015-08-06 21:14:07 -070039#include "vp10/encoder/mcomp.h"
hui suc93e5cc2015-12-07 18:18:57 -080040#include "vp10/encoder/palette.h"
Jingning Han54d66ef2015-08-06 21:14:07 -070041#include "vp10/encoder/quantize.h"
42#include "vp10/encoder/ratectrl.h"
43#include "vp10/encoder/rd.h"
44#include "vp10/encoder/rdopt.h"
45#include "vp10/encoder/aq_variance.h"
Jingning Han3ee6db62015-08-05 19:00:31 -070046
Zoe Liu3ec16012015-11-12 02:12:17 -080047#if CONFIG_EXT_REFS
48
49#define LAST_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \
50 (1 << LAST2_FRAME) | (1 << INTRA_FRAME) | \
51 (1 << LAST3_FRAME) | (1 << LAST4_FRAME))
52#define LAST2_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \
53 (1 << LAST_FRAME) | (1 << INTRA_FRAME) | \
54 (1 << LAST3_FRAME) | (1 << LAST4_FRAME))
55#define LAST3_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \
56 (1 << LAST_FRAME) | (1 << INTRA_FRAME) | \
57 (1 << LAST2_FRAME) | (1 << LAST4_FRAME))
58#define LAST4_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \
59 (1 << LAST_FRAME) | (1 << INTRA_FRAME) | \
60 (1 << LAST2_FRAME) | (1 << LAST3_FRAME))
61#define GOLDEN_FRAME_MODE_MASK ((1 << LAST_FRAME) | (1 << ALTREF_FRAME) | \
62 (1 << LAST2_FRAME) | (1 << INTRA_FRAME) | \
63 (1 << LAST3_FRAME) | (1 << LAST4_FRAME))
64#define ALT_REF_MODE_MASK ((1 << LAST_FRAME) | (1 << GOLDEN_FRAME) | \
65 (1 << LAST2_FRAME) | (1 << INTRA_FRAME) | \
66 (1 << LAST3_FRAME) | (1 << LAST4_FRAME))
67
68#else
69
Jingning Han3ee6db62015-08-05 19:00:31 -070070#define LAST_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \
71 (1 << INTRA_FRAME))
72#define GOLDEN_FRAME_MODE_MASK ((1 << LAST_FRAME) | (1 << ALTREF_FRAME) | \
73 (1 << INTRA_FRAME))
74#define ALT_REF_MODE_MASK ((1 << LAST_FRAME) | (1 << GOLDEN_FRAME) | \
75 (1 << INTRA_FRAME))
76
Zoe Liu3ec16012015-11-12 02:12:17 -080077#endif // CONFIG_EXT_REFS
78
Jingning Han3ee6db62015-08-05 19:00:31 -070079#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | 0x01)
80
81#define MIN_EARLY_TERM_INDEX 3
82#define NEW_MV_DISCOUNT_FACTOR 8
83
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -070084#if CONFIG_EXT_TX
Debargha Mukherjeeb8bc0262015-09-11 08:32:56 -070085const double ext_tx_th = 0.98;
Yaowu Xu0367f322016-01-11 10:27:35 -080086#else
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -080087const double ext_tx_th = 0.99;
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -070088#endif
89
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -080090
Jingning Han3ee6db62015-08-05 19:00:31 -070091typedef struct {
92 PREDICTION_MODE mode;
93 MV_REFERENCE_FRAME ref_frame[2];
94} MODE_DEFINITION;
95
96typedef struct {
97 MV_REFERENCE_FRAME ref_frame[2];
98} REF_DEFINITION;
99
100struct rdcost_block_args {
Jingning Han71c15602015-10-13 12:40:39 -0700101#if CONFIG_VAR_TX
102 const VP10_COMP *cpi;
103#endif
Jingning Han3ee6db62015-08-05 19:00:31 -0700104 MACROBLOCK *x;
105 ENTROPY_CONTEXT t_above[16];
106 ENTROPY_CONTEXT t_left[16];
107 int this_rate;
108 int64_t this_dist;
109 int64_t this_sse;
110 int64_t this_rd;
111 int64_t best_rd;
112 int exit_early;
113 int use_fast_coef_costing;
114 const scan_order *so;
115 uint8_t skippable;
116};
117
118#define LAST_NEW_MV_INDEX 6
119static const MODE_DEFINITION vp10_mode_order[MAX_MODES] = {
120 {NEARESTMV, {LAST_FRAME, NONE}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800121#if CONFIG_EXT_REFS
122 {NEARESTMV, {LAST2_FRAME, NONE}},
123 {NEARESTMV, {LAST3_FRAME, NONE}},
124 {NEARESTMV, {LAST4_FRAME, NONE}},
125#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700126 {NEARESTMV, {ALTREF_FRAME, NONE}},
127 {NEARESTMV, {GOLDEN_FRAME, NONE}},
128
129 {DC_PRED, {INTRA_FRAME, NONE}},
130
131 {NEWMV, {LAST_FRAME, NONE}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800132#if CONFIG_EXT_REFS
133 {NEWMV, {LAST2_FRAME, NONE}},
134 {NEWMV, {LAST3_FRAME, NONE}},
135 {NEWMV, {LAST4_FRAME, NONE}},
136#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700137 {NEWMV, {ALTREF_FRAME, NONE}},
138 {NEWMV, {GOLDEN_FRAME, NONE}},
139
140 {NEARMV, {LAST_FRAME, NONE}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800141#if CONFIG_EXT_REFS
142 {NEARMV, {LAST2_FRAME, NONE}},
143 {NEARMV, {LAST3_FRAME, NONE}},
144 {NEARMV, {LAST4_FRAME, NONE}},
145#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700146 {NEARMV, {ALTREF_FRAME, NONE}},
147 {NEARMV, {GOLDEN_FRAME, NONE}},
148
Yue Chen1ac85872016-01-07 15:13:52 -0800149#if CONFIG_EXT_INTER
150 {NEWFROMNEARMV, {LAST_FRAME, NONE}},
Yue Chen968bbc72016-01-19 16:45:45 -0800151#if CONFIG_EXT_REFS
Yue Chen1ac85872016-01-07 15:13:52 -0800152 {NEWFROMNEARMV, {LAST2_FRAME, NONE}},
153 {NEWFROMNEARMV, {LAST3_FRAME, NONE}},
154 {NEWFROMNEARMV, {LAST4_FRAME, NONE}},
Yue Chen968bbc72016-01-19 16:45:45 -0800155#endif // CONFIG_EXT_REFS
Yue Chen1ac85872016-01-07 15:13:52 -0800156 {NEWFROMNEARMV, {ALTREF_FRAME, NONE}},
157 {NEWFROMNEARMV, {GOLDEN_FRAME, NONE}},
158#endif // CONFIG_EXT_INTER
159
Jingning Han3ee6db62015-08-05 19:00:31 -0700160 {ZEROMV, {LAST_FRAME, NONE}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800161#if CONFIG_EXT_REFS
162 {ZEROMV, {LAST2_FRAME, NONE}},
163 {ZEROMV, {LAST3_FRAME, NONE}},
164 {ZEROMV, {LAST4_FRAME, NONE}},
165#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700166 {ZEROMV, {GOLDEN_FRAME, NONE}},
167 {ZEROMV, {ALTREF_FRAME, NONE}},
168
Yue Chen968bbc72016-01-19 16:45:45 -0800169#if CONFIG_EXT_INTER
170 {NEAREST_NEARESTMV, {LAST_FRAME, ALTREF_FRAME}},
171#if CONFIG_EXT_REFS
172 {NEAREST_NEARESTMV, {LAST2_FRAME, ALTREF_FRAME}},
173 {NEAREST_NEARESTMV, {LAST3_FRAME, ALTREF_FRAME}},
174 {NEAREST_NEARESTMV, {LAST4_FRAME, ALTREF_FRAME}},
175#endif // CONFIG_EXT_REFS
176 {NEAREST_NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
177#else // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -0700178 {NEARESTMV, {LAST_FRAME, ALTREF_FRAME}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800179#if CONFIG_EXT_REFS
180 {NEARESTMV, {LAST2_FRAME, ALTREF_FRAME}},
181 {NEARESTMV, {LAST3_FRAME, ALTREF_FRAME}},
182 {NEARESTMV, {LAST4_FRAME, ALTREF_FRAME}},
183#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700184 {NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
Yue Chen968bbc72016-01-19 16:45:45 -0800185#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -0700186
187 {TM_PRED, {INTRA_FRAME, NONE}},
188
Yue Chen968bbc72016-01-19 16:45:45 -0800189#if CONFIG_EXT_INTER
190 {NEAR_NEARESTMV, {LAST_FRAME, ALTREF_FRAME}},
191 {NEAR_NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
192 {NEAREST_NEARMV, {LAST_FRAME, ALTREF_FRAME}},
193 {NEAREST_NEARMV, {GOLDEN_FRAME, ALTREF_FRAME}},
194 {NEW_NEARESTMV, {LAST_FRAME, ALTREF_FRAME}},
195 {NEW_NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
196 {NEAREST_NEWMV, {LAST_FRAME, ALTREF_FRAME}},
197 {NEAREST_NEWMV, {GOLDEN_FRAME, ALTREF_FRAME}},
198 {NEW_NEARMV, {LAST_FRAME, ALTREF_FRAME}},
199 {NEW_NEARMV, {GOLDEN_FRAME, ALTREF_FRAME}},
200 {NEAR_NEWMV, {LAST_FRAME, ALTREF_FRAME}},
201 {NEAR_NEWMV, {GOLDEN_FRAME, ALTREF_FRAME}},
202 {NEW_NEWMV, {LAST_FRAME, ALTREF_FRAME}},
203 {NEW_NEWMV, {GOLDEN_FRAME, ALTREF_FRAME}},
204 {ZERO_ZEROMV, {LAST_FRAME, ALTREF_FRAME}},
205 {ZERO_ZEROMV, {GOLDEN_FRAME, ALTREF_FRAME}},
206#if CONFIG_EXT_REFS
207 {NEAR_NEARESTMV, {LAST2_FRAME, ALTREF_FRAME}},
208 {NEAREST_NEARMV, {LAST2_FRAME, ALTREF_FRAME}},
209 {NEW_NEARESTMV, {LAST2_FRAME, ALTREF_FRAME}},
210 {NEAREST_NEWMV, {LAST2_FRAME, ALTREF_FRAME}},
211 {NEW_NEARMV, {LAST2_FRAME, ALTREF_FRAME}},
212 {NEAR_NEWMV, {LAST2_FRAME, ALTREF_FRAME}},
213 {NEW_NEWMV, {LAST2_FRAME, ALTREF_FRAME}},
214 {ZERO_ZEROMV, {LAST2_FRAME, ALTREF_FRAME}},
215
216 {NEAR_NEARESTMV, {LAST3_FRAME, ALTREF_FRAME}},
217 {NEAREST_NEARMV, {LAST3_FRAME, ALTREF_FRAME}},
218 {NEW_NEARESTMV, {LAST3_FRAME, ALTREF_FRAME}},
219 {NEAREST_NEWMV, {LAST3_FRAME, ALTREF_FRAME}},
220 {NEW_NEARMV, {LAST3_FRAME, ALTREF_FRAME}},
221 {NEAR_NEWMV, {LAST3_FRAME, ALTREF_FRAME}},
222 {NEW_NEWMV, {LAST3_FRAME, ALTREF_FRAME}},
223 {ZERO_ZEROMV, {LAST3_FRAME, ALTREF_FRAME}},
224
225 {NEAR_NEARESTMV, {LAST4_FRAME, ALTREF_FRAME}},
226 {NEAREST_NEARMV, {LAST4_FRAME, ALTREF_FRAME}},
227 {NEW_NEARESTMV, {LAST4_FRAME, ALTREF_FRAME}},
228 {NEAREST_NEWMV, {LAST4_FRAME, ALTREF_FRAME}},
229 {NEW_NEARMV, {LAST4_FRAME, ALTREF_FRAME}},
230 {NEAR_NEWMV, {LAST4_FRAME, ALTREF_FRAME}},
231 {NEW_NEWMV, {LAST4_FRAME, ALTREF_FRAME}},
232 {ZERO_ZEROMV, {LAST4_FRAME, ALTREF_FRAME}},
233#endif // CONFIG_EXT_REFS
234#else
Jingning Han3ee6db62015-08-05 19:00:31 -0700235 {NEARMV, {LAST_FRAME, ALTREF_FRAME}},
236 {NEWMV, {LAST_FRAME, ALTREF_FRAME}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800237#if CONFIG_EXT_REFS
238 {NEARMV, {LAST2_FRAME, ALTREF_FRAME}},
239 {NEWMV, {LAST2_FRAME, ALTREF_FRAME}},
240 {NEARMV, {LAST3_FRAME, ALTREF_FRAME}},
241 {NEWMV, {LAST3_FRAME, ALTREF_FRAME}},
242 {NEARMV, {LAST4_FRAME, ALTREF_FRAME}},
243 {NEWMV, {LAST4_FRAME, ALTREF_FRAME}},
244#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700245 {NEARMV, {GOLDEN_FRAME, ALTREF_FRAME}},
246 {NEWMV, {GOLDEN_FRAME, ALTREF_FRAME}},
247
248 {ZEROMV, {LAST_FRAME, ALTREF_FRAME}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800249#if CONFIG_EXT_REFS
250 {ZEROMV, {LAST3_FRAME, ALTREF_FRAME}},
251 {ZEROMV, {LAST2_FRAME, ALTREF_FRAME}},
252 {ZEROMV, {LAST4_FRAME, ALTREF_FRAME}},
253#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700254 {ZEROMV, {GOLDEN_FRAME, ALTREF_FRAME}},
Yue Chen968bbc72016-01-19 16:45:45 -0800255#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -0700256
257 {H_PRED, {INTRA_FRAME, NONE}},
258 {V_PRED, {INTRA_FRAME, NONE}},
259 {D135_PRED, {INTRA_FRAME, NONE}},
260 {D207_PRED, {INTRA_FRAME, NONE}},
261 {D153_PRED, {INTRA_FRAME, NONE}},
262 {D63_PRED, {INTRA_FRAME, NONE}},
263 {D117_PRED, {INTRA_FRAME, NONE}},
264 {D45_PRED, {INTRA_FRAME, NONE}},
265};
266
267static const REF_DEFINITION vp10_ref_order[MAX_REFS] = {
268 {{LAST_FRAME, NONE}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800269#if CONFIG_EXT_REFS
270 {{LAST2_FRAME, NONE}},
271 {{LAST3_FRAME, NONE}},
272 {{LAST4_FRAME, NONE}},
273#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700274 {{GOLDEN_FRAME, NONE}},
275 {{ALTREF_FRAME, NONE}},
276 {{LAST_FRAME, ALTREF_FRAME}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800277#if CONFIG_EXT_REFS
278 {{LAST2_FRAME, ALTREF_FRAME}},
279 {{LAST3_FRAME, ALTREF_FRAME}},
280 {{LAST4_FRAME, ALTREF_FRAME}},
281#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700282 {{GOLDEN_FRAME, ALTREF_FRAME}},
283 {{INTRA_FRAME, NONE}},
284};
285
hui su5d011cb2015-09-15 12:44:13 -0700286static INLINE int write_uniform_cost(int n, int v) {
287 int l = get_unsigned_bits(n), m = (1 << l) - n;
288 if (l == 0)
289 return 0;
290 if (v < m)
291 return (l - 1) * vp10_cost_bit(128, 0);
292 else
293 return l * vp10_cost_bit(128, 0);
294}
295
Jingning Han3ee6db62015-08-05 19:00:31 -0700296static void swap_block_ptr(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
297 int m, int n, int min_plane, int max_plane) {
298 int i;
299
300 for (i = min_plane; i < max_plane; ++i) {
301 struct macroblock_plane *const p = &x->plane[i];
302 struct macroblockd_plane *const pd = &x->e_mbd.plane[i];
303
304 p->coeff = ctx->coeff_pbuf[i][m];
305 p->qcoeff = ctx->qcoeff_pbuf[i][m];
306 pd->dqcoeff = ctx->dqcoeff_pbuf[i][m];
307 p->eobs = ctx->eobs_pbuf[i][m];
308
309 ctx->coeff_pbuf[i][m] = ctx->coeff_pbuf[i][n];
310 ctx->qcoeff_pbuf[i][m] = ctx->qcoeff_pbuf[i][n];
311 ctx->dqcoeff_pbuf[i][m] = ctx->dqcoeff_pbuf[i][n];
312 ctx->eobs_pbuf[i][m] = ctx->eobs_pbuf[i][n];
313
314 ctx->coeff_pbuf[i][n] = p->coeff;
315 ctx->qcoeff_pbuf[i][n] = p->qcoeff;
316 ctx->dqcoeff_pbuf[i][n] = pd->dqcoeff;
317 ctx->eobs_pbuf[i][n] = p->eobs;
318 }
319}
320
Yaowu Xu26a9afc2015-08-13 09:42:27 -0700321static void model_rd_for_sb(VP10_COMP *cpi, BLOCK_SIZE bsize,
Jingning Han3ee6db62015-08-05 19:00:31 -0700322 MACROBLOCK *x, MACROBLOCKD *xd,
323 int *out_rate_sum, int64_t *out_dist_sum,
324 int *skip_txfm_sb, int64_t *skip_sse_sb) {
325 // Note our transform coeffs are 8 times an orthogonal transform.
326 // Hence quantizer step is also 8 times. To get effective quantizer
327 // we need to divide by 8 before sending to modeling function.
328 int i;
329 int64_t rate_sum = 0;
330 int64_t dist_sum = 0;
331 const int ref = xd->mi[0]->mbmi.ref_frame[0];
332 unsigned int sse;
333 unsigned int var = 0;
334 unsigned int sum_sse = 0;
335 int64_t total_sse = 0;
336 int skip_flag = 1;
337 const int shift = 6;
338 int rate;
339 int64_t dist;
340 const int dequant_shift =
341#if CONFIG_VP9_HIGHBITDEPTH
342 (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ?
343 xd->bd - 5 :
344#endif // CONFIG_VP9_HIGHBITDEPTH
345 3;
346
347 x->pred_sse[ref] = 0;
348
349 for (i = 0; i < MAX_MB_PLANE; ++i) {
350 struct macroblock_plane *const p = &x->plane[i];
351 struct macroblockd_plane *const pd = &xd->plane[i];
352 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
353 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
354 const BLOCK_SIZE unit_size = txsize_to_bsize[max_tx_size];
355 const int64_t dc_thr = p->quant_thred[0] >> shift;
356 const int64_t ac_thr = p->quant_thred[1] >> shift;
357 // The low thresholds are used to measure if the prediction errors are
358 // low enough so that we can skip the mode search.
James Zern5e16d392015-08-17 18:19:22 -0700359 const int64_t low_dc_thr = VPXMIN(50, dc_thr >> 2);
360 const int64_t low_ac_thr = VPXMIN(80, ac_thr >> 2);
Jingning Han3ee6db62015-08-05 19:00:31 -0700361 int bw = 1 << (b_width_log2_lookup[bs] - b_width_log2_lookup[unit_size]);
362 int bh = 1 << (b_height_log2_lookup[bs] - b_width_log2_lookup[unit_size]);
363 int idx, idy;
364 int lw = b_width_log2_lookup[unit_size] + 2;
365 int lh = b_height_log2_lookup[unit_size] + 2;
366
367 sum_sse = 0;
368
369 for (idy = 0; idy < bh; ++idy) {
370 for (idx = 0; idx < bw; ++idx) {
371 uint8_t *src = p->src.buf + (idy * p->src.stride << lh) + (idx << lw);
372 uint8_t *dst = pd->dst.buf + (idy * pd->dst.stride << lh) + (idx << lh);
373 int block_idx = (idy << 1) + idx;
374 int low_err_skip = 0;
375
376 var = cpi->fn_ptr[unit_size].vf(src, p->src.stride,
377 dst, pd->dst.stride, &sse);
378 x->bsse[(i << 2) + block_idx] = sse;
379 sum_sse += sse;
380
381 x->skip_txfm[(i << 2) + block_idx] = SKIP_TXFM_NONE;
382 if (!x->select_tx_size) {
383 // Check if all ac coefficients can be quantized to zero.
384 if (var < ac_thr || var == 0) {
385 x->skip_txfm[(i << 2) + block_idx] = SKIP_TXFM_AC_ONLY;
386
387 // Check if dc coefficient can be quantized to zero.
388 if (sse - var < dc_thr || sse == var) {
389 x->skip_txfm[(i << 2) + block_idx] = SKIP_TXFM_AC_DC;
390
391 if (!sse || (var < low_ac_thr && sse - var < low_dc_thr))
392 low_err_skip = 1;
393 }
394 }
395 }
396
397 if (skip_flag && !low_err_skip)
398 skip_flag = 0;
399
400 if (i == 0)
401 x->pred_sse[ref] += sse;
402 }
403 }
404
405 total_sse += sum_sse;
406
407 // Fast approximate the modelling function.
408 if (cpi->sf.simple_model_rd_from_var) {
409 int64_t rate;
410 const int64_t square_error = sum_sse;
411 int quantizer = (pd->dequant[1] >> dequant_shift);
412
413 if (quantizer < 120)
414 rate = (square_error * (280 - quantizer)) >> 8;
415 else
416 rate = 0;
417 dist = (square_error * quantizer) >> 8;
418 rate_sum += rate;
419 dist_sum += dist;
420 } else {
421 vp10_model_rd_from_var_lapndz(sum_sse, num_pels_log2_lookup[bs],
422 pd->dequant[1] >> dequant_shift,
423 &rate, &dist);
424 rate_sum += rate;
425 dist_sum += dist;
426 }
427 }
428
429 *skip_txfm_sb = skip_flag;
430 *skip_sse_sb = total_sse << 4;
431 *out_rate_sum = (int)rate_sum;
432 *out_dist_sum = dist_sum << 4;
433}
434
435int64_t vp10_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff,
436 intptr_t block_size, int64_t *ssz) {
437 int i;
438 int64_t error = 0, sqcoeff = 0;
439
440 for (i = 0; i < block_size; i++) {
441 const int diff = coeff[i] - dqcoeff[i];
442 error += diff * diff;
443 sqcoeff += coeff[i] * coeff[i];
444 }
445
446 *ssz = sqcoeff;
447 return error;
448}
449
450int64_t vp10_block_error_fp_c(const int16_t *coeff, const int16_t *dqcoeff,
451 int block_size) {
452 int i;
453 int64_t error = 0;
454
455 for (i = 0; i < block_size; i++) {
456 const int diff = coeff[i] - dqcoeff[i];
457 error += diff * diff;
458 }
459
460 return error;
461}
462
463#if CONFIG_VP9_HIGHBITDEPTH
464int64_t vp10_highbd_block_error_c(const tran_low_t *coeff,
465 const tran_low_t *dqcoeff,
466 intptr_t block_size,
467 int64_t *ssz, int bd) {
468 int i;
469 int64_t error = 0, sqcoeff = 0;
470 int shift = 2 * (bd - 8);
471 int rounding = shift > 0 ? 1 << (shift - 1) : 0;
472
473 for (i = 0; i < block_size; i++) {
474 const int64_t diff = coeff[i] - dqcoeff[i];
475 error += diff * diff;
476 sqcoeff += (int64_t)coeff[i] * (int64_t)coeff[i];
477 }
478 assert(error >= 0 && sqcoeff >= 0);
479 error = (error + rounding) >> shift;
480 sqcoeff = (sqcoeff + rounding) >> shift;
481
482 *ssz = sqcoeff;
483 return error;
484}
485#endif // CONFIG_VP9_HIGHBITDEPTH
486
487/* The trailing '0' is a terminator which is used inside cost_coeffs() to
488 * decide whether to include cost of a trailing EOB node or not (i.e. we
489 * can skip this if the last coefficient in this transform block, e.g. the
490 * 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block,
491 * were non-zero). */
492static const int16_t band_counts[TX_SIZES][8] = {
493 { 1, 2, 3, 4, 3, 16 - 13, 0 },
494 { 1, 2, 3, 4, 11, 64 - 21, 0 },
495 { 1, 2, 3, 4, 11, 256 - 21, 0 },
496 { 1, 2, 3, 4, 11, 1024 - 21, 0 },
497};
498static int cost_coeffs(MACROBLOCK *x,
499 int plane, int block,
Jingning Han2cdc1272015-10-09 09:57:42 -0700500#if CONFIG_VAR_TX
501 int coeff_ctx,
502#else
Jingning Han3ee6db62015-08-05 19:00:31 -0700503 ENTROPY_CONTEXT *A, ENTROPY_CONTEXT *L,
Jingning Han2cdc1272015-10-09 09:57:42 -0700504#endif
Jingning Han3ee6db62015-08-05 19:00:31 -0700505 TX_SIZE tx_size,
506 const int16_t *scan, const int16_t *nb,
507 int use_fast_coef_costing) {
508 MACROBLOCKD *const xd = &x->e_mbd;
509 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
510 const struct macroblock_plane *p = &x->plane[plane];
511 const struct macroblockd_plane *pd = &xd->plane[plane];
512 const PLANE_TYPE type = pd->plane_type;
513 const int16_t *band_count = &band_counts[tx_size][1];
514 const int eob = p->eobs[block];
515 const tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
516 unsigned int (*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
517 x->token_costs[tx_size][type][is_inter_block(mbmi)];
518 uint8_t token_cache[32 * 32];
Jingning Han2cdc1272015-10-09 09:57:42 -0700519#if CONFIG_VAR_TX
520 int pt = coeff_ctx;
521#else
Jingning Han3ee6db62015-08-05 19:00:31 -0700522 int pt = combine_entropy_contexts(*A, *L);
Jingning Han2cdc1272015-10-09 09:57:42 -0700523#endif
Jingning Han3ee6db62015-08-05 19:00:31 -0700524 int c, cost;
525#if CONFIG_VP9_HIGHBITDEPTH
526 const int16_t *cat6_high_cost = vp10_get_high_cost_table(xd->bd);
527#else
528 const int16_t *cat6_high_cost = vp10_get_high_cost_table(8);
529#endif
530
Debargha Mukherjee3787b172015-11-19 16:51:16 -0800531#if !CONFIG_VAR_TX && !CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -0700532 // Check for consistency of tx_size with mode info
533 assert(type == PLANE_TYPE_Y ? mbmi->tx_size == tx_size
534 : get_uv_tx_size(mbmi, pd) == tx_size);
Debargha Mukherjee3787b172015-11-19 16:51:16 -0800535#endif // !CONFIG_VAR_TX && !CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -0700536
537 if (eob == 0) {
538 // single eob token
539 cost = token_costs[0][0][pt][EOB_TOKEN];
540 c = 0;
541 } else {
542 int band_left = *band_count++;
543
544 // dc token
545 int v = qcoeff[0];
546 int16_t prev_t;
547 EXTRABIT e;
548 vp10_get_token_extra(v, &prev_t, &e);
549 cost = (*token_costs)[0][pt][prev_t] +
550 vp10_get_cost(prev_t, e, cat6_high_cost);
551
552 token_cache[0] = vp10_pt_energy_class[prev_t];
553 ++token_costs;
554
555 // ac tokens
556 for (c = 1; c < eob; c++) {
557 const int rc = scan[c];
558 int16_t t;
559
560 v = qcoeff[rc];
561 vp10_get_token_extra(v, &t, &e);
562 if (use_fast_coef_costing) {
563 cost += (*token_costs)[!prev_t][!prev_t][t] +
564 vp10_get_cost(t, e, cat6_high_cost);
565 } else {
566 pt = get_coef_context(nb, token_cache, c);
567 cost += (*token_costs)[!prev_t][pt][t] +
568 vp10_get_cost(t, e, cat6_high_cost);
569 token_cache[rc] = vp10_pt_energy_class[t];
570 }
571 prev_t = t;
572 if (!--band_left) {
573 band_left = *band_count++;
574 ++token_costs;
575 }
576 }
577
578 // eob token
579 if (band_left) {
580 if (use_fast_coef_costing) {
581 cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
582 } else {
583 pt = get_coef_context(nb, token_cache, c);
584 cost += (*token_costs)[0][pt][EOB_TOKEN];
585 }
586 }
587 }
588
Jingning Han2cdc1272015-10-09 09:57:42 -0700589#if !CONFIG_VAR_TX
Jingning Han3ee6db62015-08-05 19:00:31 -0700590 // is eob first coefficient;
591 *A = *L = (c > 0);
Jingning Han2cdc1272015-10-09 09:57:42 -0700592#endif
Jingning Han3ee6db62015-08-05 19:00:31 -0700593
594 return cost;
595}
596
597static void dist_block(MACROBLOCK *x, int plane, int block, TX_SIZE tx_size,
598 int64_t *out_dist, int64_t *out_sse) {
599 const int ss_txfrm_size = tx_size << 1;
600 MACROBLOCKD* const xd = &x->e_mbd;
601 const struct macroblock_plane *const p = &x->plane[plane];
602 const struct macroblockd_plane *const pd = &xd->plane[plane];
603 int64_t this_sse;
604 int shift = tx_size == TX_32X32 ? 0 : 2;
605 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
606 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
607#if CONFIG_VP9_HIGHBITDEPTH
608 const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
609 *out_dist = vp10_highbd_block_error(coeff, dqcoeff, 16 << ss_txfrm_size,
610 &this_sse, bd) >> shift;
611#else
612 *out_dist = vp10_block_error(coeff, dqcoeff, 16 << ss_txfrm_size,
613 &this_sse) >> shift;
614#endif // CONFIG_VP9_HIGHBITDEPTH
615 *out_sse = this_sse >> shift;
Jingning Han3ee6db62015-08-05 19:00:31 -0700616}
617
Jingning Hanebc48ef2015-10-07 11:43:48 -0700618static int rate_block(int plane, int block, int blk_row, int blk_col,
Jingning Han3ee6db62015-08-05 19:00:31 -0700619 TX_SIZE tx_size, struct rdcost_block_args* args) {
Jingning Han2cdc1272015-10-09 09:57:42 -0700620#if CONFIG_VAR_TX
621 int coeff_ctx = combine_entropy_contexts(*(args->t_above + blk_col),
622 *(args->t_left + blk_row));
623 int coeff_cost = cost_coeffs(args->x, plane, block, coeff_ctx,
624 tx_size, args->so->scan, args->so->neighbors,
625 args->use_fast_coef_costing);
626 const struct macroblock_plane *p = &args->x->plane[plane];
627 *(args->t_above + blk_col) = !(p->eobs[block] == 0);
628 *(args->t_left + blk_row) = !(p->eobs[block] == 0);
629 return coeff_cost;
630#else
631 return cost_coeffs(args->x, plane, block,
632 args->t_above + blk_col,
633 args->t_left + blk_row,
634 tx_size, args->so->scan, args->so->neighbors,
Jingning Han3ee6db62015-08-05 19:00:31 -0700635 args->use_fast_coef_costing);
Jingning Han2cdc1272015-10-09 09:57:42 -0700636#endif
Jingning Han3ee6db62015-08-05 19:00:31 -0700637}
638
Jingning Hanebc48ef2015-10-07 11:43:48 -0700639static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
640 BLOCK_SIZE plane_bsize,
Jingning Han3ee6db62015-08-05 19:00:31 -0700641 TX_SIZE tx_size, void *arg) {
642 struct rdcost_block_args *args = arg;
643 MACROBLOCK *const x = args->x;
644 MACROBLOCKD *const xd = &x->e_mbd;
645 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
646 int64_t rd1, rd2, rd;
647 int rate;
648 int64_t dist;
649 int64_t sse;
650
651 if (args->exit_early)
652 return;
653
654 if (!is_inter_block(mbmi)) {
Jingning Han71c15602015-10-13 12:40:39 -0700655#if CONFIG_VAR_TX
656 struct encode_b_args arg = {x, NULL, &mbmi->skip};
hui suaf084fb2015-11-17 10:40:25 -0800657#if CONFIG_VP9_HIGHBITDEPTH
658 vp10_encode_block_intra(plane, block, blk_row, blk_col,
659 plane_bsize, tx_size, &arg);
660 dist_block(x, plane, block, tx_size, &dist, &sse);
661#else
Jingning Han71c15602015-10-13 12:40:39 -0700662 uint8_t *dst, *src;
663 int src_stride = x->plane[plane].src.stride;
664 int dst_stride = xd->plane[plane].dst.stride;
665 unsigned int tmp_sse;
666 PREDICTION_MODE mode = (plane == 0) ?
Jingning Han94266f42015-10-16 18:21:11 -0700667 get_y_mode(xd->mi[0], block) : mbmi->uv_mode;
Jingning Han71c15602015-10-13 12:40:39 -0700668
Jingning Han71c15602015-10-13 12:40:39 -0700669 src = &x->plane[plane].src.buf[4 * (blk_row * src_stride + blk_col)];
670 dst = &xd->plane[plane].dst.buf[4 * (blk_row * dst_stride + blk_col)];
671 vp10_predict_intra_block(xd, b_width_log2_lookup[plane_bsize],
672 b_height_log2_lookup[plane_bsize],
673 tx_size, mode, dst, dst_stride,
674 dst, dst_stride, blk_col, blk_row, plane);
675 args->cpi->fn_ptr[txsize_to_bsize[tx_size]].vf(src, src_stride,
676 dst, dst_stride, &tmp_sse);
677 sse = (int64_t)tmp_sse * 16;
678 vp10_encode_block_intra(plane, block, blk_row, blk_col,
679 plane_bsize, tx_size, &arg);
680 args->cpi->fn_ptr[txsize_to_bsize[tx_size]].vf(src, src_stride,
681 dst, dst_stride, &tmp_sse);
682 dist = (int64_t)tmp_sse * 16;
683#endif // CONFIG_VP9_HIGHBITDEPTH
684#else
Jingning Han3ee6db62015-08-05 19:00:31 -0700685 struct encode_b_args arg = {x, NULL, &mbmi->skip};
Jingning Hanebc48ef2015-10-07 11:43:48 -0700686 vp10_encode_block_intra(plane, block, blk_row, blk_col,
687 plane_bsize, tx_size, &arg);
Jingning Han3ee6db62015-08-05 19:00:31 -0700688 dist_block(x, plane, block, tx_size, &dist, &sse);
Jingning Han71c15602015-10-13 12:40:39 -0700689#endif
Jingning Han3ee6db62015-08-05 19:00:31 -0700690 } else if (max_txsize_lookup[plane_bsize] == tx_size) {
691 if (x->skip_txfm[(plane << 2) + (block >> (tx_size << 1))] ==
692 SKIP_TXFM_NONE) {
693 // full forward transform and quantization
Jingning Hancaeb10b2015-10-22 17:25:00 -0700694 vp10_xform_quant(x, plane, block, blk_row, blk_col,
Angie Chiang88cae8b2015-11-25 13:07:13 -0800695 plane_bsize, tx_size, VP10_XFORM_QUANT_B);
Jingning Han3ee6db62015-08-05 19:00:31 -0700696 dist_block(x, plane, block, tx_size, &dist, &sse);
697 } else if (x->skip_txfm[(plane << 2) + (block >> (tx_size << 1))] ==
698 SKIP_TXFM_AC_ONLY) {
699 // compute DC coefficient
700 tran_low_t *const coeff = BLOCK_OFFSET(x->plane[plane].coeff, block);
701 tran_low_t *const dqcoeff = BLOCK_OFFSET(xd->plane[plane].dqcoeff, block);
Angie Chiang88cae8b2015-11-25 13:07:13 -0800702 vp10_xform_quant(x, plane, block, blk_row, blk_col,
703 plane_bsize, tx_size, VP10_XFORM_QUANT_DC);
Jingning Han3ee6db62015-08-05 19:00:31 -0700704 sse = x->bsse[(plane << 2) + (block >> (tx_size << 1))] << 4;
705 dist = sse;
706 if (x->plane[plane].eobs[block]) {
707 const int64_t orig_sse = (int64_t)coeff[0] * coeff[0];
708 const int64_t resd_sse = coeff[0] - dqcoeff[0];
709 int64_t dc_correct = orig_sse - resd_sse * resd_sse;
710#if CONFIG_VP9_HIGHBITDEPTH
711 dc_correct >>= ((xd->bd - 8) * 2);
712#endif
713 if (tx_size != TX_32X32)
714 dc_correct >>= 2;
715
James Zern5e16d392015-08-17 18:19:22 -0700716 dist = VPXMAX(0, sse - dc_correct);
Jingning Han3ee6db62015-08-05 19:00:31 -0700717 }
718 } else {
719 // SKIP_TXFM_AC_DC
720 // skip forward transform
721 x->plane[plane].eobs[block] = 0;
722 sse = x->bsse[(plane << 2) + (block >> (tx_size << 1))] << 4;
723 dist = sse;
724 }
725 } else {
726 // full forward transform and quantization
Angie Chiang88cae8b2015-11-25 13:07:13 -0800727 vp10_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
728 VP10_XFORM_QUANT_B);
Jingning Han3ee6db62015-08-05 19:00:31 -0700729 dist_block(x, plane, block, tx_size, &dist, &sse);
730 }
731
732 rd = RDCOST(x->rdmult, x->rddiv, 0, dist);
733 if (args->this_rd + rd > args->best_rd) {
734 args->exit_early = 1;
735 return;
736 }
737
Jingning Hanebc48ef2015-10-07 11:43:48 -0700738 rate = rate_block(plane, block, blk_row, blk_col, tx_size, args);
Jingning Han3ee6db62015-08-05 19:00:31 -0700739 rd1 = RDCOST(x->rdmult, x->rddiv, rate, dist);
740 rd2 = RDCOST(x->rdmult, x->rddiv, 0, sse);
741
742 // TODO(jingning): temporarily enabled only for luma component
James Zern5e16d392015-08-17 18:19:22 -0700743 rd = VPXMIN(rd1, rd2);
Jingning Han3ee6db62015-08-05 19:00:31 -0700744 if (plane == 0)
745 x->zcoeff_blk[tx_size][block] = !x->plane[plane].eobs[block] ||
Ronald S. Bultje60c58b52015-10-12 17:54:25 -0400746 (rd1 > rd2 && !xd->lossless[mbmi->segment_id]);
Jingning Han3ee6db62015-08-05 19:00:31 -0700747
748 args->this_rate += rate;
749 args->this_dist += dist;
750 args->this_sse += sse;
751 args->this_rd += rd;
752
753 if (args->this_rd > args->best_rd) {
754 args->exit_early = 1;
755 return;
756 }
757
758 args->skippable &= !x->plane[plane].eobs[block];
759}
760
761static void txfm_rd_in_plane(MACROBLOCK *x,
Jingning Han71c15602015-10-13 12:40:39 -0700762#if CONFIG_VAR_TX
763 const VP10_COMP *cpi,
764#endif
Jingning Han3ee6db62015-08-05 19:00:31 -0700765 int *rate, int64_t *distortion,
766 int *skippable, int64_t *sse,
767 int64_t ref_best_rd, int plane,
768 BLOCK_SIZE bsize, TX_SIZE tx_size,
769 int use_fast_coef_casting) {
770 MACROBLOCKD *const xd = &x->e_mbd;
771 const struct macroblockd_plane *const pd = &xd->plane[plane];
hui su5eed74e2015-08-18 16:57:07 -0700772 TX_TYPE tx_type;
Jingning Han3ee6db62015-08-05 19:00:31 -0700773 struct rdcost_block_args args;
774 vp10_zero(args);
775 args.x = x;
Jingning Han71c15602015-10-13 12:40:39 -0700776#if CONFIG_VAR_TX
777 args.cpi = cpi;
778#endif
Jingning Han3ee6db62015-08-05 19:00:31 -0700779 args.best_rd = ref_best_rd;
780 args.use_fast_coef_costing = use_fast_coef_casting;
781 args.skippable = 1;
782
783 if (plane == 0)
784 xd->mi[0]->mbmi.tx_size = tx_size;
785
786 vp10_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
787
hui sub3cc3a02015-08-24 14:37:54 -0700788 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -0700789 args.so = get_scan(tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Jingning Han3ee6db62015-08-05 19:00:31 -0700790
791 vp10_foreach_transformed_block_in_plane(xd, bsize, plane,
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -0700792 block_rd_txfm, &args);
Jingning Han3ee6db62015-08-05 19:00:31 -0700793 if (args.exit_early) {
794 *rate = INT_MAX;
795 *distortion = INT64_MAX;
796 *sse = INT64_MAX;
797 *skippable = 0;
798 } else {
799 *distortion = args.this_dist;
800 *rate = args.this_rate;
801 *sse = args.this_sse;
802 *skippable = args.skippable;
803 }
804}
805
Debargha Mukherjee3787b172015-11-19 16:51:16 -0800806#if CONFIG_SUPERTX
807void vp10_txfm_rd_in_plane_supertx(MACROBLOCK *x,
Debargha Mukherjee3787b172015-11-19 16:51:16 -0800808 int *rate, int64_t *distortion,
809 int *skippable, int64_t *sse,
810 int64_t ref_best_rd, int plane,
811 BLOCK_SIZE bsize, TX_SIZE tx_size,
812 int use_fast_coef_casting) {
813 MACROBLOCKD *const xd = &x->e_mbd;
814 const struct macroblockd_plane *const pd = &xd->plane[plane];
815 struct rdcost_block_args args;
816 TX_TYPE tx_type;
817
818 vp10_zero(args);
819 args.x = x;
Debargha Mukherjee3787b172015-11-19 16:51:16 -0800820 args.best_rd = ref_best_rd;
821 args.use_fast_coef_costing = use_fast_coef_casting;
822
823 if (plane == 0)
824 xd->mi[0]->mbmi.tx_size = tx_size;
825
826 vp10_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
827
828 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
829 args.so = get_scan(tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
830
831 block_rd_txfm(plane, 0, 0, 0, get_plane_block_size(bsize, pd),
832 tx_size, &args);
833
834 if (args.exit_early) {
835 *rate = INT_MAX;
836 *distortion = INT64_MAX;
837 *sse = INT64_MAX;
838 *skippable = 0;
839 } else {
840 *distortion = args.this_dist;
841 *rate = args.this_rate;
842 *sse = args.this_sse;
843 *skippable = !x->plane[plane].eobs[0];
844 }
845}
846#endif // CONFIG_SUPERTX
847
Yaowu Xu26a9afc2015-08-13 09:42:27 -0700848static void choose_largest_tx_size(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -0700849 int *rate, int64_t *distortion,
850 int *skip, int64_t *sse,
851 int64_t ref_best_rd,
852 BLOCK_SIZE bs) {
853 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
Yaowu Xufc7cbd12015-08-13 09:36:53 -0700854 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -0700855 const TX_SIZE largest_tx_size = tx_mode_to_biggest_tx_size[cm->tx_mode];
856 MACROBLOCKD *const xd = &x->e_mbd;
857 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700858 TX_TYPE tx_type, best_tx_type = DCT_DCT;
hui su6c81e372015-09-29 12:09:15 -0700859 int r, s;
860 int64_t d, psse, this_rd, best_rd = INT64_MAX;
861 vpx_prob skip_prob = vp10_get_skip_prob(cm, xd);
862 int s0 = vp10_cost_bit(skip_prob, 0);
863 int s1 = vp10_cost_bit(skip_prob, 1);
Yaowu Xu0367f322016-01-11 10:27:35 -0800864#if CONFIG_EXT_TX
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700865 int ext_tx_set;
hui su6c81e372015-09-29 12:09:15 -0700866#endif // CONFIG_EXT_TX
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -0800867 const int is_inter = is_inter_block(mbmi);
Jingning Han3ee6db62015-08-05 19:00:31 -0700868
James Zern5e16d392015-08-17 18:19:22 -0700869 mbmi->tx_size = VPXMIN(max_tx_size, largest_tx_size);
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700870
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -0700871#if CONFIG_EXT_TX
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700872 ext_tx_set = get_ext_tx_set(mbmi->tx_size, bs, is_inter);
873
Debargha Mukherjee8d69a6e2016-01-06 14:36:13 -0800874 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1 &&
Yaowu Xu5a27b3b2015-10-22 12:18:52 -0700875 !xd->lossless[mbmi->segment_id]) {
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700876 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
877 if (is_inter) {
878 if (!ext_tx_used_inter[ext_tx_set][tx_type])
879 continue;
880 } else {
hui sud894d342015-11-18 11:24:26 -0800881 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
Yaowu Xu0367f322016-01-11 10:27:35 -0800882 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode])
hui sud894d342015-11-18 11:24:26 -0800883 continue;
884 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700885 if (!ext_tx_used_intra[ext_tx_set][tx_type])
886 continue;
887 }
888
889 mbmi->tx_type = tx_type;
890 if (ext_tx_set == 1 &&
891 mbmi->tx_type >= DST_ADST && mbmi->tx_type < IDTX &&
hui su4f16f112015-10-02 10:45:27 -0700892 best_tx_type == DCT_DCT) {
893 tx_type = IDTX - 1;
hui su3fa01292015-09-28 18:38:00 -0700894 continue;
895 }
hui su6c81e372015-09-29 12:09:15 -0700896
Jingning Han71c15602015-10-13 12:40:39 -0700897 txfm_rd_in_plane(x,
898#if CONFIG_VAR_TX
899 cpi,
900#endif
901 &r, &d, &s,
hui su6c81e372015-09-29 12:09:15 -0700902 &psse, ref_best_rd, 0, bs, mbmi->tx_size,
903 cpi->sf.use_fast_coef_costing);
904
905 if (r == INT_MAX)
906 continue;
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700907 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1) {
908 if (is_inter) {
909 if (ext_tx_set > 0)
910 r += cpi->inter_tx_type_costs[ext_tx_set]
911 [mbmi->tx_size][mbmi->tx_type];
912 } else {
hui sud894d342015-11-18 11:24:26 -0800913 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700914 r += cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size]
915 [mbmi->mode][mbmi->tx_type];
916 }
hui su3fa01292015-09-28 18:38:00 -0700917 }
hui su6c81e372015-09-29 12:09:15 -0700918
919 if (s)
920 this_rd = RDCOST(x->rdmult, x->rddiv, s1, psse);
921 else
922 this_rd = RDCOST(x->rdmult, x->rddiv, r + s0, d);
Yaowu Xu5a27b3b2015-10-22 12:18:52 -0700923 if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] && !s)
hui su6c81e372015-09-29 12:09:15 -0700924 this_rd = VPXMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, psse));
925
hui su4f16f112015-10-02 10:45:27 -0700926 if (this_rd < ((best_tx_type == DCT_DCT) ? ext_tx_th : 1) * best_rd) {
hui su6c81e372015-09-29 12:09:15 -0700927 best_rd = this_rd;
hui su4f16f112015-10-02 10:45:27 -0700928 best_tx_type = mbmi->tx_type;
hui su6c81e372015-09-29 12:09:15 -0700929 }
930 }
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -0700931 }
hui su6c81e372015-09-29 12:09:15 -0700932
Yaowu Xu0367f322016-01-11 10:27:35 -0800933#else // CONFIG_EXT_TX
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -0800934 if (mbmi->tx_size < TX_32X32 &&
935 !xd->lossless[mbmi->segment_id]) {
936 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
937 mbmi->tx_type = tx_type;
Yaowu Xu0367f322016-01-11 10:27:35 -0800938 txfm_rd_in_plane(x,
939#if CONFIG_VAR_TX
940 cpi,
941#endif
942 &r, &d, &s,
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -0800943 &psse, ref_best_rd, 0, bs, mbmi->tx_size,
944 cpi->sf.use_fast_coef_costing);
945 if (r == INT_MAX)
946 continue;
947 if (is_inter)
948 r += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
949 else
950 r += cpi->intra_tx_type_costs[mbmi->tx_size]
951 [intra_mode_to_tx_type_context[mbmi->mode]]
952 [mbmi->tx_type];
953 if (s)
954 this_rd = RDCOST(x->rdmult, x->rddiv, s1, psse);
955 else
956 this_rd = RDCOST(x->rdmult, x->rddiv, r + s0, d);
957 if (is_inter && !xd->lossless[mbmi->segment_id] && !s)
958 this_rd = VPXMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, psse));
959
960 if (this_rd < ((best_tx_type == DCT_DCT) ? ext_tx_th : 1) * best_rd) {
961 best_rd = this_rd;
962 best_tx_type = mbmi->tx_type;
963 }
964 }
965 }
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -0700966#endif // CONFIG_EXT_TX
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -0800967 mbmi->tx_type = best_tx_type;
Jingning Han3ee6db62015-08-05 19:00:31 -0700968
Jingning Han71c15602015-10-13 12:40:39 -0700969 txfm_rd_in_plane(x,
970#if CONFIG_VAR_TX
971 cpi,
972#endif
973 rate, distortion, skip,
Jingning Han3ee6db62015-08-05 19:00:31 -0700974 sse, ref_best_rd, 0, bs,
975 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -0700976
977#if CONFIG_EXT_TX
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700978 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1 &&
Yaowu Xu5a27b3b2015-10-22 12:18:52 -0700979 !xd->lossless[mbmi->segment_id] && *rate != INT_MAX) {
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700980 int ext_tx_set = get_ext_tx_set(mbmi->tx_size, bs, is_inter);
hui sud894d342015-11-18 11:24:26 -0800981 if (is_inter) {
982 if (ext_tx_set > 0)
983 *rate += cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size]
Debargha Mukherjee8d69a6e2016-01-06 14:36:13 -0800984 [mbmi->tx_type];
hui sud894d342015-11-18 11:24:26 -0800985 } else {
986 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
987 *rate +=
988 cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size]
Debargha Mukherjee8d69a6e2016-01-06 14:36:13 -0800989 [mbmi->mode][mbmi->tx_type];
hui sud894d342015-11-18 11:24:26 -0800990 }
hui su3fa01292015-09-28 18:38:00 -0700991 }
Yaowu Xu0367f322016-01-11 10:27:35 -0800992#else
Debargha Mukherjeea0900fd2016-01-08 12:01:51 -0800993 if (mbmi->tx_size < TX_32X32 && !xd->lossless[mbmi->segment_id] &&
994 *rate != INT_MAX) {
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -0800995 if (is_inter)
996 *rate += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
997 else
998 *rate += cpi->intra_tx_type_costs[mbmi->tx_size]
999 [intra_mode_to_tx_type_context[mbmi->mode]]
1000 [mbmi->tx_type];
1001 }
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001002#endif // CONFIG_EXT_TX
Jingning Han3ee6db62015-08-05 19:00:31 -07001003}
1004
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001005static void choose_smallest_tx_size(VP10_COMP *cpi, MACROBLOCK *x,
1006 int *rate, int64_t *distortion,
1007 int *skip, int64_t *sse,
1008 int64_t ref_best_rd,
1009 BLOCK_SIZE bs) {
1010 MACROBLOCKD *const xd = &x->e_mbd;
1011 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1012
1013 mbmi->tx_size = TX_4X4;
Debargha Mukherjee4e406f72016-01-22 03:29:39 -08001014 mbmi->tx_type = DCT_DCT;
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001015
Jingning Han71c15602015-10-13 12:40:39 -07001016 txfm_rd_in_plane(x,
1017#if CONFIG_VAR_TX
1018 cpi,
1019#endif
1020 rate, distortion, skip,
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001021 sse, ref_best_rd, 0, bs,
1022 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
1023}
1024
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08001025static INLINE int vp10_cost_tx_size(TX_SIZE tx_size, TX_SIZE max_tx_size,
1026 const vpx_prob *tx_probs) {
1027 int m;
1028 int r_tx_size = 0;
1029
1030 for (m = 0; m <= tx_size - (tx_size == max_tx_size); ++m) {
1031 if (m == tx_size)
1032 r_tx_size += vp10_cost_zero(tx_probs[m]);
1033 else
1034 r_tx_size += vp10_cost_one(tx_probs[m]);
1035 }
1036
1037 return r_tx_size;
1038}
1039
Yaowu Xu26a9afc2015-08-13 09:42:27 -07001040static void choose_tx_size_from_rd(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07001041 int *rate,
1042 int64_t *distortion,
1043 int *skip,
1044 int64_t *psse,
1045 int64_t ref_best_rd,
1046 BLOCK_SIZE bs) {
1047 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
Yaowu Xufc7cbd12015-08-13 09:36:53 -07001048 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07001049 MACROBLOCKD *const xd = &x->e_mbd;
1050 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1051 vpx_prob skip_prob = vp10_get_skip_prob(cm, xd);
hui su38debe52015-09-20 19:18:00 -07001052 int r, s;
1053 int64_t d, sse;
1054 int64_t rd = INT64_MAX;
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08001055 int n;
Jingning Han3ee6db62015-08-05 19:00:31 -07001056 int s0, s1;
hui su38debe52015-09-20 19:18:00 -07001057 int64_t best_rd = INT64_MAX, last_rd = INT64_MAX;
Jingning Han3ee6db62015-08-05 19:00:31 -07001058 TX_SIZE best_tx = max_tx_size;
1059 int start_tx, end_tx;
hui su38debe52015-09-20 19:18:00 -07001060 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001061 TX_TYPE tx_type, best_tx_type = DCT_DCT;
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001062 const int is_inter = is_inter_block(mbmi);
Yaowu Xu0367f322016-01-11 10:27:35 -08001063#if CONFIG_EXT_TX
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001064 int ext_tx_set;
hui su07154b02015-09-22 10:34:18 -07001065#endif // CONFIG_EXT_TX
1066
Jingning Han3ee6db62015-08-05 19:00:31 -07001067 const vpx_prob *tx_probs = get_tx_probs2(max_tx_size, xd, &cm->fc->tx_probs);
1068 assert(skip_prob > 0);
1069 s0 = vp10_cost_bit(skip_prob, 0);
1070 s1 = vp10_cost_bit(skip_prob, 1);
1071
hui su38debe52015-09-20 19:18:00 -07001072 if (tx_select) {
Jingning Han3ee6db62015-08-05 19:00:31 -07001073 start_tx = max_tx_size;
1074 end_tx = 0;
1075 } else {
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001076 const TX_SIZE chosen_tx_size =
1077 VPXMIN(max_tx_size, tx_mode_to_biggest_tx_size[cm->tx_mode]);
Jingning Han3ee6db62015-08-05 19:00:31 -07001078 start_tx = chosen_tx_size;
1079 end_tx = chosen_tx_size;
1080 }
1081
hui su38debe52015-09-20 19:18:00 -07001082 *distortion = INT64_MAX;
1083 *rate = INT_MAX;
1084 *skip = 0;
1085 *psse = INT64_MAX;
1086
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001087 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001088 last_rd = INT64_MAX;
hui su07154b02015-09-22 10:34:18 -07001089 for (n = start_tx; n >= end_tx; --n) {
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08001090 const int r_tx_size = vp10_cost_tx_size(n, max_tx_size, tx_probs);
hui su07154b02015-09-22 10:34:18 -07001091
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001092#if CONFIG_EXT_TX
1093 ext_tx_set = get_ext_tx_set(n, bs, is_inter);
1094 if (is_inter) {
1095 if (!ext_tx_used_inter[ext_tx_set][tx_type])
1096 continue;
1097 } else {
hui sud894d342015-11-18 11:24:26 -08001098 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
Yaowu Xu0367f322016-01-11 10:27:35 -08001099 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode])
hui sud894d342015-11-18 11:24:26 -08001100 continue;
1101 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001102 if (!ext_tx_used_intra[ext_tx_set][tx_type])
1103 continue;
1104 }
1105 mbmi->tx_type = tx_type;
1106 if (ext_tx_set == 1 &&
1107 mbmi->tx_type >= DST_ADST && mbmi->tx_type < IDTX &&
1108 best_tx_type == DCT_DCT) {
1109 tx_type = IDTX - 1;
1110 break;
1111 }
Jingning Han71c15602015-10-13 12:40:39 -07001112 txfm_rd_in_plane(x,
1113#if CONFIG_VAR_TX
1114 cpi,
1115#endif
1116 &r, &d, &s,
hui su07154b02015-09-22 10:34:18 -07001117 &sse, ref_best_rd, 0, bs, n,
1118 cpi->sf.use_fast_coef_costing);
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001119 if (get_ext_tx_types(n, bs, is_inter) > 1 &&
1120 !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1121 r != INT_MAX) {
1122 if (is_inter) {
1123 if (ext_tx_set > 0)
1124 r += cpi->inter_tx_type_costs[ext_tx_set]
1125 [mbmi->tx_size][mbmi->tx_type];
1126 } else {
hui sud894d342015-11-18 11:24:26 -08001127 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001128 r += cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size]
1129 [mbmi->mode][mbmi->tx_type];
1130 }
hui su3fa01292015-09-28 18:38:00 -07001131 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001132#else // CONFIG_EXT_TX
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001133 if (n >= TX_32X32 && tx_type != DCT_DCT) {
1134 continue;
1135 }
1136 mbmi->tx_type = tx_type;
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001137 txfm_rd_in_plane(x,
1138#if CONFIG_VAR_TX
1139 cpi,
1140#endif
1141 &r, &d, &s,
1142 &sse, ref_best_rd, 0, bs, n,
1143 cpi->sf.use_fast_coef_costing);
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001144 if (n < TX_32X32 &&
1145 !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1146 r != INT_MAX) {
1147 if (is_inter)
1148 r += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
1149 else
1150 r += cpi->intra_tx_type_costs[mbmi->tx_size]
1151 [intra_mode_to_tx_type_context[mbmi->mode]]
1152 [mbmi->tx_type];
1153 }
hui su07154b02015-09-22 10:34:18 -07001154#endif // CONFIG_EXT_TX
1155
1156 if (r == INT_MAX)
1157 continue;
1158
hui su07154b02015-09-22 10:34:18 -07001159 if (s) {
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001160 if (is_inter) {
hui su07154b02015-09-22 10:34:18 -07001161 rd = RDCOST(x->rdmult, x->rddiv, s1, sse);
hui su07154b02015-09-22 10:34:18 -07001162 } else {
1163 rd = RDCOST(x->rdmult, x->rddiv, s1 + r_tx_size * tx_select, sse);
1164 }
1165 } else {
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001166 rd = RDCOST(x->rdmult, x->rddiv, r + s0 + r_tx_size * tx_select, d);
hui su07154b02015-09-22 10:34:18 -07001167 }
1168
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001169 if (tx_select && !(s && is_inter))
1170 r += r_tx_size;
1171
1172 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] && !s)
hui su07154b02015-09-22 10:34:18 -07001173 rd = VPXMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, sse));
1174
1175 // Early termination in transform size search.
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001176 if (cpi->sf.tx_size_search_breakout &&
1177 (rd == INT64_MAX ||
Jingning Han35b3bd32015-11-10 16:02:33 -08001178 (s == 1 && tx_type != DCT_DCT && n < start_tx) ||
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001179 (n < (int) max_tx_size && rd > last_rd)))
hui su07154b02015-09-22 10:34:18 -07001180 break;
1181
1182 last_rd = rd;
hui su4f16f112015-10-02 10:45:27 -07001183 if (rd <
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001184 (is_inter && best_tx_type == DCT_DCT ? ext_tx_th : 1) *
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001185 best_rd) {
hui su07154b02015-09-22 10:34:18 -07001186 best_tx = n;
1187 best_rd = rd;
1188 *distortion = d;
1189 *rate = r;
1190 *skip = s;
1191 *psse = sse;
hui su4f16f112015-10-02 10:45:27 -07001192 best_tx_type = mbmi->tx_type;
hui su07154b02015-09-22 10:34:18 -07001193 }
Jingning Han3ee6db62015-08-05 19:00:31 -07001194 }
Jingning Han3ee6db62015-08-05 19:00:31 -07001195 }
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001196
Jingning Han3ee6db62015-08-05 19:00:31 -07001197 mbmi->tx_size = best_tx;
hui su4f16f112015-10-02 10:45:27 -07001198 mbmi->tx_type = best_tx_type;
Julia Robson9fe188e2016-01-21 17:14:29 +00001199 if (mbmi->tx_size >= TX_32X32)
1200 assert(mbmi->tx_type == DCT_DCT);
Jingning Han71c15602015-10-13 12:40:39 -07001201 txfm_rd_in_plane(x,
1202#if CONFIG_VAR_TX
1203 cpi,
1204#endif
1205 &r, &d, &s,
hui su07154b02015-09-22 10:34:18 -07001206 &sse, ref_best_rd, 0, bs, best_tx,
1207 cpi->sf.use_fast_coef_costing);
Jingning Han3ee6db62015-08-05 19:00:31 -07001208}
1209
Yaowu Xu26a9afc2015-08-13 09:42:27 -07001210static void super_block_yrd(VP10_COMP *cpi, MACROBLOCK *x, int *rate,
Jingning Han3ee6db62015-08-05 19:00:31 -07001211 int64_t *distortion, int *skip,
1212 int64_t *psse, BLOCK_SIZE bs,
1213 int64_t ref_best_rd) {
1214 MACROBLOCKD *xd = &x->e_mbd;
1215 int64_t sse;
1216 int64_t *ret_sse = psse ? psse : &sse;
1217
1218 assert(bs == xd->mi[0]->mbmi.sb_type);
1219
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08001220 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001221 choose_smallest_tx_size(cpi, x, rate, distortion, skip, ret_sse,
1222 ref_best_rd, bs);
hui su66f2f652015-11-16 16:58:15 -08001223 } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
Jingning Han3ee6db62015-08-05 19:00:31 -07001224 choose_largest_tx_size(cpi, x, rate, distortion, skip, ret_sse, ref_best_rd,
1225 bs);
1226 } else {
1227 choose_tx_size_from_rd(cpi, x, rate, distortion, skip, ret_sse,
1228 ref_best_rd, bs);
1229 }
1230}
1231
1232static int conditional_skipintra(PREDICTION_MODE mode,
1233 PREDICTION_MODE best_intra_mode) {
1234 if (mode == D117_PRED &&
1235 best_intra_mode != V_PRED &&
1236 best_intra_mode != D135_PRED)
1237 return 1;
1238 if (mode == D63_PRED &&
1239 best_intra_mode != V_PRED &&
1240 best_intra_mode != D45_PRED)
1241 return 1;
1242 if (mode == D207_PRED &&
1243 best_intra_mode != H_PRED &&
1244 best_intra_mode != D45_PRED)
1245 return 1;
1246 if (mode == D153_PRED &&
1247 best_intra_mode != H_PRED &&
1248 best_intra_mode != D135_PRED)
1249 return 1;
1250 return 0;
1251}
1252
hui suc93e5cc2015-12-07 18:18:57 -08001253void rd_pick_palette_intra_sby(VP10_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
1254 int palette_ctx, int dc_mode_cost,
1255 PALETTE_MODE_INFO *palette_mode_info,
1256 uint8_t *best_palette_color_map,
1257 TX_SIZE *best_tx, PREDICTION_MODE *mode_selected,
1258 int64_t *best_rd) {
1259 MACROBLOCKD *const xd = &x->e_mbd;
1260 MODE_INFO *const mic = xd->mi[0];
1261 int rows = 4 * num_4x4_blocks_high_lookup[bsize];
1262 int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
1263 int this_rate, this_rate_tokenonly, s;
1264 int64_t this_distortion, this_rd;
1265 int colors, n;
1266 int src_stride = x->plane[0].src.stride;
1267 uint8_t *src = x->plane[0].src.buf;
1268
1269#if CONFIG_VP9_HIGHBITDEPTH
1270 if (cpi->common.use_highbitdepth)
1271 colors = vp10_count_colors_highbd(src, src_stride, rows, cols,
1272 cpi->common.bit_depth);
1273 else
1274#endif // CONFIG_VP9_HIGHBITDEPTH
1275 colors = vp10_count_colors(src, src_stride, rows, cols);
1276 palette_mode_info->palette_size[0] = 0;
1277
1278 if (colors > 1 && colors <= 64 && cpi->common.allow_screen_content_tools) {
1279 int r, c, i, j, k;
1280 int max_itr = 50;
1281 int color_ctx, color_idx = 0;
1282 int color_order[PALETTE_MAX_SIZE];
1283 double *data = x->palette_buffer->kmeans_data_buf;
1284 uint8_t *indices = x->palette_buffer->kmeans_indices_buf;
1285 uint8_t *pre_indices = x->palette_buffer->kmeans_pre_indices_buf;
1286 double centroids[PALETTE_MAX_SIZE];
1287 uint8_t *color_map;
1288 double lb, ub, val;
1289 PALETTE_MODE_INFO *pmi = &mic->mbmi.palette_mode_info;
1290#if CONFIG_VP9_HIGHBITDEPTH
1291 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
1292 if (cpi->common.use_highbitdepth)
1293 lb = ub = src16[0];
1294 else
1295#endif // CONFIG_VP9_HIGHBITDEPTH
1296 lb = ub = src[0];
1297
1298#if CONFIG_VP9_HIGHBITDEPTH
1299 if (cpi->common.use_highbitdepth) {
1300 for (r = 0; r < rows; ++r) {
1301 for (c = 0; c < cols; ++c) {
1302 val = src16[r * src_stride + c];
1303 data[r * cols + c] = val;
1304 if (val < lb)
1305 lb = val;
1306 else if (val > ub)
1307 ub = val;
1308 }
1309 }
1310 } else {
1311#endif // CONFIG_VP9_HIGHBITDEPTH
1312 for (r = 0; r < rows; ++r) {
1313 for (c = 0; c < cols; ++c) {
1314 val = src[r * src_stride + c];
1315 data[r * cols + c] = val;
1316 if (val < lb)
1317 lb = val;
1318 else if (val > ub)
1319 ub = val;
1320 }
1321 }
1322#if CONFIG_VP9_HIGHBITDEPTH
1323 }
1324#endif // CONFIG_VP9_HIGHBITDEPTH
1325
1326 mic->mbmi.mode = DC_PRED;
1327
1328 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors;
1329 n >= 2; --n) {
1330 for (i = 0; i < n; ++i)
1331 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
1332 vp10_k_means(data, centroids, indices, pre_indices, rows * cols,
1333 n, 1, max_itr);
1334 vp10_insertion_sort(centroids, n);
1335 for (i = 0; i < n; ++i)
1336 centroids[i] = round(centroids[i]);
1337 // remove duplicates
1338 i = 1;
1339 k = n;
1340 while (i < k) {
1341 if (centroids[i] == centroids[i - 1]) {
1342 j = i;
1343 while (j < k - 1) {
1344 centroids[j] = centroids[j + 1];
1345 ++j;
1346 }
1347 --k;
1348 } else {
1349 ++i;
1350 }
1351 }
1352
1353#if CONFIG_VP9_HIGHBITDEPTH
1354 if (cpi->common.use_highbitdepth)
1355 for (i = 0; i < k; ++i)
Yaowu Xu3c28b4a2016-02-08 09:41:43 -08001356 pmi->palette_colors[i] = clip_pixel_highbd((int)round(centroids[i]),
1357 cpi->common.bit_depth);
hui suc93e5cc2015-12-07 18:18:57 -08001358 else
1359#endif // CONFIG_VP9_HIGHBITDEPTH
1360 for (i = 0; i < k; ++i)
1361 pmi->palette_colors[i] = clip_pixel((int)round(centroids[i]));
1362 pmi->palette_size[0] = k;
1363
1364 vp10_calc_indices(data, centroids, indices, rows * cols, k, 1);
1365 for (r = 0; r < rows; ++r)
1366 for (c = 0; c < cols; ++c)
1367 xd->plane[0].color_index_map[r * cols + c] = indices[r * cols + c];
1368
1369 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
1370 &s, NULL, bsize, *best_rd);
1371 if (this_rate_tokenonly == INT_MAX)
1372 continue;
1373
1374 this_rate = this_rate_tokenonly + dc_mode_cost +
1375 cpi->common.bit_depth * k * vp10_cost_bit(128, 0) +
1376 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - 2];
1377 this_rate +=
1378 vp10_cost_bit(vp10_default_palette_y_mode_prob[bsize - BLOCK_8X8]
1379 [palette_ctx], 1);
1380 color_map = xd->plane[0].color_index_map;
1381 this_rate += write_uniform_cost(k, xd->plane[0].color_index_map[0]);
1382 for (i = 0; i < rows; ++i) {
1383 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
1384 color_ctx = vp10_get_palette_color_context(color_map, cols, i, j,
1385 k, color_order);
1386 for (r = 0; r < k; ++r)
1387 if (color_map[i * cols + j] == color_order[r]) {
1388 color_idx = r;
1389 break;
1390 }
1391 assert(color_idx < k);
1392 this_rate +=
1393 cpi->palette_y_color_cost[k - 2][color_ctx][color_idx];
1394 }
1395 }
1396 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
1397
1398 if (this_rd < *best_rd) {
1399 *best_rd = this_rd;
1400 *palette_mode_info = mic->mbmi.palette_mode_info;
1401 memcpy(best_palette_color_map, xd->plane[0].color_index_map,
1402 rows * cols * sizeof(xd->plane[0].color_index_map[0]));
1403 *mode_selected = DC_PRED;
1404 *best_tx = mic->mbmi.tx_size;
1405 }
1406 }
1407 }
1408}
1409
Yaowu Xu26a9afc2015-08-13 09:42:27 -07001410static int64_t rd_pick_intra4x4block(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07001411 int row, int col,
1412 PREDICTION_MODE *best_mode,
1413 const int *bmode_costs,
1414 ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
1415 int *bestrate, int *bestratey,
1416 int64_t *bestdistortion,
1417 BLOCK_SIZE bsize, int64_t rd_thresh) {
1418 PREDICTION_MODE mode;
1419 MACROBLOCKD *const xd = &x->e_mbd;
1420 int64_t best_rd = rd_thresh;
1421 struct macroblock_plane *p = &x->plane[0];
1422 struct macroblockd_plane *pd = &xd->plane[0];
1423 const int src_stride = p->src.stride;
1424 const int dst_stride = pd->dst.stride;
1425 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
1426 uint8_t *dst_init = &pd->dst.buf[row * 4 * src_stride + col * 4];
1427 ENTROPY_CONTEXT ta[2], tempa[2];
1428 ENTROPY_CONTEXT tl[2], templ[2];
1429 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1430 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1431 int idx, idy;
1432 uint8_t best_dst[8 * 8];
1433#if CONFIG_VP9_HIGHBITDEPTH
1434 uint16_t best_dst16[8 * 8];
1435#endif
1436
1437 memcpy(ta, a, sizeof(ta));
1438 memcpy(tl, l, sizeof(tl));
1439 xd->mi[0]->mbmi.tx_size = TX_4X4;
hui suc93e5cc2015-12-07 18:18:57 -08001440 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07001441
1442#if CONFIG_VP9_HIGHBITDEPTH
1443 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1444 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
1445 int64_t this_rd;
1446 int ratey = 0;
1447 int64_t distortion = 0;
1448 int rate = bmode_costs[mode];
1449
1450 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode)))
1451 continue;
1452
1453 // Only do the oblique modes if the best so far is
1454 // one of the neighboring directional modes
1455 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
1456 if (conditional_skipintra(mode, *best_mode))
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001457 continue;
Jingning Han3ee6db62015-08-05 19:00:31 -07001458 }
1459
1460 memcpy(tempa, ta, sizeof(ta));
1461 memcpy(templ, tl, sizeof(tl));
1462
1463 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
1464 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
1465 const int block = (row + idy) * 2 + (col + idx);
1466 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
1467 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
1468 int16_t *const src_diff = vp10_raster_block_offset_int16(BLOCK_8X8,
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001469 block,
1470 p->src_diff);
Jingning Han3ee6db62015-08-05 19:00:31 -07001471 tran_low_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block);
1472 xd->mi[0]->bmi[block].as_mode = mode;
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001473 vp10_predict_intra_block(xd, 1, 1, TX_4X4, mode, dst, dst_stride,
Jingning Han3ee6db62015-08-05 19:00:31 -07001474 dst, dst_stride,
1475 col + idx, row + idy, 0);
1476 vpx_highbd_subtract_block(4, 4, src_diff, 8, src, src_stride,
1477 dst, dst_stride, xd->bd);
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001478 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
hui sub3cc3a02015-08-24 14:37:54 -07001479 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001480 const scan_order *so = get_scan(TX_4X4, tx_type, 0);
Jingning Han20484042015-10-21 17:38:00 -07001481#if CONFIG_VAR_TX
1482 const int coeff_ctx = combine_entropy_contexts(*(tempa + idx),
1483 *(templ + idy));
1484#endif
Yaowu Xu7c514e22015-09-28 15:55:46 -07001485 vp10_highbd_fwd_txfm_4x4(src_diff, coeff, 8, DCT_DCT, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07001486 vp10_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
Jingning Han20484042015-10-21 17:38:00 -07001487 ratey += cost_coeffs(x, 0, block,
1488#if CONFIG_VAR_TX
1489 coeff_ctx,
1490#else
1491 tempa + idx, templ + idy,
1492#endif
1493 TX_4X4,
Jingning Han3ee6db62015-08-05 19:00:31 -07001494 so->scan, so->neighbors,
1495 cpi->sf.use_fast_coef_costing);
1496 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1497 goto next_highbd;
hui sud76e5b32015-08-13 16:27:19 -07001498 vp10_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block),
1499 dst, dst_stride, p->eobs[block],
Yaowu Xu7c514e22015-09-28 15:55:46 -07001500 xd->bd, DCT_DCT, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07001501 } else {
1502 int64_t unused;
hui sub3cc3a02015-08-24 14:37:54 -07001503 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001504 const scan_order *so = get_scan(TX_4X4, tx_type, 0);
Jingning Han20484042015-10-21 17:38:00 -07001505#if CONFIG_VAR_TX
1506 const int coeff_ctx = combine_entropy_contexts(*(tempa + idx),
1507 *(templ + idy));
1508#endif
Yaowu Xu7c514e22015-09-28 15:55:46 -07001509 vp10_highbd_fwd_txfm_4x4(src_diff, coeff, 8, tx_type, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07001510 vp10_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
Jingning Han20484042015-10-21 17:38:00 -07001511 ratey += cost_coeffs(x, 0, block,
1512#if CONFIG_VAR_TX
1513 coeff_ctx,
1514#else
1515 tempa + idx, templ + idy,
1516#endif
1517 TX_4X4,
Jingning Han3ee6db62015-08-05 19:00:31 -07001518 so->scan, so->neighbors,
1519 cpi->sf.use_fast_coef_costing);
1520 distortion += vp10_highbd_block_error(
1521 coeff, BLOCK_OFFSET(pd->dqcoeff, block),
1522 16, &unused, xd->bd) >> 2;
1523 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1524 goto next_highbd;
hui sud76e5b32015-08-13 16:27:19 -07001525 vp10_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block),
1526 dst, dst_stride, p->eobs[block],
Yaowu Xu7c514e22015-09-28 15:55:46 -07001527 xd->bd, tx_type, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07001528 }
1529 }
1530 }
1531
1532 rate += ratey;
1533 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
1534
1535 if (this_rd < best_rd) {
1536 *bestrate = rate;
1537 *bestratey = ratey;
1538 *bestdistortion = distortion;
1539 best_rd = this_rd;
1540 *best_mode = mode;
1541 memcpy(a, tempa, sizeof(tempa));
1542 memcpy(l, templ, sizeof(templ));
1543 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
1544 memcpy(best_dst16 + idy * 8,
1545 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
1546 num_4x4_blocks_wide * 4 * sizeof(uint16_t));
1547 }
1548 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001549next_highbd:
Jingning Han3ee6db62015-08-05 19:00:31 -07001550 {}
1551 }
Jingning Han481b8342015-09-11 08:56:06 -07001552 if (best_rd >= rd_thresh)
Jingning Han3ee6db62015-08-05 19:00:31 -07001553 return best_rd;
1554
1555 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
1556 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
1557 best_dst16 + idy * 8,
1558 num_4x4_blocks_wide * 4 * sizeof(uint16_t));
1559 }
1560
1561 return best_rd;
1562 }
1563#endif // CONFIG_VP9_HIGHBITDEPTH
1564
1565 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
1566 int64_t this_rd;
1567 int ratey = 0;
1568 int64_t distortion = 0;
1569 int rate = bmode_costs[mode];
1570
1571 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode)))
1572 continue;
1573
1574 // Only do the oblique modes if the best so far is
1575 // one of the neighboring directional modes
1576 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
1577 if (conditional_skipintra(mode, *best_mode))
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001578 continue;
Jingning Han3ee6db62015-08-05 19:00:31 -07001579 }
1580
1581 memcpy(tempa, ta, sizeof(ta));
1582 memcpy(templ, tl, sizeof(tl));
1583
1584 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
1585 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
1586 const int block = (row + idy) * 2 + (col + idx);
1587 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
1588 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
1589 int16_t *const src_diff =
1590 vp10_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff);
1591 tran_low_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block);
1592 xd->mi[0]->bmi[block].as_mode = mode;
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001593 vp10_predict_intra_block(xd, 1, 1, TX_4X4, mode, dst, dst_stride,
Jingning Han3ee6db62015-08-05 19:00:31 -07001594 dst, dst_stride, col + idx, row + idy, 0);
1595 vpx_subtract_block(4, 4, src_diff, 8, src, src_stride, dst, dst_stride);
1596
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001597 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
hui sub3cc3a02015-08-24 14:37:54 -07001598 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001599 const scan_order *so = get_scan(TX_4X4, tx_type, 0);
Jingning Han2cdc1272015-10-09 09:57:42 -07001600#if CONFIG_VAR_TX
1601 int coeff_ctx = combine_entropy_contexts(*(tempa + idx),
1602 *(templ + idy));
1603#endif
Yaowu Xu7c514e22015-09-28 15:55:46 -07001604 vp10_fwd_txfm_4x4(src_diff, coeff, 8, DCT_DCT, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07001605 vp10_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
Jingning Han2cdc1272015-10-09 09:57:42 -07001606#if CONFIG_VAR_TX
1607 ratey += cost_coeffs(x, 0, block, coeff_ctx, TX_4X4, so->scan,
1608 so->neighbors, cpi->sf.use_fast_coef_costing);
1609 *(tempa + idx) = !(p->eobs[block] == 0);
1610 *(templ + idy) = !(p->eobs[block] == 0);
1611#else
1612 ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy,
1613 TX_4X4,
Jingning Han3ee6db62015-08-05 19:00:31 -07001614 so->scan, so->neighbors,
1615 cpi->sf.use_fast_coef_costing);
Jingning Han2cdc1272015-10-09 09:57:42 -07001616#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07001617 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1618 goto next;
hui sud76e5b32015-08-13 16:27:19 -07001619 vp10_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block),
Yaowu Xu7c514e22015-09-28 15:55:46 -07001620 dst, dst_stride, p->eobs[block], DCT_DCT, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07001621 } else {
1622 int64_t unused;
hui sub3cc3a02015-08-24 14:37:54 -07001623 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001624 const scan_order *so = get_scan(TX_4X4, tx_type, 0);
Jingning Han2cdc1272015-10-09 09:57:42 -07001625#if CONFIG_VAR_TX
1626 int coeff_ctx = combine_entropy_contexts(*(tempa + idx),
1627 *(templ + idy));
1628#endif
Yaowu Xu7c514e22015-09-28 15:55:46 -07001629 vp10_fwd_txfm_4x4(src_diff, coeff, 8, tx_type, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07001630 vp10_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
Jingning Han2cdc1272015-10-09 09:57:42 -07001631#if CONFIG_VAR_TX
1632 ratey += cost_coeffs(x, 0, block, coeff_ctx, TX_4X4, so->scan,
1633 so->neighbors, cpi->sf.use_fast_coef_costing);
1634 *(tempa + idx) = !(p->eobs[block] == 0);
1635 *(templ + idy) = !(p->eobs[block] == 0);
1636#else
1637 ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy,
1638 TX_4X4, so->scan, so->neighbors,
1639 cpi->sf.use_fast_coef_costing);
1640#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07001641 distortion += vp10_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, block),
1642 16, &unused) >> 2;
1643 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1644 goto next;
hui sud76e5b32015-08-13 16:27:19 -07001645 vp10_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block),
Yaowu Xu7c514e22015-09-28 15:55:46 -07001646 dst, dst_stride, p->eobs[block], tx_type, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07001647 }
1648 }
1649 }
1650
1651 rate += ratey;
1652 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
1653
1654 if (this_rd < best_rd) {
1655 *bestrate = rate;
1656 *bestratey = ratey;
1657 *bestdistortion = distortion;
1658 best_rd = this_rd;
1659 *best_mode = mode;
1660 memcpy(a, tempa, sizeof(tempa));
1661 memcpy(l, templ, sizeof(templ));
1662 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
1663 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
1664 num_4x4_blocks_wide * 4);
1665 }
1666 next:
1667 {}
1668 }
1669
Jingning Hanf1376972015-09-10 12:42:21 -07001670 if (best_rd >= rd_thresh)
Jingning Han3ee6db62015-08-05 19:00:31 -07001671 return best_rd;
1672
1673 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
1674 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
1675 num_4x4_blocks_wide * 4);
1676
1677 return best_rd;
1678}
1679
Yaowu Xu26a9afc2015-08-13 09:42:27 -07001680static int64_t rd_pick_intra_sub_8x8_y_mode(VP10_COMP *cpi, MACROBLOCK *mb,
Jingning Han3ee6db62015-08-05 19:00:31 -07001681 int *rate, int *rate_y,
1682 int64_t *distortion,
1683 int64_t best_rd) {
1684 int i, j;
1685 const MACROBLOCKD *const xd = &mb->e_mbd;
1686 MODE_INFO *const mic = xd->mi[0];
1687 const MODE_INFO *above_mi = xd->above_mi;
1688 const MODE_INFO *left_mi = xd->left_mi;
1689 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
1690 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1691 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1692 int idx, idy;
1693 int cost = 0;
1694 int64_t total_distortion = 0;
1695 int tot_rate_y = 0;
1696 int64_t total_rd = 0;
1697 ENTROPY_CONTEXT t_above[4], t_left[4];
hui su1559afd2015-12-30 10:27:19 -08001698 const int *bmode_costs = cpi->mbmode_cost[0];
Jingning Han3ee6db62015-08-05 19:00:31 -07001699
1700 memcpy(t_above, xd->plane[0].above_context, sizeof(t_above));
1701 memcpy(t_left, xd->plane[0].left_context, sizeof(t_left));
1702
hui sube3559b2015-10-07 09:29:02 -07001703#if CONFIG_EXT_INTRA
1704 mic->mbmi.ext_intra_mode_info.use_ext_intra_mode[0] = 0;
hui su3b1c7662016-01-12 16:38:58 -08001705 mic->mbmi.intra_filter = INTRA_FILTER_LINEAR;
hui sube3559b2015-10-07 09:29:02 -07001706#endif // CONFIG_EXT_INTRA
1707
Debargha Mukherjeed46c1f22016-02-08 15:59:17 -08001708 // TODO(any): Add search of the tx_type to improve rd performance at the
1709 // expense of speed.
1710 mic->mbmi.tx_type = DCT_DCT;
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08001711 mic->mbmi.tx_size = TX_4X4;
Debargha Mukherjeed46c1f22016-02-08 15:59:17 -08001712
Jingning Han3ee6db62015-08-05 19:00:31 -07001713 // Pick modes for each sub-block (of size 4x4, 4x8, or 8x4) in an 8x8 block.
1714 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
1715 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
1716 PREDICTION_MODE best_mode = DC_PRED;
1717 int r = INT_MAX, ry = INT_MAX;
1718 int64_t d = INT64_MAX, this_rd = INT64_MAX;
1719 i = idy * 2 + idx;
1720 if (cpi->common.frame_type == KEY_FRAME) {
1721 const PREDICTION_MODE A = vp10_above_block_mode(mic, above_mi, i);
1722 const PREDICTION_MODE L = vp10_left_block_mode(mic, left_mi, i);
1723
1724 bmode_costs = cpi->y_mode_costs[A][L];
1725 }
1726
1727 this_rd = rd_pick_intra4x4block(cpi, mb, idy, idx, &best_mode,
1728 bmode_costs, t_above + idx, t_left + idy,
1729 &r, &ry, &d, bsize, best_rd - total_rd);
1730 if (this_rd >= best_rd - total_rd)
1731 return INT64_MAX;
1732
1733 total_rd += this_rd;
1734 cost += r;
1735 total_distortion += d;
1736 tot_rate_y += ry;
1737
1738 mic->bmi[i].as_mode = best_mode;
1739 for (j = 1; j < num_4x4_blocks_high; ++j)
1740 mic->bmi[i + j * 2].as_mode = best_mode;
1741 for (j = 1; j < num_4x4_blocks_wide; ++j)
1742 mic->bmi[i + j].as_mode = best_mode;
1743
1744 if (total_rd >= best_rd)
1745 return INT64_MAX;
1746 }
1747 }
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08001748 mic->mbmi.mode = mic->bmi[3].as_mode;
1749
1750 // Add in the cost of the transform type
1751 if (!xd->lossless[mic->mbmi.segment_id]) {
1752 int rate_tx_type = 0;
1753#if CONFIG_EXT_TX
1754 if (get_ext_tx_types(TX_4X4, bsize, 0) > 1) {
1755 const int eset = get_ext_tx_set(TX_4X4, bsize, 0);
1756 rate_tx_type =
1757 cpi->intra_tx_type_costs[eset][TX_4X4]
1758 [mic->mbmi.mode][mic->mbmi.tx_type];
1759 }
1760#else
1761 rate_tx_type =
1762 cpi->intra_tx_type_costs[TX_4X4]
1763 [intra_mode_to_tx_type_context[mic->mbmi.mode]]
1764 [mic->mbmi.tx_type];
1765#endif
1766 assert(mic->mbmi.tx_size == TX_4X4);
1767 cost += rate_tx_type;
1768 tot_rate_y += rate_tx_type;
1769 }
Jingning Han3ee6db62015-08-05 19:00:31 -07001770
1771 *rate = cost;
1772 *rate_y = tot_rate_y;
1773 *distortion = total_distortion;
Jingning Han3ee6db62015-08-05 19:00:31 -07001774
1775 return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
1776}
1777
hui sube3559b2015-10-07 09:29:02 -07001778#if CONFIG_EXT_INTRA
1779// Return 1 if an ext intra mode is selected; return 0 otherwise.
1780static int rd_pick_ext_intra_sby(VP10_COMP *cpi, MACROBLOCK *x,
1781 int *rate, int *rate_tokenonly,
1782 int64_t *distortion, int *skippable,
1783 BLOCK_SIZE bsize, int mode_cost,
1784 int64_t *best_rd) {
1785 MACROBLOCKD *const xd = &x->e_mbd;
1786 MODE_INFO *const mic = xd->mi[0];
1787 MB_MODE_INFO *mbmi = &mic->mbmi;
1788 int this_rate, this_rate_tokenonly, s;
1789 int ext_intra_selected_flag = 0;
hui su4aa50c12015-11-10 12:09:59 -08001790 int64_t this_distortion, this_rd;
hui sube3559b2015-10-07 09:29:02 -07001791 EXT_INTRA_MODE mode;
1792 TX_SIZE best_tx_size = TX_4X4;
1793 EXT_INTRA_MODE_INFO ext_intra_mode_info;
hui sube3559b2015-10-07 09:29:02 -07001794 TX_TYPE best_tx_type;
hui sube3559b2015-10-07 09:29:02 -07001795
1796 vp10_zero(ext_intra_mode_info);
1797 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 1;
1798 mbmi->mode = DC_PRED;
1799
hui su4aa50c12015-11-10 12:09:59 -08001800 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
1801 mbmi->ext_intra_mode_info.ext_intra_mode[0] = mode;
1802 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
1803 &s, NULL, bsize, *best_rd);
1804 if (this_rate_tokenonly == INT_MAX)
1805 continue;
hui sube3559b2015-10-07 09:29:02 -07001806
hui su4aa50c12015-11-10 12:09:59 -08001807 this_rate = this_rate_tokenonly +
1808 vp10_cost_bit(cpi->common.fc->ext_intra_probs[0], 1) +
1809 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
1810 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui sube3559b2015-10-07 09:29:02 -07001811
hui su4aa50c12015-11-10 12:09:59 -08001812 if (this_rd < *best_rd) {
1813 *best_rd = this_rd;
1814 best_tx_size = mic->mbmi.tx_size;
1815 ext_intra_mode_info = mbmi->ext_intra_mode_info;
hui su4aa50c12015-11-10 12:09:59 -08001816 best_tx_type = mic->mbmi.tx_type;
hui su4aa50c12015-11-10 12:09:59 -08001817 *rate = this_rate;
1818 *rate_tokenonly = this_rate_tokenonly;
1819 *distortion = this_distortion;
1820 *skippable = s;
1821 ext_intra_selected_flag = 1;
hui sube3559b2015-10-07 09:29:02 -07001822 }
1823 }
1824
1825 if (ext_intra_selected_flag) {
1826 mbmi->mode = DC_PRED;
1827 mbmi->tx_size = best_tx_size;
1828 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] =
1829 ext_intra_mode_info.use_ext_intra_mode[0];
1830 mbmi->ext_intra_mode_info.ext_intra_mode[0] =
1831 ext_intra_mode_info.ext_intra_mode[0];
hui sube3559b2015-10-07 09:29:02 -07001832 mbmi->tx_type = best_tx_type;
hui sube3559b2015-10-07 09:29:02 -07001833 return 1;
1834 } else {
1835 return 0;
1836 }
1837}
hui su4aa50c12015-11-10 12:09:59 -08001838
hui su5a7c8d82016-02-08 10:39:17 -08001839static void pick_intra_angle_routine_sby(VP10_COMP *cpi, MACROBLOCK *x,
1840 int *rate, int *rate_tokenonly,
1841 int64_t *distortion, int *skippable,
1842 int *best_angle_delta,
1843 TX_SIZE *best_tx_size,
1844 TX_TYPE *best_tx_type,
1845 INTRA_FILTER *best_filter,
1846 BLOCK_SIZE bsize, int rate_overhead,
1847 int64_t *best_rd) {
1848 int this_rate, this_rate_tokenonly, s;
1849 int64_t this_distortion, this_rd;
1850 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
1851 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
1852 &s, NULL, bsize, *best_rd);
1853 if (this_rate_tokenonly == INT_MAX)
1854 return;
1855
1856 this_rate = this_rate_tokenonly + rate_overhead;
1857 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
1858
1859 if (this_rd < *best_rd) {
1860 *best_rd = this_rd;
1861 *best_angle_delta = mbmi->angle_delta[0];
1862 *best_tx_size = mbmi->tx_size;
1863 *best_filter = mbmi->intra_filter;
1864 *best_tx_type = mbmi->tx_type;
1865 *rate = this_rate;
1866 *rate_tokenonly = this_rate_tokenonly;
1867 *distortion = this_distortion;
1868 *skippable = s;
1869 }
1870}
1871
hui su4aa50c12015-11-10 12:09:59 -08001872static int64_t rd_pick_intra_angle_sby(VP10_COMP *cpi, MACROBLOCK *x,
1873 int *rate, int *rate_tokenonly,
1874 int64_t *distortion, int *skippable,
1875 BLOCK_SIZE bsize, int rate_overhead,
1876 int64_t best_rd) {
1877 MACROBLOCKD *const xd = &x->e_mbd;
1878 MODE_INFO *const mic = xd->mi[0];
1879 MB_MODE_INFO *mbmi = &mic->mbmi;
1880 int this_rate, this_rate_tokenonly, s;
hui su3b1c7662016-01-12 16:38:58 -08001881 int angle_delta, best_angle_delta = 0, p_angle;
1882 const int intra_filter_ctx = vp10_get_pred_context_intra_interp(xd);
1883 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
hui su4aa50c12015-11-10 12:09:59 -08001884 const double rd_adjust = 1.2;
1885 int64_t this_distortion, this_rd, sse_dummy;
1886 TX_SIZE best_tx_size = mic->mbmi.tx_size;
hui su4aa50c12015-11-10 12:09:59 -08001887 TX_TYPE best_tx_type = mbmi->tx_type;
hui su4aa50c12015-11-10 12:09:59 -08001888
1889 if (ANGLE_FAST_SEARCH) {
1890 int deltas_level1[3] = {0, -2, 2};
1891 int deltas_level2[3][2] = {
1892 {-1, 1}, {-3, -1}, {1, 3},
1893 };
1894 const int level1 = 3, level2 = 2;
1895 int i, j, best_i = -1;
1896
1897 for (i = 0; i < level1; ++i) {
1898 mic->mbmi.angle_delta[0] = deltas_level1[i];
hui su3b1c7662016-01-12 16:38:58 -08001899 p_angle = mode_to_angle_map[mbmi->mode] +
1900 mbmi->angle_delta[0] * ANGLE_STEP;
1901 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
hui su5b618b72016-02-03 11:32:25 -08001902 if ((FILTER_FAST_SEARCH || !pick_intra_filter(p_angle)) &&
1903 filter != INTRA_FILTER_LINEAR)
hui su4aa50c12015-11-10 12:09:59 -08001904 continue;
hui su3b1c7662016-01-12 16:38:58 -08001905 mic->mbmi.intra_filter = filter;
hui su4aa50c12015-11-10 12:09:59 -08001906 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
hui su3b1c7662016-01-12 16:38:58 -08001907 &s, NULL, bsize,
1908 (i == 0 && filter == INTRA_FILTER_LINEAR &&
1909 best_rd < INT64_MAX) ? best_rd * rd_adjust : best_rd);
1910 if (this_rate_tokenonly == INT_MAX) {
1911 if (i == 0 && filter == INTRA_FILTER_LINEAR)
1912 return best_rd;
1913 else
1914 continue;
1915 }
1916 this_rate = this_rate_tokenonly + rate_overhead +
1917 cpi->intra_filter_cost[intra_filter_ctx][filter];
hui su4aa50c12015-11-10 12:09:59 -08001918 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui su3b1c7662016-01-12 16:38:58 -08001919 if (i == 0 && filter == INTRA_FILTER_LINEAR &&
1920 best_rd < INT64_MAX && this_rd > best_rd * rd_adjust)
1921 return best_rd;
hui su4aa50c12015-11-10 12:09:59 -08001922 if (this_rd < best_rd) {
hui su3b1c7662016-01-12 16:38:58 -08001923 best_i = i;
hui su4aa50c12015-11-10 12:09:59 -08001924 best_rd = this_rd;
1925 best_angle_delta = mbmi->angle_delta[0];
1926 best_tx_size = mbmi->tx_size;
hui su3b1c7662016-01-12 16:38:58 -08001927 best_filter = mbmi->intra_filter;
hui su4aa50c12015-11-10 12:09:59 -08001928 best_tx_type = mbmi->tx_type;
hui su4aa50c12015-11-10 12:09:59 -08001929 *rate = this_rate;
1930 *rate_tokenonly = this_rate_tokenonly;
1931 *distortion = this_distortion;
1932 *skippable = s;
1933 }
1934 }
1935 }
hui su3b1c7662016-01-12 16:38:58 -08001936
1937 if (best_i >= 0) {
1938 for (j = 0; j < level2; ++j) {
1939 mic->mbmi.angle_delta[0] = deltas_level2[best_i][j];
1940 p_angle = mode_to_angle_map[mbmi->mode] +
1941 mbmi->angle_delta[0] * ANGLE_STEP;
1942 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
1943 mic->mbmi.intra_filter = filter;
hui su5b618b72016-02-03 11:32:25 -08001944 if ((FILTER_FAST_SEARCH || !pick_intra_filter(p_angle)) &&
1945 filter != INTRA_FILTER_LINEAR)
hui su3b1c7662016-01-12 16:38:58 -08001946 continue;
hui su5a7c8d82016-02-08 10:39:17 -08001947 pick_intra_angle_routine_sby(cpi, x, rate, rate_tokenonly,
1948 distortion, skippable,
1949 &best_angle_delta, &best_tx_size,
1950 &best_tx_type, &best_filter, bsize,
1951 rate_overhead +
1952 cpi->intra_filter_cost
1953 [intra_filter_ctx][filter],
1954 &best_rd);
hui su3b1c7662016-01-12 16:38:58 -08001955 }
1956 }
1957 }
hui su4aa50c12015-11-10 12:09:59 -08001958 } else {
1959 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
1960 ++angle_delta) {
hui su3b1c7662016-01-12 16:38:58 -08001961 mbmi->angle_delta[0] = angle_delta;
1962 p_angle = mode_to_angle_map[mbmi->mode] +
1963 mbmi->angle_delta[0] * ANGLE_STEP;
1964 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
1965 mic->mbmi.intra_filter = filter;
hui su5b618b72016-02-03 11:32:25 -08001966 if ((FILTER_FAST_SEARCH || !pick_intra_filter(p_angle)) &&
1967 filter != INTRA_FILTER_LINEAR)
hui su3b1c7662016-01-12 16:38:58 -08001968 continue;
hui su5a7c8d82016-02-08 10:39:17 -08001969 pick_intra_angle_routine_sby(cpi, x, rate, rate_tokenonly,
1970 distortion, skippable,
1971 &best_angle_delta, &best_tx_size,
1972 &best_tx_type, &best_filter, bsize,
1973 rate_overhead +
1974 cpi->intra_filter_cost
1975 [intra_filter_ctx][filter],
1976 &best_rd);
hui su4aa50c12015-11-10 12:09:59 -08001977 }
1978 }
1979 }
1980
hui su5b618b72016-02-03 11:32:25 -08001981 if (FILTER_FAST_SEARCH && *rate_tokenonly < INT_MAX) {
1982 mbmi->angle_delta[0] = best_angle_delta;
1983 p_angle = mode_to_angle_map[mbmi->mode] +
1984 mbmi->angle_delta[0] * ANGLE_STEP;
1985 if (pick_intra_filter(p_angle)) {
1986 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
1987 mic->mbmi.intra_filter = filter;
hui su5a7c8d82016-02-08 10:39:17 -08001988 pick_intra_angle_routine_sby(cpi, x, rate, rate_tokenonly,
1989 distortion, skippable,
1990 &best_angle_delta, &best_tx_size,
1991 &best_tx_type, &best_filter, bsize,
1992 rate_overhead + cpi->intra_filter_cost
1993 [intra_filter_ctx][filter], &best_rd);
hui su5b618b72016-02-03 11:32:25 -08001994 }
1995 }
1996 }
1997
hui su4aa50c12015-11-10 12:09:59 -08001998 mbmi->tx_size = best_tx_size;
1999 mbmi->angle_delta[0] = best_angle_delta;
hui su3b1c7662016-01-12 16:38:58 -08002000 mic->mbmi.intra_filter = best_filter;
hui su4aa50c12015-11-10 12:09:59 -08002001 mbmi->tx_type = best_tx_type;
hui su4aa50c12015-11-10 12:09:59 -08002002
2003 if (*rate_tokenonly < INT_MAX) {
2004 txfm_rd_in_plane(x,
2005#if CONFIG_VAR_TX
2006 cpi,
2007#endif
2008 &this_rate_tokenonly, &this_distortion, &s,
2009 &sse_dummy, INT64_MAX, 0, bsize, mbmi->tx_size,
2010 cpi->sf.use_fast_coef_costing);
2011 }
2012
2013 return best_rd;
2014}
hui sud7c8bc72015-11-12 19:18:32 -08002015
2016static inline int get_angle_index(double angle) {
2017 const double step = 22.5, base = 45;
2018 return (int)round((angle - base) / step);
2019}
2020
2021static void angle_estimation(const uint8_t *src, int src_stride,
2022 int rows, int cols, double *hist) {
2023 int r, c, i, index;
2024 const double pi = 3.1415;
2025 double angle, dx, dy;
2026 double temp, divisor = 0;
2027
2028 for (i = 0; i < DIRECTIONAL_MODES; ++i)
2029 hist[i] = 0;
2030
2031 src += src_stride;
2032 for (r = 1; r < rows; ++r) {
2033 for (c = 1; c < cols; ++c) {
2034 dx = src[c] - src[c - 1];
2035 dy = src[c] - src[c - src_stride];
2036 temp = dx * dx + dy * dy;
2037 if (dy == 0)
2038 angle = 90;
2039 else
2040 angle = (atan((double)dx / (double)dy)) * 180 / pi;
2041 assert(angle >= -90 && angle <= 90);
2042 index = get_angle_index(angle + 180);
2043 if (index < DIRECTIONAL_MODES) {
2044 hist[index] += temp;
2045 divisor += temp;
2046 }
2047 if (angle > 0) {
2048 index = get_angle_index(angle);
2049 if (index >= 0) {
2050 hist[index] += temp;
2051 divisor += temp;
2052 }
2053 }
2054 }
2055 src += src_stride;
2056 }
2057
2058 if (divisor < 1)
2059 divisor = 1;
2060 for (i = 0; i < DIRECTIONAL_MODES; ++i)
2061 hist[i] /= divisor;
2062}
2063
2064#if CONFIG_VP9_HIGHBITDEPTH
2065static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
2066 int rows, int cols, double *hist) {
2067 int r, c, i, index;
2068 const double pi = 3.1415;
2069 double angle, dx, dy;
2070 double temp, divisor = 0;
2071 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
2072
2073 for (i = 0; i < DIRECTIONAL_MODES; ++i)
2074 hist[i] = 0;
2075
2076 src += src_stride;
2077 for (r = 1; r < rows; ++r) {
2078 for (c = 1; c < cols; ++c) {
2079 dx = src[c] - src[c - 1];
2080 dy = src[c] - src[c - src_stride];
2081 temp = dx * dx + dy * dy;
2082 if (dy == 0)
2083 angle = 90;
2084 else
2085 angle = (atan((double)dx / (double)dy)) * 180 / pi;
2086 assert(angle >= -90 && angle <= 90);
2087 index = get_angle_index(angle + 180);
2088 if (index < DIRECTIONAL_MODES) {
2089 hist[index] += temp;
2090 divisor += temp;
2091 }
2092 if (angle > 0) {
2093 index = get_angle_index(angle);
2094 if (index >= 0) {
2095 hist[index] += temp;
2096 divisor += temp;
2097 }
2098 }
2099 }
2100 src += src_stride;
2101 }
2102
2103 if (divisor < 1)
2104 divisor = 1;
2105 for (i = 0; i < DIRECTIONAL_MODES; ++i)
2106 hist[i] /= divisor;
2107}
2108#endif // CONFIG_VP9_HIGHBITDEPTH
hui sube3559b2015-10-07 09:29:02 -07002109#endif // CONFIG_EXT_INTRA
2110
Jingning Han3ee6db62015-08-05 19:00:31 -07002111// This function is used only for intra_only frames
Yaowu Xu26a9afc2015-08-13 09:42:27 -07002112static int64_t rd_pick_intra_sby_mode(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07002113 int *rate, int *rate_tokenonly,
2114 int64_t *distortion, int *skippable,
2115 BLOCK_SIZE bsize,
2116 int64_t best_rd) {
2117 PREDICTION_MODE mode;
2118 PREDICTION_MODE mode_selected = DC_PRED;
2119 MACROBLOCKD *const xd = &x->e_mbd;
2120 MODE_INFO *const mic = xd->mi[0];
2121 int this_rate, this_rate_tokenonly, s;
2122 int64_t this_distortion, this_rd;
2123 TX_SIZE best_tx = TX_4X4;
hui sube3559b2015-10-07 09:29:02 -07002124#if CONFIG_EXT_INTRA
hui su3b1c7662016-01-12 16:38:58 -08002125 const int intra_filter_ctx = vp10_get_pred_context_intra_interp(xd);
hui sube3559b2015-10-07 09:29:02 -07002126 EXT_INTRA_MODE_INFO ext_intra_mode_info;
hui su4aa50c12015-11-10 12:09:59 -08002127 int is_directional_mode, rate_overhead, best_angle_delta = 0;
hui su3b1c7662016-01-12 16:38:58 -08002128 INTRA_FILTER best_filter = INTRA_FILTER_LINEAR;
hui sud7c8bc72015-11-12 19:18:32 -08002129 uint8_t directional_mode_skip_mask[INTRA_MODES];
2130 const int src_stride = x->plane[0].src.stride;
2131 const uint8_t *src = x->plane[0].src.buf;
2132 double hist[DIRECTIONAL_MODES];
hui sube3559b2015-10-07 09:29:02 -07002133#endif // CONFIG_EXT_INTRA
hui su4f16f112015-10-02 10:45:27 -07002134 TX_TYPE best_tx_type = DCT_DCT;
Jingning Han3ee6db62015-08-05 19:00:31 -07002135 int *bmode_costs;
hui suc93e5cc2015-12-07 18:18:57 -08002136 PALETTE_MODE_INFO palette_mode_info;
2137 uint8_t *best_palette_color_map = cpi->common.allow_screen_content_tools ?
2138 x->palette_buffer->best_palette_color_map : NULL;
2139 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
2140 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
2141 int palette_ctx = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07002142 const MODE_INFO *above_mi = xd->above_mi;
2143 const MODE_INFO *left_mi = xd->left_mi;
2144 const PREDICTION_MODE A = vp10_above_block_mode(mic, above_mi, 0);
2145 const PREDICTION_MODE L = vp10_left_block_mode(mic, left_mi, 0);
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08002146 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
2147 const vpx_prob *tx_probs = get_tx_probs2(max_tx_size, xd,
2148 &cpi->common.fc->tx_probs);
Jingning Han3ee6db62015-08-05 19:00:31 -07002149 bmode_costs = cpi->y_mode_costs[A][L];
2150
hui sube3559b2015-10-07 09:29:02 -07002151#if CONFIG_EXT_INTRA
2152 ext_intra_mode_info.use_ext_intra_mode[0] = 0;
2153 mic->mbmi.ext_intra_mode_info.use_ext_intra_mode[0] = 0;
hui su4aa50c12015-11-10 12:09:59 -08002154 mic->mbmi.angle_delta[0] = 0;
hui sud7c8bc72015-11-12 19:18:32 -08002155 memset(directional_mode_skip_mask, 0,
2156 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
2157#if CONFIG_VP9_HIGHBITDEPTH
2158 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
2159 highbd_angle_estimation(src, src_stride, rows, cols, hist);
2160 else
2161#endif
2162 angle_estimation(src, src_stride, rows, cols, hist);
2163
2164 for (mode = 0; mode < INTRA_MODES; ++mode) {
2165 if (mode != DC_PRED && mode != TM_PRED) {
2166 int index = get_angle_index((double)mode_to_angle_map[mode]);
2167 double score, weight = 1.0;
2168 score = hist[index];
2169 if (index > 0) {
2170 score += hist[index - 1] * 0.5;
2171 weight += 0.5;
2172 }
2173 if (index < DIRECTIONAL_MODES - 1) {
2174 score += hist[index + 1] * 0.5;
2175 weight += 0.5;
2176 }
2177 score /= weight;
2178 if (score < ANGLE_SKIP_THRESH)
2179 directional_mode_skip_mask[mode] = 1;
2180 }
2181 }
hui sube3559b2015-10-07 09:29:02 -07002182#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07002183 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
hui suc93e5cc2015-12-07 18:18:57 -08002184 palette_mode_info.palette_size[0] = 0;
2185 mic->mbmi.palette_mode_info.palette_size[0] = 0;
2186 if (above_mi)
2187 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
2188 if (left_mi)
2189 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
hui su5d011cb2015-09-15 12:44:13 -07002190
Jingning Han3ee6db62015-08-05 19:00:31 -07002191 /* Y Search for intra prediction mode */
hui sube3559b2015-10-07 09:29:02 -07002192 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
Jingning Han3ee6db62015-08-05 19:00:31 -07002193 mic->mbmi.mode = mode;
hui su4aa50c12015-11-10 12:09:59 -08002194#if CONFIG_EXT_INTRA
2195 is_directional_mode = (mode != DC_PRED && mode != TM_PRED);
hui sud7c8bc72015-11-12 19:18:32 -08002196 if (is_directional_mode && directional_mode_skip_mask[mode])
2197 continue;
hui su4aa50c12015-11-10 12:09:59 -08002198 if (is_directional_mode) {
hui sud7c8bc72015-11-12 19:18:32 -08002199 rate_overhead = bmode_costs[mode] +
2200 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
2201 this_rate_tokenonly = INT_MAX;
2202 this_rd =
2203 rd_pick_intra_angle_sby(cpi, x, &this_rate, &this_rate_tokenonly,
2204 &this_distortion, &s, bsize, rate_overhead,
2205 best_rd);
hui su4aa50c12015-11-10 12:09:59 -08002206 } else {
2207 mic->mbmi.angle_delta[0] = 0;
2208 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
2209 &s, NULL, bsize, best_rd);
2210 }
2211#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07002212 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
hui su4aa50c12015-11-10 12:09:59 -08002213 &s, NULL, bsize, best_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07002214
2215 if (this_rate_tokenonly == INT_MAX)
2216 continue;
2217
2218 this_rate = this_rate_tokenonly + bmode_costs[mode];
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08002219
2220 if (!xd->lossless[xd->mi[0]->mbmi.segment_id]) {
2221 // super_block_yrd above includes the cost of the tx_size in the
2222 // tokenonly rate, but for intra blocks, tx_size is always coded
2223 // (prediction granularity), so we account for it in the full rate,
2224 // not the tokenonly rate.
2225 this_rate_tokenonly -= vp10_cost_tx_size(mic->mbmi.tx_size, max_tx_size,
2226 tx_probs);
2227 }
hui suc93e5cc2015-12-07 18:18:57 -08002228 if (cpi->common.allow_screen_content_tools && mode == DC_PRED)
2229 this_rate +=
2230 vp10_cost_bit(vp10_default_palette_y_mode_prob[bsize - BLOCK_8X8]
2231 [palette_ctx], 0);
hui sube3559b2015-10-07 09:29:02 -07002232#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08002233 if (mode == DC_PRED && ALLOW_FILTER_INTRA_MODES)
hui sube3559b2015-10-07 09:29:02 -07002234 this_rate += vp10_cost_bit(cpi->common.fc->ext_intra_probs[0], 0);
hui su3b1c7662016-01-12 16:38:58 -08002235 if (is_directional_mode) {
2236 int p_angle;
hui su4aa50c12015-11-10 12:09:59 -08002237 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
2238 MAX_ANGLE_DELTAS +
2239 mic->mbmi.angle_delta[0]);
hui su3b1c7662016-01-12 16:38:58 -08002240 p_angle = mode_to_angle_map[mic->mbmi.mode] +
2241 mic->mbmi.angle_delta[0] * ANGLE_STEP;
2242 if (pick_intra_filter(p_angle))
2243 this_rate +=
2244 cpi->intra_filter_cost[intra_filter_ctx][mic->mbmi.intra_filter];
2245 }
hui sube3559b2015-10-07 09:29:02 -07002246#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07002247 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
2248
2249 if (this_rd < best_rd) {
2250 mode_selected = mode;
2251 best_rd = this_rd;
2252 best_tx = mic->mbmi.tx_size;
hui su4aa50c12015-11-10 12:09:59 -08002253#if CONFIG_EXT_INTRA
2254 best_angle_delta = mic->mbmi.angle_delta[0];
hui su3b1c7662016-01-12 16:38:58 -08002255 best_filter = mic->mbmi.intra_filter;
hui su4aa50c12015-11-10 12:09:59 -08002256#endif // CONFIG_EXT_INTRA
hui su4f16f112015-10-02 10:45:27 -07002257 best_tx_type = mic->mbmi.tx_type;
Jingning Han3ee6db62015-08-05 19:00:31 -07002258 *rate = this_rate;
2259 *rate_tokenonly = this_rate_tokenonly;
2260 *distortion = this_distortion;
2261 *skippable = s;
2262 }
2263 }
2264
hui suc93e5cc2015-12-07 18:18:57 -08002265 if (cpi->common.allow_screen_content_tools)
2266 rd_pick_palette_intra_sby(cpi, x, bsize, palette_ctx, bmode_costs[DC_PRED],
2267 &palette_mode_info, best_palette_color_map,
2268 &best_tx, &mode_selected, &best_rd);
2269
hui sube3559b2015-10-07 09:29:02 -07002270#if CONFIG_EXT_INTRA
hui suc93e5cc2015-12-07 18:18:57 -08002271 if (!palette_mode_info.palette_size[0] > 0 && ALLOW_FILTER_INTRA_MODES) {
2272 if (rd_pick_ext_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
2273 skippable, bsize, bmode_costs[DC_PRED],
2274 &best_rd)) {
2275 mode_selected = mic->mbmi.mode;
2276 best_tx = mic->mbmi.tx_size;
2277 ext_intra_mode_info = mic->mbmi.ext_intra_mode_info;
hui suc93e5cc2015-12-07 18:18:57 -08002278 best_tx_type = mic->mbmi.tx_type;
hui suc93e5cc2015-12-07 18:18:57 -08002279 }
hui sube3559b2015-10-07 09:29:02 -07002280 }
2281
2282 mic->mbmi.ext_intra_mode_info.use_ext_intra_mode[0] =
2283 ext_intra_mode_info.use_ext_intra_mode[0];
2284 if (ext_intra_mode_info.use_ext_intra_mode[0]) {
2285 mic->mbmi.ext_intra_mode_info.ext_intra_mode[0] =
2286 ext_intra_mode_info.ext_intra_mode[0];
hui sube3559b2015-10-07 09:29:02 -07002287 }
2288#endif // CONFIG_EXT_INTRA
2289
Jingning Han3ee6db62015-08-05 19:00:31 -07002290 mic->mbmi.mode = mode_selected;
2291 mic->mbmi.tx_size = best_tx;
hui su4aa50c12015-11-10 12:09:59 -08002292#if CONFIG_EXT_INTRA
2293 mic->mbmi.angle_delta[0] = best_angle_delta;
hui su3b1c7662016-01-12 16:38:58 -08002294 mic->mbmi.intra_filter = best_filter;
hui su4aa50c12015-11-10 12:09:59 -08002295#endif // CONFIG_EXT_INTRA
hui su4f16f112015-10-02 10:45:27 -07002296 mic->mbmi.tx_type = best_tx_type;
hui suc93e5cc2015-12-07 18:18:57 -08002297 mic->mbmi.palette_mode_info.palette_size[0] =
2298 palette_mode_info.palette_size[0];
2299 if (palette_mode_info.palette_size[0] > 0) {
2300 memcpy(mic->mbmi.palette_mode_info.palette_colors,
2301 palette_mode_info.palette_colors,
2302 PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
2303 memcpy(xd->plane[0].color_index_map, best_palette_color_map,
2304 rows * cols * sizeof(best_palette_color_map[0]));
2305 }
Jingning Han3ee6db62015-08-05 19:00:31 -07002306
2307 return best_rd;
2308}
2309
Jingning Hana8dad552015-10-08 16:46:10 -07002310#if CONFIG_VAR_TX
Jingning Han4c6c82a2016-02-09 17:51:49 -08002311void vp10_tx_block_rd_b(const VP10_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
2312 int blk_row, int blk_col, int plane, int block,
2313 int plane_bsize, int coeff_ctx,
2314 int *rate, int64_t *dist, int64_t *bsse, int *skip) {
Jingning Han2cdc1272015-10-09 09:57:42 -07002315 MACROBLOCKD *xd = &x->e_mbd;
2316 const struct macroblock_plane *const p = &x->plane[plane];
2317 struct macroblockd_plane *const pd = &xd->plane[plane];
Jingning Han71c15602015-10-13 12:40:39 -07002318#if CONFIG_VP9_HIGHBITDEPTH
Jingning Han2cdc1272015-10-09 09:57:42 -07002319 const int ss_txfrm_size = tx_size << 1;
2320 int64_t this_sse;
2321 int shift = tx_size == TX_32X32 ? 0 : 2;
2322 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
Jingning Han71c15602015-10-13 12:40:39 -07002323#endif
2324 unsigned int tmp_sse = 0;
Jingning Han2cdc1272015-10-09 09:57:42 -07002325 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
2326 PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
2327 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
2328 const scan_order *const scan_order =
2329 get_scan(tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
2330
Jingning Han71c15602015-10-13 12:40:39 -07002331 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
2332 int bh = 4 * num_4x4_blocks_wide_lookup[txm_bsize];
2333 int src_stride = p->src.stride;
2334 uint8_t *src = &p->src.buf[4 * blk_row * src_stride + 4 * blk_col];
2335 uint8_t *dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
Peter de Rivaz22850492015-12-08 15:58:21 +00002336#if CONFIG_VP9_HIGHBITDEPTH
2337 DECLARE_ALIGNED(16, uint16_t, rec_buffer_alloc_16[32 * 32]);
2338 uint8_t *rec_buffer;
2339#else
Jingning Han71c15602015-10-13 12:40:39 -07002340 DECLARE_ALIGNED(16, uint8_t, rec_buffer[32 * 32]);
Peter de Rivaz22850492015-12-08 15:58:21 +00002341#endif
Jingning Han71c15602015-10-13 12:40:39 -07002342
2343 int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
2344 int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
2345
2346 if (xd->mb_to_bottom_edge < 0)
2347 max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
2348 if (xd->mb_to_right_edge < 0)
2349 max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
2350
Angie Chiang88cae8b2015-11-25 13:07:13 -08002351 vp10_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
2352 VP10_XFORM_QUANT_B);
Jingning Han2cdc1272015-10-09 09:57:42 -07002353
Peter de Rivaz22850492015-12-08 15:58:21 +00002354#if CONFIG_VP9_HIGHBITDEPTH
2355 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2356 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer_alloc_16);
2357 vpx_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, 32,
2358 NULL, 0, NULL, 0, bh, bh, xd->bd);
2359 } else {
2360 rec_buffer = (uint8_t *)rec_buffer_alloc_16;
2361 vpx_convolve_copy(dst, pd->dst.stride, rec_buffer, 32,
2362 NULL, 0, NULL, 0, bh, bh);
2363 }
2364#else
Jingning Han71c15602015-10-13 12:40:39 -07002365 vpx_convolve_copy(dst, pd->dst.stride, rec_buffer, 32,
2366 NULL, 0, NULL, 0, bh, bh);
Peter de Rivaz22850492015-12-08 15:58:21 +00002367#endif
Jingning Han71c15602015-10-13 12:40:39 -07002368
2369 if (blk_row + (bh >> 2) > max_blocks_high ||
2370 blk_col + (bh >> 2) > max_blocks_wide) {
2371 int idx, idy;
2372 unsigned int this_sse;
2373 int blocks_height = VPXMIN(bh >> 2, max_blocks_high - blk_row);
2374 int blocks_width = VPXMIN(bh >> 2, max_blocks_wide - blk_col);
2375 for (idy = 0; idy < blocks_height; idy += 2) {
2376 for (idx = 0; idx < blocks_width; idx += 2) {
2377 cpi->fn_ptr[BLOCK_8X8].vf(src + 4 * idy * src_stride + 4 * idx,
2378 src_stride,
2379 rec_buffer + 4 * idy * 32 + 4 * idx,
2380 32, &this_sse);
2381 tmp_sse += this_sse;
2382 }
2383 }
2384 } else {
2385 cpi->fn_ptr[txm_bsize].vf(src, src_stride, rec_buffer, 32, &tmp_sse);
2386 }
2387
Jingning Han2cdc1272015-10-09 09:57:42 -07002388#if CONFIG_VP9_HIGHBITDEPTH
2389 *dist += vp10_highbd_block_error(coeff, dqcoeff, 16 << ss_txfrm_size,
2390 &this_sse, xd->bd) >> shift;
Jingning Han2cdc1272015-10-09 09:57:42 -07002391 *bsse += this_sse >> shift;
Jingning Han71c15602015-10-13 12:40:39 -07002392#else
2393 *bsse += (int64_t)tmp_sse * 16;
2394
2395 if (p->eobs[block] > 0) {
Jingning Han71c15602015-10-13 12:40:39 -07002396 switch (tx_size) {
2397 case TX_32X32:
2398 vp10_inv_txfm_add_32x32(dqcoeff, rec_buffer, 32, p->eobs[block],
2399 tx_type);
2400 break;
2401 case TX_16X16:
2402 vp10_inv_txfm_add_16x16(dqcoeff, rec_buffer, 32, p->eobs[block],
2403 tx_type);
2404 break;
2405 case TX_8X8:
2406 vp10_inv_txfm_add_8x8(dqcoeff, rec_buffer, 32, p->eobs[block],
2407 tx_type);
2408 break;
2409 case TX_4X4:
2410 vp10_inv_txfm_add_4x4(dqcoeff, rec_buffer, 32, p->eobs[block],
2411 tx_type,
2412 xd->lossless[xd->mi[0]->mbmi.segment_id]);
2413 break;
2414 default:
2415 assert(0 && "Invalid transform size");
2416 break;
2417 }
2418
2419 if ((bh >> 2) + blk_col > max_blocks_wide ||
2420 (bh >> 2) + blk_row > max_blocks_high) {
2421 int idx, idy;
2422 unsigned int this_sse;
2423 int blocks_height = VPXMIN(bh >> 2, max_blocks_high - blk_row);
2424 int blocks_width = VPXMIN(bh >> 2, max_blocks_wide - blk_col);
2425 tmp_sse = 0;
2426 for (idy = 0; idy < blocks_height; idy += 2) {
2427 for (idx = 0; idx < blocks_width; idx += 2) {
2428 cpi->fn_ptr[BLOCK_8X8].vf(src + 4 * idy * src_stride + 4 * idx,
2429 src_stride,
2430 rec_buffer + 4 * idy * 32 + 4 * idx,
2431 32, &this_sse);
2432 tmp_sse += this_sse;
2433 }
2434 }
2435 } else {
2436 cpi->fn_ptr[txm_bsize].vf(src, src_stride,
2437 rec_buffer, 32, &tmp_sse);
2438 }
2439 }
2440 *dist += (int64_t)tmp_sse * 16;
2441#endif // CONFIG_VP9_HIGHBITDEPTH
Jingning Han2cdc1272015-10-09 09:57:42 -07002442
2443 *rate += cost_coeffs(x, plane, block, coeff_ctx, tx_size,
2444 scan_order->scan, scan_order->neighbors, 0);
2445 *skip &= (p->eobs[block] == 0);
2446}
2447
2448static void select_tx_block(const VP10_COMP *cpi, MACROBLOCK *x,
2449 int blk_row, int blk_col, int plane, int block,
2450 TX_SIZE tx_size, BLOCK_SIZE plane_bsize,
Jingning Han2cdc1272015-10-09 09:57:42 -07002451 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
Jingning Han3edad6e2015-10-14 09:38:17 -07002452 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
Jingning Han2cdc1272015-10-09 09:57:42 -07002453 int *rate, int64_t *dist,
Jingning Han1e48f742015-10-13 11:59:49 -07002454 int64_t *bsse, int *skip,
2455 int64_t ref_best_rd, int *is_cost_valid) {
Jingning Han2cdc1272015-10-09 09:57:42 -07002456 MACROBLOCKD *const xd = &x->e_mbd;
2457 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2458 struct macroblock_plane *const p = &x->plane[plane];
2459 struct macroblockd_plane *const pd = &xd->plane[plane];
2460 int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
2461 (blk_col >> (1 - pd->subsampling_x));
2462 int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
2463 int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
2464 int64_t this_rd = INT64_MAX;
Jingning Han2cdc1272015-10-09 09:57:42 -07002465 ENTROPY_CONTEXT *pta = ta + blk_col;
2466 ENTROPY_CONTEXT *ptl = tl + blk_row;
Jingning Han3a279612015-10-12 19:20:58 -07002467 ENTROPY_CONTEXT stxa = 0, stxl = 0;
Jingning Han2cdc1272015-10-09 09:57:42 -07002468 int coeff_ctx, i;
Jingning Han3edad6e2015-10-14 09:38:17 -07002469 int ctx = txfm_partition_context(tx_above + (blk_col >> 1),
2470 tx_left + (blk_row >> 1), tx_size);
2471
Jingning Han3a279612015-10-12 19:20:58 -07002472 int64_t sum_dist = 0, sum_bsse = 0;
2473 int64_t sum_rd = INT64_MAX;
Jingning Han3edad6e2015-10-14 09:38:17 -07002474 int sum_rate = vp10_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Jingning Han3a279612015-10-12 19:20:58 -07002475 int all_skip = 1;
Jingning Han1e48f742015-10-13 11:59:49 -07002476 int tmp_eob = 0;
Jingning Hanbfeac5e2015-10-15 23:11:30 -07002477 int zero_blk_rate;
Jingning Han1e48f742015-10-13 11:59:49 -07002478
2479 if (ref_best_rd < 0) {
2480 *is_cost_valid = 0;
2481 return;
2482 }
Jingning Han2cdc1272015-10-09 09:57:42 -07002483
2484 switch (tx_size) {
2485 case TX_4X4:
Jingning Han3a279612015-10-12 19:20:58 -07002486 stxa = pta[0];
2487 stxl = ptl[0];
Jingning Han2cdc1272015-10-09 09:57:42 -07002488 break;
2489 case TX_8X8:
Jingning Han3a279612015-10-12 19:20:58 -07002490 stxa = !!*(const uint16_t *)&pta[0];
2491 stxl = !!*(const uint16_t *)&ptl[0];
Jingning Han2cdc1272015-10-09 09:57:42 -07002492 break;
2493 case TX_16X16:
Jingning Han3a279612015-10-12 19:20:58 -07002494 stxa = !!*(const uint32_t *)&pta[0];
2495 stxl = !!*(const uint32_t *)&ptl[0];
Jingning Han2cdc1272015-10-09 09:57:42 -07002496 break;
2497 case TX_32X32:
Jingning Han3a279612015-10-12 19:20:58 -07002498 stxa = !!*(const uint64_t *)&pta[0];
2499 stxl = !!*(const uint64_t *)&ptl[0];
Jingning Han2cdc1272015-10-09 09:57:42 -07002500 break;
2501 default:
2502 assert(0 && "Invalid transform size.");
2503 break;
2504 }
Jingning Han3a279612015-10-12 19:20:58 -07002505 coeff_ctx = combine_entropy_contexts(stxa, stxl);
Jingning Han2cdc1272015-10-09 09:57:42 -07002506
2507 if (xd->mb_to_bottom_edge < 0)
2508 max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
2509 if (xd->mb_to_right_edge < 0)
2510 max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
2511
2512 *rate = 0;
2513 *dist = 0;
2514 *bsse = 0;
2515 *skip = 1;
2516
2517 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
2518 return;
2519
Jingning Hanbfeac5e2015-10-15 23:11:30 -07002520 zero_blk_rate =
2521 x->token_costs[tx_size][pd->plane_type][1][0][0][coeff_ctx][EOB_TOKEN];
2522
Jingning Han1e48f742015-10-13 11:59:49 -07002523 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
2524 mbmi->inter_tx_size[tx_idx] = tx_size;
Jingning Han4c6c82a2016-02-09 17:51:49 -08002525 vp10_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
2526 plane_bsize, coeff_ctx, rate, dist, bsse, skip);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07002527
Jingning Han47c7fd92015-10-30 13:00:48 -07002528 if ((RDCOST(x->rdmult, x->rddiv, *rate, *dist) >=
2529 RDCOST(x->rdmult, x->rddiv, zero_blk_rate, *bsse) || *skip == 1) &&
Jingning Hanbfeac5e2015-10-15 23:11:30 -07002530 !xd->lossless[mbmi->segment_id]) {
2531 *rate = zero_blk_rate;
2532 *dist = *bsse;
2533 *skip = 1;
2534 x->blk_skip[plane][blk_row * max_blocks_wide + blk_col] = 1;
2535 p->eobs[block] = 0;
2536 } else {
2537 x->blk_skip[plane][blk_row * max_blocks_wide + blk_col] = 0;
2538 *skip = 0;
2539 }
2540
Jingning Han1e48f742015-10-13 11:59:49 -07002541 if (tx_size > TX_4X4)
Jingning Han3edad6e2015-10-14 09:38:17 -07002542 *rate += vp10_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
Jingning Han1e48f742015-10-13 11:59:49 -07002543 this_rd = RDCOST(x->rdmult, x->rddiv, *rate, *dist);
2544 tmp_eob = p->eobs[block];
2545 }
2546
Jingning Han2cdc1272015-10-09 09:57:42 -07002547 if (tx_size > TX_4X4) {
2548 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
Jingning Han3a279612015-10-12 19:20:58 -07002549 int bsl = b_height_log2_lookup[bsize];
Jingning Han2cdc1272015-10-09 09:57:42 -07002550 int sub_step = 1 << (2 * (tx_size - 1));
2551 int i;
Jingning Han3a279612015-10-12 19:20:58 -07002552 int this_rate;
2553 int64_t this_dist;
2554 int64_t this_bsse;
2555 int this_skip;
Jingning Han1e48f742015-10-13 11:59:49 -07002556 int this_cost_valid = 1;
2557 int64_t tmp_rd = 0;
Jingning Han3a279612015-10-12 19:20:58 -07002558
2559 --bsl;
Jingning Han236623c2015-10-26 19:39:30 -07002560 for (i = 0; i < 4 && this_cost_valid; ++i) {
Jingning Han3a279612015-10-12 19:20:58 -07002561 int offsetr = (i >> 1) << bsl;
2562 int offsetc = (i & 0x01) << bsl;
Jingning Han2cdc1272015-10-09 09:57:42 -07002563 select_tx_block(cpi, x, blk_row + offsetr, blk_col + offsetc,
2564 plane, block + i * sub_step, tx_size - 1,
Jingning Han3edad6e2015-10-14 09:38:17 -07002565 plane_bsize, ta, tl, tx_above, tx_left,
2566 &this_rate, &this_dist,
Jingning Han1e48f742015-10-13 11:59:49 -07002567 &this_bsse, &this_skip,
2568 ref_best_rd - tmp_rd, &this_cost_valid);
Jingning Han2cdc1272015-10-09 09:57:42 -07002569 sum_rate += this_rate;
2570 sum_dist += this_dist;
2571 sum_bsse += this_bsse;
2572 all_skip &= this_skip;
Peter de Rivaz2f943132016-01-05 15:35:43 +00002573 tmp_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
Jingning Han1e48f742015-10-13 11:59:49 -07002574 if (this_rd < tmp_rd)
2575 break;
Jingning Han2cdc1272015-10-09 09:57:42 -07002576 }
Jingning Han1e48f742015-10-13 11:59:49 -07002577 if (this_cost_valid)
2578 sum_rd = tmp_rd;
Jingning Han3a279612015-10-12 19:20:58 -07002579 }
2580
2581 if (this_rd < sum_rd) {
Jingning Han79fe7242015-10-23 14:27:21 -07002582 int idx, idy;
Jingning Han3a279612015-10-12 19:20:58 -07002583 for (i = 0; i < (1 << tx_size); ++i)
Jingning Han1e48f742015-10-13 11:59:49 -07002584 pta[i] = ptl[i] = !(tmp_eob == 0);
Jingning Han3edad6e2015-10-14 09:38:17 -07002585 txfm_partition_update(tx_above + (blk_col >> 1),
2586 tx_left + (blk_row >> 1), tx_size);
Jingning Han1e48f742015-10-13 11:59:49 -07002587 mbmi->inter_tx_size[tx_idx] = tx_size;
Jingning Han79fe7242015-10-23 14:27:21 -07002588
2589 for (idy = 0; idy < (1 << tx_size) / 2; ++idy)
2590 for (idx = 0; idx < (1 << tx_size) / 2; ++idx)
2591 mbmi->inter_tx_size[tx_idx + (idy << 3) + idx] = tx_size;
Jingning Han3a279612015-10-12 19:20:58 -07002592 mbmi->tx_size = tx_size;
Jingning Han236623c2015-10-26 19:39:30 -07002593 if (this_rd == INT64_MAX)
2594 *is_cost_valid = 0;
Jingning Hanbfeac5e2015-10-15 23:11:30 -07002595 x->blk_skip[plane][blk_row * max_blocks_wide + blk_col] = *skip;
Jingning Han3a279612015-10-12 19:20:58 -07002596 } else {
2597 *rate = sum_rate;
2598 *dist = sum_dist;
2599 *bsse = sum_bsse;
2600 *skip = all_skip;
Jingning Han236623c2015-10-26 19:39:30 -07002601 if (sum_rd == INT64_MAX)
2602 *is_cost_valid = 0;
Jingning Han2cdc1272015-10-09 09:57:42 -07002603 }
2604}
2605
2606static void inter_block_yrd(const VP10_COMP *cpi, MACROBLOCK *x,
2607 int *rate, int64_t *distortion, int *skippable,
2608 int64_t *sse, BLOCK_SIZE bsize,
2609 int64_t ref_best_rd) {
2610 MACROBLOCKD *const xd = &x->e_mbd;
2611 int is_cost_valid = 1;
Jingning Han1e48f742015-10-13 11:59:49 -07002612 int64_t this_rd = 0;
Jingning Han2cdc1272015-10-09 09:57:42 -07002613
2614 if (ref_best_rd < 0)
2615 is_cost_valid = 0;
2616
2617 *rate = 0;
2618 *distortion = 0;
2619 *sse = 0;
2620 *skippable = 1;
2621
2622 if (is_cost_valid) {
2623 const struct macroblockd_plane *const pd = &xd->plane[0];
2624 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
2625 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
2626 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
2627 BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[plane_bsize]];
2628 int bh = num_4x4_blocks_wide_lookup[txb_size];
2629 int idx, idy;
2630 int block = 0;
2631 int step = 1 << (max_txsize_lookup[plane_bsize] * 2);
2632 ENTROPY_CONTEXT ctxa[16], ctxl[16];
Jingning Han3edad6e2015-10-14 09:38:17 -07002633 TXFM_CONTEXT tx_above[8], tx_left[8];
Jingning Han2cdc1272015-10-09 09:57:42 -07002634
2635 int pnrate = 0, pnskip = 1;
2636 int64_t pndist = 0, pnsse = 0;
2637
2638 vp10_get_entropy_contexts(bsize, TX_4X4, pd, ctxa, ctxl);
Jingning Han3edad6e2015-10-14 09:38:17 -07002639 memcpy(tx_above, xd->above_txfm_context,
2640 sizeof(TXFM_CONTEXT) * (mi_width >> 1));
2641 memcpy(tx_left, xd->left_txfm_context,
2642 sizeof(TXFM_CONTEXT) * (mi_height >> 1));
Jingning Han2cdc1272015-10-09 09:57:42 -07002643
2644 for (idy = 0; idy < mi_height; idy += bh) {
2645 for (idx = 0; idx < mi_width; idx += bh) {
2646 select_tx_block(cpi, x, idy, idx, 0, block,
Jingning Han3a279612015-10-12 19:20:58 -07002647 max_txsize_lookup[plane_bsize], plane_bsize,
Jingning Han3edad6e2015-10-14 09:38:17 -07002648 ctxa, ctxl, tx_above, tx_left,
2649 &pnrate, &pndist, &pnsse, &pnskip,
Jingning Han1e48f742015-10-13 11:59:49 -07002650 ref_best_rd - this_rd, &is_cost_valid);
Jingning Han2cdc1272015-10-09 09:57:42 -07002651 *rate += pnrate;
2652 *distortion += pndist;
2653 *sse += pnsse;
2654 *skippable &= pnskip;
Jingning Han1e48f742015-10-13 11:59:49 -07002655 this_rd += VPXMIN(RDCOST(x->rdmult, x->rddiv, pnrate, pndist),
2656 RDCOST(x->rdmult, x->rddiv, 0, pnsse));
Jingning Han2cdc1272015-10-09 09:57:42 -07002657 block += step;
2658 }
2659 }
2660 }
2661
2662 this_rd = VPXMIN(RDCOST(x->rdmult, x->rddiv, *rate, *distortion),
2663 RDCOST(x->rdmult, x->rddiv, 0, *sse));
2664 if (this_rd > ref_best_rd)
2665 is_cost_valid = 0;
2666
2667 if (!is_cost_valid) {
2668 // reset cost value
2669 *rate = INT_MAX;
2670 *distortion = INT64_MAX;
2671 *sse = INT64_MAX;
2672 *skippable = 0;
2673 }
2674}
2675
Jingning Han4b594d32015-11-02 12:05:47 -08002676static void select_tx_type_yrd(const VP10_COMP *cpi, MACROBLOCK *x,
2677 int *rate, int64_t *distortion, int *skippable,
2678 int64_t *sse, BLOCK_SIZE bsize,
2679 int64_t ref_best_rd) {
2680 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
2681 const VP10_COMMON *const cm = &cpi->common;
2682 MACROBLOCKD *const xd = &x->e_mbd;
2683 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2684 int64_t rd = INT64_MAX;
2685 int64_t best_rd = INT64_MAX;
2686 TX_TYPE tx_type, best_tx_type = DCT_DCT;
Jingning Han4b594d32015-11-02 12:05:47 -08002687 const int is_inter = is_inter_block(mbmi);
2688 vpx_prob skip_prob = vp10_get_skip_prob(cm, xd);
2689 int s0 = vp10_cost_bit(skip_prob, 0);
2690 int s1 = vp10_cost_bit(skip_prob, 1);
Jingning Han696ee002015-11-03 08:56:47 -08002691 TX_SIZE best_tx_size[64];
Jingning Han493d0232015-11-03 12:59:24 -08002692 TX_SIZE best_tx = TX_SIZES;
2693 uint8_t best_blk_skip[256];
2694 const int n4 = 1 << (num_pels_log2_lookup[bsize] - 4);
Jingning Han696ee002015-11-03 08:56:47 -08002695 int idx, idy;
Julia Robson9fe188e2016-01-21 17:14:29 +00002696#if CONFIG_EXT_TX
2697 int ext_tx_set = get_ext_tx_set(max_tx_size, bsize, is_inter);
2698#endif
Jingning Han4b594d32015-11-02 12:05:47 -08002699
2700 *distortion = INT64_MAX;
2701 *rate = INT_MAX;
2702 *skippable = 0;
2703 *sse = INT64_MAX;
2704
2705 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
2706 int this_rate = 0;
2707 int this_skip = 1;
2708 int64_t this_dist = 0;
2709 int64_t this_sse = 0;
Julia Robson9fe188e2016-01-21 17:14:29 +00002710#if CONFIG_EXT_TX
Jingning Han4b594d32015-11-02 12:05:47 -08002711 if (is_inter) {
2712 if (!ext_tx_used_inter[ext_tx_set][tx_type])
2713 continue;
2714 } else {
hui sud894d342015-11-18 11:24:26 -08002715 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
Yaowu Xu0367f322016-01-11 10:27:35 -08002716 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode])
hui sud894d342015-11-18 11:24:26 -08002717 continue;
2718 }
Jingning Han4b594d32015-11-02 12:05:47 -08002719 if (!ext_tx_used_intra[ext_tx_set][tx_type])
2720 continue;
2721 }
2722
2723 mbmi->tx_type = tx_type;
2724
2725 if (ext_tx_set == 1 &&
2726 mbmi->tx_type >= DST_ADST && mbmi->tx_type < IDTX &&
2727 best_tx_type == DCT_DCT) {
2728 tx_type = IDTX - 1;
2729 break;
2730 }
2731
2732 inter_block_yrd(cpi, x, &this_rate, &this_dist, &this_skip, &this_sse,
2733 bsize, ref_best_rd);
2734
2735 if (get_ext_tx_types(max_tx_size, bsize, is_inter) > 1 &&
2736 !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
2737 this_rate != INT_MAX) {
2738 if (is_inter) {
2739 if (ext_tx_set > 0)
2740 this_rate += cpi->inter_tx_type_costs[ext_tx_set]
Jingning Han696ee002015-11-03 08:56:47 -08002741 [max_tx_size][mbmi->tx_type];
Jingning Han4b594d32015-11-02 12:05:47 -08002742 } else {
hui sud894d342015-11-18 11:24:26 -08002743 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Jingning Han696ee002015-11-03 08:56:47 -08002744 this_rate += cpi->intra_tx_type_costs[ext_tx_set][max_tx_size]
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08002745 [mbmi->mode][mbmi->tx_type];
Jingning Han4b594d32015-11-02 12:05:47 -08002746 }
2747 }
Julia Robson9fe188e2016-01-21 17:14:29 +00002748#else // CONFIG_EXT_TX
Jingning Han5c772f32016-02-10 11:33:37 -08002749 if (max_tx_size >= TX_32X32 && tx_type != DCT_DCT)
Julia Robson9fe188e2016-01-21 17:14:29 +00002750 continue;
Jingning Han5c772f32016-02-10 11:33:37 -08002751
Julia Robson9fe188e2016-01-21 17:14:29 +00002752 mbmi->tx_type = tx_type;
2753
2754 inter_block_yrd(cpi, x, &this_rate, &this_dist, &this_skip, &this_sse,
2755 bsize, ref_best_rd);
2756
2757 if (max_tx_size < TX_32X32 &&
2758 !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
2759 this_rate != INT_MAX) {
2760 if (is_inter)
2761 this_rate += cpi->inter_tx_type_costs[max_tx_size][mbmi->tx_type];
2762 else
2763 this_rate += cpi->intra_tx_type_costs[max_tx_size]
2764 [intra_mode_to_tx_type_context[mbmi->mode]]
2765 [mbmi->tx_type];
2766 }
2767#endif // CONFIG_EXT_TX
Jingning Han4b594d32015-11-02 12:05:47 -08002768
2769 if (this_rate == INT_MAX)
2770 continue;
2771
2772 if (this_skip)
2773 rd = RDCOST(x->rdmult, x->rddiv, s1, this_sse);
2774 else
2775 rd = RDCOST(x->rdmult, x->rddiv, this_rate + s0, this_dist);
2776
2777 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] && !this_skip)
2778 rd = VPXMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, this_sse));
2779
Jingning Han5c772f32016-02-10 11:33:37 -08002780 if (rd < (is_inter && best_tx_type == DCT_DCT ? ext_tx_th : 1) * best_rd) {
Jingning Han4b594d32015-11-02 12:05:47 -08002781 best_rd = rd;
2782 *distortion = this_dist;
2783 *rate = this_rate;
2784 *skippable = this_skip;
2785 *sse = this_sse;
2786 best_tx_type = mbmi->tx_type;
Jingning Han493d0232015-11-03 12:59:24 -08002787 best_tx = mbmi->tx_size;
2788 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
Jingning Han696ee002015-11-03 08:56:47 -08002789 for (idy = 0; idy < xd->n8_h; ++idy)
2790 for (idx = 0; idx < xd->n8_w; ++idx)
2791 best_tx_size[idy * 8 + idx] = mbmi->inter_tx_size[idy * 8 + idx];
Jingning Han4b594d32015-11-02 12:05:47 -08002792 }
2793 }
2794
2795 mbmi->tx_type = best_tx_type;
Jingning Han696ee002015-11-03 08:56:47 -08002796 for (idy = 0; idy < xd->n8_h; ++idy)
2797 for (idx = 0; idx < xd->n8_w; ++idx)
2798 mbmi->inter_tx_size[idy * 8 + idx] = best_tx_size[idy * 8 + idx];
Jingning Han493d0232015-11-03 12:59:24 -08002799 mbmi->tx_size = best_tx;
2800 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
Jingning Han4b594d32015-11-02 12:05:47 -08002801}
Jingning Han4b594d32015-11-02 12:05:47 -08002802
Jingning Hana8dad552015-10-08 16:46:10 -07002803static void tx_block_rd(const VP10_COMP *cpi, MACROBLOCK *x,
2804 int blk_row, int blk_col, int plane, int block,
2805 TX_SIZE tx_size, BLOCK_SIZE plane_bsize,
2806 ENTROPY_CONTEXT *above_ctx, ENTROPY_CONTEXT *left_ctx,
2807 int *rate, int64_t *dist, int64_t *bsse, int *skip) {
2808 MACROBLOCKD *const xd = &x->e_mbd;
2809 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Jingning Han2cdc1272015-10-09 09:57:42 -07002810 struct macroblock_plane *const p = &x->plane[plane];
Jingning Hana8dad552015-10-08 16:46:10 -07002811 struct macroblockd_plane *const pd = &xd->plane[plane];
Jingning Han2cdc1272015-10-09 09:57:42 -07002812 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
Jingning Hana8dad552015-10-08 16:46:10 -07002813 int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
2814 (blk_col >> (1 - pd->subsampling_x));
2815 TX_SIZE plane_tx_size = plane ?
Jingning Han2cdc1272015-10-09 09:57:42 -07002816 get_uv_tx_size_impl(mbmi->inter_tx_size[tx_idx], bsize,
2817 0, 0) :
Jingning Hana8dad552015-10-08 16:46:10 -07002818 mbmi->inter_tx_size[tx_idx];
2819
2820 int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
2821 int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
2822
2823 if (xd->mb_to_bottom_edge < 0)
2824 max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
2825 if (xd->mb_to_right_edge < 0)
2826 max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
2827
2828 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
2829 return;
2830
2831 if (tx_size == plane_tx_size) {
Jingning Han2cdc1272015-10-09 09:57:42 -07002832 int coeff_ctx, i;
Jingning Hana8dad552015-10-08 16:46:10 -07002833 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
Jingning Han2cdc1272015-10-09 09:57:42 -07002834 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
Jingning Hana8dad552015-10-08 16:46:10 -07002835 switch (tx_size) {
2836 case TX_4X4:
2837 break;
2838 case TX_8X8:
2839 ta[0] = !!*(const uint16_t *)&ta[0];
2840 tl[0] = !!*(const uint16_t *)&tl[0];
2841 break;
2842 case TX_16X16:
2843 ta[0] = !!*(const uint32_t *)&ta[0];
2844 tl[0] = !!*(const uint32_t *)&tl[0];
2845 break;
2846 case TX_32X32:
2847 ta[0] = !!*(const uint64_t *)&ta[0];
2848 tl[0] = !!*(const uint64_t *)&tl[0];
2849 break;
2850 default:
2851 assert(0 && "Invalid transform size.");
2852 break;
2853 }
Jingning Han2cdc1272015-10-09 09:57:42 -07002854 coeff_ctx = combine_entropy_contexts(ta[0], tl[0]);
Jingning Han4c6c82a2016-02-09 17:51:49 -08002855 vp10_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
2856 plane_bsize, coeff_ctx, rate, dist, bsse, skip);
Jingning Hana8dad552015-10-08 16:46:10 -07002857 for (i = 0; i < (1 << tx_size); ++i) {
Jingning Han2cdc1272015-10-09 09:57:42 -07002858 ta[i] = !(p->eobs[block] == 0);
2859 tl[i] = !(p->eobs[block] == 0);
Jingning Hana8dad552015-10-08 16:46:10 -07002860 }
Jingning Hana8dad552015-10-08 16:46:10 -07002861 } else {
Jingning Hana8dad552015-10-08 16:46:10 -07002862 int bsl = b_width_log2_lookup[bsize];
2863 int step = 1 << (2 * (tx_size - 1));
2864 int i;
2865
2866 assert(bsl > 0);
2867 --bsl;
2868
2869 for (i = 0; i < 4; ++i) {
2870 int offsetr = (i >> 1) << bsl;
2871 int offsetc = (i & 0x01) << bsl;
2872 tx_block_rd(cpi, x, blk_row + offsetr, blk_col + offsetc, plane,
2873 block + i * step, tx_size - 1, plane_bsize,
2874 above_ctx, left_ctx, rate, dist, bsse, skip);
2875 }
2876 }
2877}
2878
2879// Return value 0: early termination triggered, no valid rd cost available;
2880// 1: rd cost values are valid.
2881static int inter_block_uvrd(const VP10_COMP *cpi, MACROBLOCK *x,
2882 int *rate, int64_t *distortion, int *skippable,
2883 int64_t *sse, BLOCK_SIZE bsize,
2884 int64_t ref_best_rd) {
2885 MACROBLOCKD *const xd = &x->e_mbd;
2886 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2887 int plane;
2888 int is_cost_valid = 1;
2889 int64_t this_rd;
2890
2891 if (ref_best_rd < 0)
2892 is_cost_valid = 0;
2893
2894 if (is_inter_block(mbmi) && is_cost_valid) {
2895 int plane;
2896 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
2897 vp10_subtract_plane(x, bsize, plane);
2898 }
2899
2900 *rate = 0;
2901 *distortion = 0;
2902 *sse = 0;
2903 *skippable = 1;
2904
2905 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
2906 const struct macroblockd_plane *const pd = &xd->plane[plane];
2907 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
2908 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
2909 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
2910 BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[plane_bsize]];
2911 int bh = num_4x4_blocks_wide_lookup[txb_size];
2912 int idx, idy;
2913 int block = 0;
2914 int step = 1 << (max_txsize_lookup[plane_bsize] * 2);
2915 int pnrate = 0, pnskip = 1;
2916 int64_t pndist = 0, pnsse = 0;
2917 ENTROPY_CONTEXT ta[16], tl[16];
2918
2919 vp10_get_entropy_contexts(bsize, TX_4X4, pd, ta, tl);
2920
2921 for (idy = 0; idy < mi_height; idy += bh) {
2922 for (idx = 0; idx < mi_width; idx += bh) {
2923 tx_block_rd(cpi, x, idy, idx, plane, block,
2924 max_txsize_lookup[plane_bsize], plane_bsize, ta, tl,
2925 &pnrate, &pndist, &pnsse, &pnskip);
2926 block += step;
2927 }
2928 }
2929
2930 if (pnrate == INT_MAX) {
2931 is_cost_valid = 0;
2932 break;
2933 }
2934
2935 *rate += pnrate;
2936 *distortion += pndist;
2937 *sse += pnsse;
2938 *skippable &= pnskip;
2939
2940 this_rd = VPXMIN(RDCOST(x->rdmult, x->rddiv, *rate, *distortion),
2941 RDCOST(x->rdmult, x->rddiv, 0, *sse));
2942
2943 if (this_rd > ref_best_rd) {
2944 is_cost_valid = 0;
2945 break;
2946 }
2947 }
2948
2949 if (!is_cost_valid) {
2950 // reset cost value
2951 *rate = INT_MAX;
2952 *distortion = INT64_MAX;
2953 *sse = INT64_MAX;
2954 *skippable = 0;
2955 }
2956
2957 return is_cost_valid;
2958}
2959#endif
2960
Jingning Han3ee6db62015-08-05 19:00:31 -07002961// Return value 0: early termination triggered, no valid rd cost available;
2962// 1: rd cost values are valid.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07002963static int super_block_uvrd(const VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07002964 int *rate, int64_t *distortion, int *skippable,
2965 int64_t *sse, BLOCK_SIZE bsize,
2966 int64_t ref_best_rd) {
2967 MACROBLOCKD *const xd = &x->e_mbd;
2968 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2969 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
2970 int plane;
2971 int pnrate = 0, pnskip = 1;
2972 int64_t pndist = 0, pnsse = 0;
2973 int is_cost_valid = 1;
2974
2975 if (ref_best_rd < 0)
2976 is_cost_valid = 0;
2977
2978 if (is_inter_block(mbmi) && is_cost_valid) {
2979 int plane;
2980 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
2981 vp10_subtract_plane(x, bsize, plane);
2982 }
2983
2984 *rate = 0;
2985 *distortion = 0;
2986 *sse = 0;
2987 *skippable = 1;
2988
2989 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
Jingning Han71c15602015-10-13 12:40:39 -07002990 txfm_rd_in_plane(x,
2991#if CONFIG_VAR_TX
2992 cpi,
2993#endif
2994 &pnrate, &pndist, &pnskip, &pnsse,
Jingning Han3ee6db62015-08-05 19:00:31 -07002995 ref_best_rd, plane, bsize, uv_tx_size,
2996 cpi->sf.use_fast_coef_costing);
2997 if (pnrate == INT_MAX) {
2998 is_cost_valid = 0;
2999 break;
3000 }
3001 *rate += pnrate;
3002 *distortion += pndist;
3003 *sse += pnsse;
3004 *skippable &= pnskip;
3005 }
3006
3007 if (!is_cost_valid) {
3008 // reset cost value
3009 *rate = INT_MAX;
3010 *distortion = INT64_MAX;
3011 *sse = INT64_MAX;
3012 *skippable = 0;
3013 }
3014
3015 return is_cost_valid;
3016}
3017
hui sube3559b2015-10-07 09:29:02 -07003018#if CONFIG_EXT_INTRA
3019// Return 1 if an ext intra mode is selected; return 0 otherwise.
3020static int rd_pick_ext_intra_sbuv(VP10_COMP *cpi, MACROBLOCK *x,
3021 PICK_MODE_CONTEXT *ctx,
3022 int *rate, int *rate_tokenonly,
3023 int64_t *distortion, int *skippable,
3024 BLOCK_SIZE bsize, int64_t *best_rd) {
3025 MACROBLOCKD *const xd = &x->e_mbd;
3026 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
3027 int ext_intra_selected_flag = 0;
3028 int this_rate_tokenonly, this_rate, s;
hui su4aa50c12015-11-10 12:09:59 -08003029 int64_t this_distortion, this_sse, this_rd;
hui sube3559b2015-10-07 09:29:02 -07003030 EXT_INTRA_MODE mode;
hui sube3559b2015-10-07 09:29:02 -07003031 EXT_INTRA_MODE_INFO ext_intra_mode_info;
3032
3033 vp10_zero(ext_intra_mode_info);
3034 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 1;
3035 mbmi->uv_mode = DC_PRED;
3036
hui su4aa50c12015-11-10 12:09:59 -08003037 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
3038 mbmi->ext_intra_mode_info.ext_intra_mode[1] = mode;
3039 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3040 &this_distortion, &s, &this_sse, bsize, *best_rd))
3041 continue;
hui sube3559b2015-10-07 09:29:02 -07003042
hui su4aa50c12015-11-10 12:09:59 -08003043 this_rate = this_rate_tokenonly +
3044 vp10_cost_bit(cpi->common.fc->ext_intra_probs[1], 1) +
3045 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
3046 write_uniform_cost(FILTER_INTRA_MODES, mode);
3047 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3048 if (this_rd < *best_rd) {
3049 *best_rd = this_rd;
3050 *rate = this_rate;
3051 *rate_tokenonly = this_rate_tokenonly;
3052 *distortion = this_distortion;
3053 *skippable = s;
3054 ext_intra_mode_info = mbmi->ext_intra_mode_info;
3055 ext_intra_selected_flag = 1;
3056 if (!x->select_tx_size)
3057 swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE);
hui sube3559b2015-10-07 09:29:02 -07003058 }
3059 }
3060
hui sube3559b2015-10-07 09:29:02 -07003061
3062 if (ext_intra_selected_flag) {
3063 mbmi->uv_mode = DC_PRED;
3064 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
3065 ext_intra_mode_info.use_ext_intra_mode[1];
3066 mbmi->ext_intra_mode_info.ext_intra_mode[1] =
3067 ext_intra_mode_info.ext_intra_mode[1];
hui sube3559b2015-10-07 09:29:02 -07003068 return 1;
3069 } else {
3070 return 0;
3071 }
3072}
hui su4aa50c12015-11-10 12:09:59 -08003073
hui su5a7c8d82016-02-08 10:39:17 -08003074static void pick_intra_angle_routine_sbuv(VP10_COMP *cpi, MACROBLOCK *x,
3075 int *rate, int *rate_tokenonly,
3076 int64_t *distortion, int *skippable,
3077 int *best_angle_delta,
3078 BLOCK_SIZE bsize, int rate_overhead,
3079 int64_t *best_rd) {
3080 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
3081 int this_rate_tokenonly, this_rate, s;
3082 int64_t this_distortion, this_sse, this_rd;
3083
3084 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3085 &this_distortion, &s, &this_sse, bsize, *best_rd))
3086 return;
3087
3088 this_rate = this_rate_tokenonly + rate_overhead;
3089 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3090 if (this_rd < *best_rd) {
3091 *best_rd = this_rd;
3092 *best_angle_delta = mbmi->angle_delta[1];
3093 *rate = this_rate;
3094 *rate_tokenonly = this_rate_tokenonly;
3095 *distortion = this_distortion;
3096 *skippable = s;
3097 }
3098}
3099
hui su4aa50c12015-11-10 12:09:59 -08003100static int rd_pick_intra_angle_sbuv(VP10_COMP *cpi, MACROBLOCK *x,
3101 PICK_MODE_CONTEXT *ctx,
3102 int *rate, int *rate_tokenonly,
3103 int64_t *distortion, int *skippable,
3104 BLOCK_SIZE bsize, int rate_overhead,
3105 int64_t best_rd) {
3106 MACROBLOCKD *const xd = &x->e_mbd;
3107 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
3108 int this_rate_tokenonly, this_rate, s;
3109 int64_t this_distortion, this_sse, this_rd;
3110 int angle_delta, best_angle_delta = 0;
3111 const double rd_adjust = 1.2;
3112
3113 (void)ctx;
3114 *rate_tokenonly = INT_MAX;
3115 if (ANGLE_FAST_SEARCH) {
3116 int deltas_level1[3] = {0, -2, 2};
3117 int deltas_level2[3][2] = {
3118 {-1, 1}, {-3, -1}, {1, 3},
3119 };
3120 const int level1 = 3, level2 = 2;
3121 int i, j, best_i = -1;
3122
3123 for (i = 0; i < level1; ++i) {
3124 mbmi->angle_delta[1] = deltas_level1[i];
3125 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3126 &this_distortion, &s, &this_sse, bsize,
3127 (i == 0 && best_rd < INT64_MAX) ?
3128 best_rd * rd_adjust : best_rd)) {
3129 if (i == 0)
3130 break;
3131 else
3132 continue;
3133 }
3134 this_rate = this_rate_tokenonly + rate_overhead;
3135 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3136 if (i == 0 && best_rd < INT64_MAX && this_rd > best_rd * rd_adjust)
3137 break;
3138 if (this_rd < best_rd) {
3139 best_i = i;
3140 best_rd = this_rd;
3141 best_angle_delta = mbmi->angle_delta[1];
3142 *rate = this_rate;
3143 *rate_tokenonly = this_rate_tokenonly;
3144 *distortion = this_distortion;
3145 *skippable = s;
3146 }
3147 }
3148
3149 if (best_i >= 0) {
3150 for (j = 0; j < level2; ++j) {
3151 mbmi->angle_delta[1] = deltas_level2[best_i][j];
hui su5a7c8d82016-02-08 10:39:17 -08003152 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly,
3153 distortion, skippable,
3154 &best_angle_delta, bsize,
3155 rate_overhead, &best_rd);
hui su4aa50c12015-11-10 12:09:59 -08003156 }
3157 }
3158 } else {
3159 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
3160 ++angle_delta) {
3161 mbmi->angle_delta[1] = angle_delta;
hui su5a7c8d82016-02-08 10:39:17 -08003162 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly,
3163 distortion, skippable,
3164 &best_angle_delta, bsize,
3165 rate_overhead, &best_rd);
hui su4aa50c12015-11-10 12:09:59 -08003166 }
3167 }
3168
3169 mbmi->angle_delta[1] = best_angle_delta;
3170 if (*rate_tokenonly != INT_MAX)
3171 super_block_uvrd(cpi, x, &this_rate_tokenonly,
3172 &this_distortion, &s, &this_sse, bsize, INT_MAX);
3173 return *rate_tokenonly != INT_MAX;
3174}
hui sube3559b2015-10-07 09:29:02 -07003175#endif // CONFIG_EXT_INTRA
3176
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003177static int64_t rd_pick_intra_sbuv_mode(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003178 PICK_MODE_CONTEXT *ctx,
3179 int *rate, int *rate_tokenonly,
3180 int64_t *distortion, int *skippable,
3181 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
3182 MACROBLOCKD *xd = &x->e_mbd;
hui sube3559b2015-10-07 09:29:02 -07003183 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Jingning Han3ee6db62015-08-05 19:00:31 -07003184 PREDICTION_MODE mode;
3185 PREDICTION_MODE mode_selected = DC_PRED;
3186 int64_t best_rd = INT64_MAX, this_rd;
3187 int this_rate_tokenonly, this_rate, s;
3188 int64_t this_distortion, this_sse;
hui sube3559b2015-10-07 09:29:02 -07003189#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08003190 int is_directional_mode, rate_overhead, best_angle_delta = 0;
hui sube3559b2015-10-07 09:29:02 -07003191 EXT_INTRA_MODE_INFO ext_intra_mode_info;
Jingning Han3ee6db62015-08-05 19:00:31 -07003192
hui sube3559b2015-10-07 09:29:02 -07003193 ext_intra_mode_info.use_ext_intra_mode[1] = 0;
3194 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
3195#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07003196 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
hui suc93e5cc2015-12-07 18:18:57 -08003197 xd->mi[0]->mbmi.palette_mode_info.palette_size[1] = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07003198 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
3199 if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode)))
3200 continue;
3201
hui sube3559b2015-10-07 09:29:02 -07003202 mbmi->uv_mode = mode;
hui su4aa50c12015-11-10 12:09:59 -08003203#if CONFIG_EXT_INTRA
3204 is_directional_mode = (mode != DC_PRED && mode != TM_PRED);
3205 rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
3206 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
3207 mbmi->angle_delta[1] = 0;
3208 if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode) {
3209 if (!rd_pick_intra_angle_sbuv(cpi, x, ctx, &this_rate,
3210 &this_rate_tokenonly, &this_distortion, &s,
3211 bsize, rate_overhead, best_rd))
3212 continue;
3213 } else {
3214 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3215 &this_distortion, &s, &this_sse, bsize, best_rd))
3216 continue;
3217 }
3218 this_rate = this_rate_tokenonly +
3219 cpi->intra_uv_mode_cost[mbmi->mode][mode];
3220 if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode)
3221 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
3222 MAX_ANGLE_DELTAS +
3223 mbmi->angle_delta[1]);
3224 if (mode == DC_PRED && 0)
3225 this_rate += vp10_cost_bit(cpi->common.fc->ext_intra_probs[1], 0);
3226#else
Jingning Han3ee6db62015-08-05 19:00:31 -07003227 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3228 &this_distortion, &s, &this_sse, bsize, best_rd))
3229 continue;
hui su6ab6ac42015-11-06 13:56:51 -08003230 this_rate = this_rate_tokenonly +
3231 cpi->intra_uv_mode_cost[xd->mi[0]->mbmi.mode][mode];
hui sube3559b2015-10-07 09:29:02 -07003232#endif // CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08003233
Jingning Han3ee6db62015-08-05 19:00:31 -07003234 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3235
3236 if (this_rd < best_rd) {
3237 mode_selected = mode;
hui su4aa50c12015-11-10 12:09:59 -08003238#if CONFIG_EXT_INTRA
3239 best_angle_delta = mbmi->angle_delta[1];
3240#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07003241 best_rd = this_rd;
3242 *rate = this_rate;
3243 *rate_tokenonly = this_rate_tokenonly;
3244 *distortion = this_distortion;
3245 *skippable = s;
3246 if (!x->select_tx_size)
3247 swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE);
3248 }
3249 }
3250
hui sube3559b2015-10-07 09:29:02 -07003251#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08003252 if (mbmi->sb_type >= BLOCK_8X8 && ALLOW_FILTER_INTRA_MODES) {
hui sube3559b2015-10-07 09:29:02 -07003253 if (rd_pick_ext_intra_sbuv(cpi, x, ctx, rate, rate_tokenonly, distortion,
3254 skippable, bsize, &best_rd)) {
3255 mode_selected = mbmi->uv_mode;
3256 ext_intra_mode_info = mbmi->ext_intra_mode_info;
3257 }
3258 }
3259
3260 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
3261 ext_intra_mode_info.use_ext_intra_mode[1];
3262 if (ext_intra_mode_info.use_ext_intra_mode[1])
3263 mbmi->ext_intra_mode_info.ext_intra_mode[1] =
3264 ext_intra_mode_info.ext_intra_mode[1];
hui su4aa50c12015-11-10 12:09:59 -08003265 mbmi->angle_delta[1] = best_angle_delta;
hui sube3559b2015-10-07 09:29:02 -07003266#endif // CONFIG_EXT_INTRA
3267 mbmi->uv_mode = mode_selected;
Jingning Han3ee6db62015-08-05 19:00:31 -07003268 return best_rd;
3269}
3270
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003271static int64_t rd_sbuv_dcpred(const VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003272 int *rate, int *rate_tokenonly,
3273 int64_t *distortion, int *skippable,
3274 BLOCK_SIZE bsize) {
Jingning Han3ee6db62015-08-05 19:00:31 -07003275 int64_t unused;
3276
3277 x->e_mbd.mi[0]->mbmi.uv_mode = DC_PRED;
3278 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
3279 super_block_uvrd(cpi, x, rate_tokenonly, distortion,
3280 skippable, &unused, bsize, INT64_MAX);
hui su6ab6ac42015-11-06 13:56:51 -08003281 *rate = *rate_tokenonly +
3282 cpi->intra_uv_mode_cost[x->e_mbd.mi[0]->mbmi.mode][DC_PRED];
Jingning Han3ee6db62015-08-05 19:00:31 -07003283 return RDCOST(x->rdmult, x->rddiv, *rate, *distortion);
3284}
3285
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003286static void choose_intra_uv_mode(VP10_COMP *cpi, MACROBLOCK *const x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003287 PICK_MODE_CONTEXT *ctx,
3288 BLOCK_SIZE bsize, TX_SIZE max_tx_size,
3289 int *rate_uv, int *rate_uv_tokenonly,
3290 int64_t *dist_uv, int *skip_uv,
3291 PREDICTION_MODE *mode_uv) {
3292 // Use an estimated rd for uv_intra based on DC_PRED if the
3293 // appropriate speed flag is set.
3294 if (cpi->sf.use_uv_intra_rd_estimate) {
3295 rd_sbuv_dcpred(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv,
3296 skip_uv, bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize);
3297 // Else do a proper rd search for each possible transform size that may
3298 // be considered in the main rd loop.
3299 } else {
3300 rd_pick_intra_sbuv_mode(cpi, x, ctx,
3301 rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
3302 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
3303 }
3304 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
3305}
3306
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003307static int cost_mv_ref(const VP10_COMP *cpi, PREDICTION_MODE mode,
Yue Chen1ac85872016-01-07 15:13:52 -08003308#if CONFIG_REF_MV && CONFIG_EXT_INTER
3309 int is_compound,
3310#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003311 int16_t mode_context) {
Jingning Han1dc18072015-12-02 10:59:01 -08003312#if CONFIG_REF_MV
3313 int mode_cost = 0;
Yue Chen968bbc72016-01-19 16:45:45 -08003314#if CONFIG_EXT_INTER
3315 int16_t mode_ctx = is_compound ? mode_context :
3316 (mode_context & NEWMV_CTX_MASK);
3317#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003318 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
Yue Chen968bbc72016-01-19 16:45:45 -08003319#endif // CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003320 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
Jingning Han1dc18072015-12-02 10:59:01 -08003321
3322 assert(is_inter_mode(mode));
3323
Yue Chen1ac85872016-01-07 15:13:52 -08003324#if CONFIG_EXT_INTER
Yue Chen968bbc72016-01-19 16:45:45 -08003325 if (is_compound) {
3326 return cpi->inter_compound_mode_cost[mode_context]
3327 [INTER_COMPOUND_OFFSET(mode)];
3328 } else {
3329 if (mode == NEWMV || mode == NEWFROMNEARMV) {
Yue Chen1ac85872016-01-07 15:13:52 -08003330#else
Jingning Han1dc18072015-12-02 10:59:01 -08003331 if (mode == NEWMV) {
Yue Chen1ac85872016-01-07 15:13:52 -08003332#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08003333 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
Yue Chen1ac85872016-01-07 15:13:52 -08003334#if CONFIG_EXT_INTER
3335 if (!is_compound)
3336 mode_cost += cpi->new2mv_mode_cost[mode == NEWFROMNEARMV];
3337#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08003338 return mode_cost;
3339 } else {
3340 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
3341 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003342
3343 if (is_all_zero_mv)
3344 return mode_cost;
3345
Jingning Han1dc18072015-12-02 10:59:01 -08003346 if (mode == ZEROMV) {
3347 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
3348 return mode_cost;
3349 } else {
3350 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003351 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
Jingning Han387a10e2015-12-09 09:07:39 -08003352
3353 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET))
3354 mode_ctx = 6;
3355 if (mode_context & (1 << SKIP_NEARMV_OFFSET))
3356 mode_ctx = 7;
3357 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET))
3358 mode_ctx = 8;
3359
Jingning Han1dc18072015-12-02 10:59:01 -08003360 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
3361 return mode_cost;
3362 }
3363 }
Yue Chen968bbc72016-01-19 16:45:45 -08003364#if CONFIG_EXT_INTER
3365 }
3366#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08003367#else
Jingning Han3ee6db62015-08-05 19:00:31 -07003368 assert(is_inter_mode(mode));
Yue Chen968bbc72016-01-19 16:45:45 -08003369#if CONFIG_EXT_INTER
3370 if (is_inter_compound_mode(mode)) {
3371 return cpi->inter_compound_mode_cost[mode_context]
3372 [INTER_COMPOUND_OFFSET(mode)];
3373 } else {
3374#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003375 return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
Yue Chen968bbc72016-01-19 16:45:45 -08003376#if CONFIG_EXT_INTER
3377 }
3378#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08003379#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07003380}
3381
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003382static int set_and_cost_bmi_mvs(VP10_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd,
Jingning Han3ee6db62015-08-05 19:00:31 -07003383 int i,
3384 PREDICTION_MODE mode, int_mv this_mv[2],
3385 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
3386 int_mv seg_mvs[MAX_REF_FRAMES],
Yue Chen1ac85872016-01-07 15:13:52 -08003387#if CONFIG_EXT_INTER
3388 int_mv compound_seg_newmvs[2],
3389#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003390 int_mv *best_ref_mv[2], const int *mvjcost,
3391 int *mvcost[2]) {
3392 MODE_INFO *const mic = xd->mi[0];
3393 const MB_MODE_INFO *const mbmi = &mic->mbmi;
3394 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
3395 int thismvcost = 0;
3396 int idx, idy;
3397 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
3398 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
3399 const int is_compound = has_second_ref(mbmi);
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003400 int mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
Jingning Han3ee6db62015-08-05 19:00:31 -07003401
3402 switch (mode) {
3403 case NEWMV:
Yue Chen1ac85872016-01-07 15:13:52 -08003404#if CONFIG_EXT_INTER
3405 case NEWFROMNEARMV:
Yue Chen1ac85872016-01-07 15:13:52 -08003406#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003407 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08003408#if CONFIG_EXT_INTER
3409 if (!cpi->common.allow_high_precision_mv ||
3410 !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
3411 lower_mv_precision(&this_mv[0].as_mv, 0);
3412#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003413 thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
3414 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yue Chen968bbc72016-01-19 16:45:45 -08003415#if !CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003416 if (is_compound) {
3417 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
3418 thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
3419 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
3420 }
Yue Chen968bbc72016-01-19 16:45:45 -08003421#endif // !CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003422 break;
3423 case NEARMV:
3424 case NEARESTMV:
3425 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
3426 if (is_compound)
3427 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
3428 break;
3429 case ZEROMV:
3430 this_mv[0].as_int = 0;
3431 if (is_compound)
3432 this_mv[1].as_int = 0;
3433 break;
Yue Chen968bbc72016-01-19 16:45:45 -08003434#if CONFIG_EXT_INTER
3435 case NEW_NEWMV:
3436 if (compound_seg_newmvs[0].as_int == INVALID_MV ||
3437 compound_seg_newmvs[1].as_int == INVALID_MV) {
3438 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
3439 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
3440 } else {
3441 this_mv[0].as_int = compound_seg_newmvs[0].as_int;
3442 this_mv[1].as_int = compound_seg_newmvs[1].as_int;
3443 }
3444 if (!cpi->common.allow_high_precision_mv ||
3445 !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
3446 lower_mv_precision(&this_mv[0].as_mv, 0);
3447 if (!cpi->common.allow_high_precision_mv ||
3448 !vp10_use_mv_hp(&best_ref_mv[1]->as_mv))
3449 lower_mv_precision(&this_mv[1].as_mv, 0);
3450 thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv,
3451 &best_ref_mv[0]->as_mv,
3452 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
3453 thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv,
3454 &best_ref_mv[1]->as_mv,
3455 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
3456 break;
3457 case NEW_NEARMV:
3458 case NEW_NEARESTMV:
3459 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
3460 if (!cpi->common.allow_high_precision_mv ||
3461 !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
3462 lower_mv_precision(&this_mv[0].as_mv, 0);
3463 thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
3464 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
3465 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
3466 break;
3467 case NEAR_NEWMV:
3468 case NEAREST_NEWMV:
3469 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
3470 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
3471 if (!cpi->common.allow_high_precision_mv ||
3472 !vp10_use_mv_hp(&best_ref_mv[1]->as_mv))
3473 lower_mv_precision(&this_mv[1].as_mv, 0);
3474 thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
3475 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
3476 break;
3477 case NEAREST_NEARMV:
3478 case NEAR_NEARESTMV:
3479 case NEAREST_NEARESTMV:
3480 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
3481 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
3482 break;
3483 case ZERO_ZEROMV:
3484 this_mv[0].as_int = 0;
3485 this_mv[1].as_int = 0;
3486 break;
3487#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003488 default:
3489 break;
3490 }
3491
3492 mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
3493 if (is_compound)
3494 mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
3495
3496 mic->bmi[i].as_mode = mode;
3497
3498 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
3499 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
3500 memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
3501
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003502#if CONFIG_REF_MV
Yue Chen968bbc72016-01-19 16:45:45 -08003503#if CONFIG_EXT_INTER
3504 if (is_compound)
3505 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
3506 else
3507#endif // CONFIG_EXT_INTER
Jingning Han387a10e2015-12-09 09:07:39 -08003508 mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
3509 mbmi->ref_frame, mbmi->sb_type, i);
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003510#endif
Yue Chen1ac85872016-01-07 15:13:52 -08003511#if CONFIG_REF_MV && CONFIG_EXT_INTER
3512 return cost_mv_ref(cpi, mode, is_compound, mode_ctx) + thismvcost;
3513#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003514 return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
Yue Chen1ac85872016-01-07 15:13:52 -08003515#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003516}
3517
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003518static int64_t encode_inter_mb_segment(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07003519 MACROBLOCK *x,
3520 int64_t best_yrd,
3521 int i,
3522 int *labelyrate,
3523 int64_t *distortion, int64_t *sse,
3524 ENTROPY_CONTEXT *ta,
3525 ENTROPY_CONTEXT *tl,
Yaowu Xu7c514e22015-09-28 15:55:46 -07003526 int ir, int ic,
Jingning Han3ee6db62015-08-05 19:00:31 -07003527 int mi_row, int mi_col) {
3528 int k;
3529 MACROBLOCKD *xd = &x->e_mbd;
3530 struct macroblockd_plane *const pd = &xd->plane[0];
3531 struct macroblock_plane *const p = &x->plane[0];
3532 MODE_INFO *const mi = xd->mi[0];
3533 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
3534 const int width = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
3535 const int height = 4 * num_4x4_blocks_high_lookup[plane_bsize];
3536 int idx, idy;
Yaowu Xu7c514e22015-09-28 15:55:46 -07003537 void (*fwd_txm4x4)(const int16_t *input, tran_low_t *output, int stride);
Jingning Han3ee6db62015-08-05 19:00:31 -07003538
3539 const uint8_t *const src =
3540 &p->src.buf[vp10_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
3541 uint8_t *const dst = &pd->dst.buf[vp10_raster_block_offset(BLOCK_8X8, i,
3542 pd->dst.stride)];
3543 int64_t thisdistortion = 0, thissse = 0;
Yaowu Xu7c514e22015-09-28 15:55:46 -07003544 int thisrate = 0;
hui sub3cc3a02015-08-24 14:37:54 -07003545 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, i, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07003546 const scan_order *so = get_scan(TX_4X4, tx_type, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07003547
Yaowu Xu7c514e22015-09-28 15:55:46 -07003548 vp10_build_inter_predictor_sub8x8(xd, 0, i, ir, ic, mi_row, mi_col);
3549
Jingning Han3ee6db62015-08-05 19:00:31 -07003550#if CONFIG_VP9_HIGHBITDEPTH
3551 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04003552 fwd_txm4x4 = xd->lossless[mi->mbmi.segment_id] ? vp10_highbd_fwht4x4
3553 : vpx_highbd_fdct4x4;
Jingning Han3ee6db62015-08-05 19:00:31 -07003554 } else {
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04003555 fwd_txm4x4 = xd->lossless[mi->mbmi.segment_id] ? vp10_fwht4x4 : vpx_fdct4x4;
Jingning Han3ee6db62015-08-05 19:00:31 -07003556 }
3557#else
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04003558 fwd_txm4x4 = xd->lossless[mi->mbmi.segment_id] ? vp10_fwht4x4 : vpx_fdct4x4;
Jingning Han3ee6db62015-08-05 19:00:31 -07003559#endif // CONFIG_VP9_HIGHBITDEPTH
Jingning Han3ee6db62015-08-05 19:00:31 -07003560
3561#if CONFIG_VP9_HIGHBITDEPTH
3562 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3563 vpx_highbd_subtract_block(
3564 height, width, vp10_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
3565 8, src, p->src.stride, dst, pd->dst.stride, xd->bd);
3566 } else {
3567 vpx_subtract_block(
3568 height, width, vp10_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
3569 8, src, p->src.stride, dst, pd->dst.stride);
3570 }
3571#else
3572 vpx_subtract_block(height, width,
3573 vp10_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
3574 8, src, p->src.stride, dst, pd->dst.stride);
3575#endif // CONFIG_VP9_HIGHBITDEPTH
3576
3577 k = i;
3578 for (idy = 0; idy < height / 4; ++idy) {
3579 for (idx = 0; idx < width / 4; ++idx) {
3580 int64_t ssz, rd, rd1, rd2;
3581 tran_low_t* coeff;
Jingning Han2cdc1272015-10-09 09:57:42 -07003582#if CONFIG_VAR_TX
3583 int coeff_ctx;
3584#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07003585 k += (idy * 2 + idx);
Jingning Han2cdc1272015-10-09 09:57:42 -07003586#if CONFIG_VAR_TX
3587 coeff_ctx = combine_entropy_contexts(*(ta + (k & 1)),
3588 *(tl + (k >> 1)));
3589#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07003590 coeff = BLOCK_OFFSET(p->coeff, k);
Yaowu Xu7c514e22015-09-28 15:55:46 -07003591 fwd_txm4x4(vp10_raster_block_offset_int16(BLOCK_8X8, k, p->src_diff),
3592 coeff, 8);
Jingning Han3ee6db62015-08-05 19:00:31 -07003593 vp10_regular_quantize_b_4x4(x, 0, k, so->scan, so->iscan);
3594#if CONFIG_VP9_HIGHBITDEPTH
3595 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3596 thisdistortion += vp10_highbd_block_error(coeff,
3597 BLOCK_OFFSET(pd->dqcoeff, k),
3598 16, &ssz, xd->bd);
3599 } else {
3600 thisdistortion += vp10_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, k),
3601 16, &ssz);
3602 }
3603#else
3604 thisdistortion += vp10_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, k),
3605 16, &ssz);
3606#endif // CONFIG_VP9_HIGHBITDEPTH
3607 thissse += ssz;
Jingning Han2cdc1272015-10-09 09:57:42 -07003608#if CONFIG_VAR_TX
3609 thisrate += cost_coeffs(x, 0, k, coeff_ctx,
3610 TX_4X4,
Jingning Han3ee6db62015-08-05 19:00:31 -07003611 so->scan, so->neighbors,
3612 cpi->sf.use_fast_coef_costing);
Jingning Han2cdc1272015-10-09 09:57:42 -07003613 *(ta + (k & 1)) = !(p->eobs[k] == 0);
3614 *(tl + (k >> 1)) = !(p->eobs[k] == 0);
3615#else
3616 thisrate += cost_coeffs(x, 0, k, ta + (k & 1), tl + (k >> 1),
3617 TX_4X4,
3618 so->scan, so->neighbors,
3619 cpi->sf.use_fast_coef_costing);
3620#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07003621 rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion >> 2);
3622 rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse >> 2);
James Zern5e16d392015-08-17 18:19:22 -07003623 rd = VPXMIN(rd1, rd2);
Jingning Han3ee6db62015-08-05 19:00:31 -07003624 if (rd >= best_yrd)
3625 return INT64_MAX;
3626 }
3627 }
3628
3629 *distortion = thisdistortion >> 2;
3630 *labelyrate = thisrate;
3631 *sse = thissse >> 2;
3632
3633 return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
3634}
3635
3636typedef struct {
3637 int eobs;
3638 int brate;
3639 int byrate;
3640 int64_t bdist;
3641 int64_t bsse;
3642 int64_t brdcost;
3643 int_mv mvs[2];
Yue Chen1ac85872016-01-07 15:13:52 -08003644#if CONFIG_EXT_INTER
3645 int_mv ref_mv[2];
3646#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003647 ENTROPY_CONTEXT ta[2];
3648 ENTROPY_CONTEXT tl[2];
3649} SEG_RDSTAT;
3650
3651typedef struct {
3652 int_mv *ref_mv[2];
3653 int_mv mvp;
3654
3655 int64_t segment_rd;
3656 int r;
3657 int64_t d;
3658 int64_t sse;
3659 int segment_yrate;
3660 PREDICTION_MODE modes[4];
Yue Chen968bbc72016-01-19 16:45:45 -08003661#if CONFIG_EXT_INTER
3662 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
3663#else
Jingning Han3ee6db62015-08-05 19:00:31 -07003664 SEG_RDSTAT rdstat[4][INTER_MODES];
Yue Chen968bbc72016-01-19 16:45:45 -08003665#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003666 int mvthresh;
3667} BEST_SEG_INFO;
3668
3669static INLINE int mv_check_bounds(const MACROBLOCK *x, const MV *mv) {
3670 return (mv->row >> 3) < x->mv_row_min ||
3671 (mv->row >> 3) > x->mv_row_max ||
3672 (mv->col >> 3) < x->mv_col_min ||
3673 (mv->col >> 3) > x->mv_col_max;
3674}
3675
3676static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
3677 MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
3678 struct macroblock_plane *const p = &x->plane[0];
3679 struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
3680
3681 p->src.buf = &p->src.buf[vp10_raster_block_offset(BLOCK_8X8, i,
3682 p->src.stride)];
3683 assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
3684 pd->pre[0].buf = &pd->pre[0].buf[vp10_raster_block_offset(BLOCK_8X8, i,
3685 pd->pre[0].stride)];
3686 if (has_second_ref(mbmi))
3687 pd->pre[1].buf = &pd->pre[1].buf[vp10_raster_block_offset(BLOCK_8X8, i,
3688 pd->pre[1].stride)];
3689}
3690
3691static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
3692 struct buf_2d orig_pre[2]) {
3693 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
3694 x->plane[0].src = orig_src;
3695 x->e_mbd.plane[0].pre[0] = orig_pre[0];
3696 if (has_second_ref(mbmi))
3697 x->e_mbd.plane[0].pre[1] = orig_pre[1];
3698}
3699
Jingning Han3ee6db62015-08-05 19:00:31 -07003700// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
3701// TODO(aconverse): Find out if this is still productive then clean up or remove
3702static int check_best_zero_mv(
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003703 const VP10_COMP *cpi, const int16_t mode_context[MAX_REF_FRAMES],
Yue Chen968bbc72016-01-19 16:45:45 -08003704#if CONFIG_REF_MV && CONFIG_EXT_INTER
3705 const int16_t compound_mode_context[MAX_REF_FRAMES],
3706#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003707 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES], int this_mode,
Jingning Han387a10e2015-12-09 09:07:39 -08003708 const MV_REFERENCE_FRAME ref_frames[2],
3709 const BLOCK_SIZE bsize, int block) {
Jingning Han3ee6db62015-08-05 19:00:31 -07003710 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
3711 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
3712 (ref_frames[1] == NONE ||
3713 frame_mv[this_mode][ref_frames[1]].as_int == 0)) {
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003714#if CONFIG_REF_MV
Jingning Han387a10e2015-12-09 09:07:39 -08003715 int16_t rfc = vp10_mode_context_analyzer(mode_context,
3716 ref_frames, bsize, block);
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003717#else
3718 int16_t rfc = mode_context[ref_frames[0]];
3719#endif
Yue Chen1ac85872016-01-07 15:13:52 -08003720#if CONFIG_REF_MV && CONFIG_EXT_INTER
3721 int c1 = cost_mv_ref(cpi, NEARMV, ref_frames[1] > INTRA_FRAME, rfc);
3722 int c2 = cost_mv_ref(cpi, NEARESTMV, ref_frames[1] > INTRA_FRAME, rfc);
3723 int c3 = cost_mv_ref(cpi, ZEROMV, ref_frames[1] > INTRA_FRAME, rfc);
3724#else
Jingning Han3ee6db62015-08-05 19:00:31 -07003725 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
3726 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
3727 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
Yue Chen1ac85872016-01-07 15:13:52 -08003728#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003729
Jingning Han387a10e2015-12-09 09:07:39 -08003730#if !CONFIG_REF_MV
3731 (void)bsize;
3732 (void)block;
3733#endif
3734
Jingning Han3ee6db62015-08-05 19:00:31 -07003735 if (this_mode == NEARMV) {
3736 if (c1 > c3) return 0;
3737 } else if (this_mode == NEARESTMV) {
3738 if (c2 > c3) return 0;
3739 } else {
3740 assert(this_mode == ZEROMV);
3741 if (ref_frames[1] == NONE) {
3742 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
3743 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
3744 return 0;
3745 } else {
3746 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
3747 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
3748 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
3749 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
3750 return 0;
3751 }
3752 }
3753 }
Yue Chen968bbc72016-01-19 16:45:45 -08003754#if CONFIG_EXT_INTER
3755 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
3756 this_mode == NEAR_NEARESTMV || this_mode == ZERO_ZEROMV) &&
3757 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
3758 frame_mv[this_mode][ref_frames[1]].as_int == 0) {
3759#if CONFIG_REF_MV
3760 int16_t rfc = compound_mode_context[ref_frames[0]];
3761 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, 1, rfc);
3762 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, 1, rfc);
3763 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, 1, rfc);
3764 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, 1, rfc);
3765#else
3766 int16_t rfc = mode_context[ref_frames[0]];
3767 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
3768 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
3769 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
3770 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
3771#endif
3772
3773 if (this_mode == NEAREST_NEARMV) {
3774 if (c1 > c3) return 0;
3775 } else if (this_mode == NEAREST_NEARESTMV) {
3776 if (c2 > c3) return 0;
3777 } else if (this_mode == NEAR_NEARESTMV) {
3778 if (c4 > c3) return 0;
3779 } else {
3780 assert(this_mode == ZERO_ZEROMV);
3781 if (ref_frames[1] == NONE) {
3782 if ((c3 >= c2 &&
3783 frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0) ||
3784 (c3 >= c1 &&
3785 frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0) ||
3786 (c3 >= c4 &&
3787 frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0))
3788 return 0;
3789 } else {
3790 if ((c3 >= c2 &&
3791 frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
3792 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
3793 (c3 >= c1 &&
3794 frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
3795 frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
3796 (c3 >= c4 &&
3797 frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
3798 frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
3799 return 0;
3800 }
3801 }
3802 }
3803#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003804 return 1;
3805}
3806
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003807static void joint_motion_search(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003808 BLOCK_SIZE bsize,
3809 int_mv *frame_mv,
3810 int mi_row, int mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08003811#if CONFIG_EXT_INTER
3812 int_mv* ref_mv_sub8x8[2],
3813#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07003814 int_mv single_newmv[MAX_REF_FRAMES],
3815 int *rate_mv) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07003816 const VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07003817 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
3818 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
3819 MACROBLOCKD *xd = &x->e_mbd;
3820 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
3821 const int refs[2] = {mbmi->ref_frame[0],
3822 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]};
3823 int_mv ref_mv[2];
3824 int ite, ref;
Angie Chiang10ad97b2016-02-01 12:49:15 -08003825 const INTERP_FILTER interp_filter = mbmi->interp_filter;
Jingning Han3ee6db62015-08-05 19:00:31 -07003826 struct scale_factors sf;
3827
3828 // Do joint motion search in compound mode to get more accurate mv.
3829 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
3830 int last_besterr[2] = {INT_MAX, INT_MAX};
3831 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
3832 vp10_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
3833 vp10_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
3834 };
3835
3836 // Prediction buffer from second frame.
3837#if CONFIG_VP9_HIGHBITDEPTH
3838 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[64 * 64]);
3839 uint8_t *second_pred;
3840#else
3841 DECLARE_ALIGNED(16, uint8_t, second_pred[64 * 64]);
3842#endif // CONFIG_VP9_HIGHBITDEPTH
3843
3844 for (ref = 0; ref < 2; ++ref) {
Yue Chen1ac85872016-01-07 15:13:52 -08003845#if CONFIG_EXT_INTER
3846 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
3847 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
3848 else
3849#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003850 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
3851
3852 if (scaled_ref_frame[ref]) {
3853 int i;
3854 // Swap out the reference frame for a version that's been scaled to
3855 // match the resolution of the current frame, allowing the existing
3856 // motion search code to be used without additional modifications.
3857 for (i = 0; i < MAX_MB_PLANE; i++)
3858 backup_yv12[ref][i] = xd->plane[i].pre[ref];
3859 vp10_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
3860 NULL);
3861 }
3862
3863 frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
3864 }
3865
3866 // Since we have scaled the reference frames to match the size of the current
3867 // frame we must use a unit scaling factor during mode selection.
3868#if CONFIG_VP9_HIGHBITDEPTH
3869 vp10_setup_scale_factors_for_frame(&sf, cm->width, cm->height,
Debargha Mukherjee85514c42015-10-30 09:19:36 -07003870 cm->width, cm->height,
3871 cm->use_highbitdepth);
Jingning Han3ee6db62015-08-05 19:00:31 -07003872#else
3873 vp10_setup_scale_factors_for_frame(&sf, cm->width, cm->height,
Debargha Mukherjee85514c42015-10-30 09:19:36 -07003874 cm->width, cm->height);
Jingning Han3ee6db62015-08-05 19:00:31 -07003875#endif // CONFIG_VP9_HIGHBITDEPTH
3876
3877 // Allow joint search multiple times iteratively for each reference frame
3878 // and break out of the search loop if it couldn't find a better mv.
3879 for (ite = 0; ite < 4; ite++) {
3880 struct buf_2d ref_yv12[2];
3881 int bestsme = INT_MAX;
3882 int sadpb = x->sadperbit16;
3883 MV tmp_mv;
3884 int search_range = 3;
3885
3886 int tmp_col_min = x->mv_col_min;
3887 int tmp_col_max = x->mv_col_max;
3888 int tmp_row_min = x->mv_row_min;
3889 int tmp_row_max = x->mv_row_max;
3890 int id = ite % 2; // Even iterations search in the first reference frame,
3891 // odd iterations search in the second. The predictor
3892 // found for the 'other' reference frame is factored in.
3893
3894 // Initialized here because of compiler problem in Visual Studio.
3895 ref_yv12[0] = xd->plane[0].pre[0];
3896 ref_yv12[1] = xd->plane[0].pre[1];
3897
3898 // Get the prediction block from the 'other' reference frame.
3899#if CONFIG_VP9_HIGHBITDEPTH
3900 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3901 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
3902 vp10_highbd_build_inter_predictor(ref_yv12[!id].buf,
3903 ref_yv12[!id].stride,
3904 second_pred, pw,
3905 &frame_mv[refs[!id]].as_mv,
3906 &sf, pw, ph, 0,
Angie Chiang10ad97b2016-02-01 12:49:15 -08003907 interp_filter, MV_PRECISION_Q3,
Jingning Han3ee6db62015-08-05 19:00:31 -07003908 mi_col * MI_SIZE, mi_row * MI_SIZE,
3909 xd->bd);
3910 } else {
3911 second_pred = (uint8_t *)second_pred_alloc_16;
3912 vp10_build_inter_predictor(ref_yv12[!id].buf,
3913 ref_yv12[!id].stride,
3914 second_pred, pw,
3915 &frame_mv[refs[!id]].as_mv,
3916 &sf, pw, ph, 0,
Angie Chiang10ad97b2016-02-01 12:49:15 -08003917 interp_filter, MV_PRECISION_Q3,
Jingning Han3ee6db62015-08-05 19:00:31 -07003918 mi_col * MI_SIZE, mi_row * MI_SIZE);
3919 }
3920#else
3921 vp10_build_inter_predictor(ref_yv12[!id].buf,
3922 ref_yv12[!id].stride,
3923 second_pred, pw,
3924 &frame_mv[refs[!id]].as_mv,
3925 &sf, pw, ph, 0,
Angie Chiang10ad97b2016-02-01 12:49:15 -08003926 interp_filter, MV_PRECISION_Q3,
Jingning Han3ee6db62015-08-05 19:00:31 -07003927 mi_col * MI_SIZE, mi_row * MI_SIZE);
3928#endif // CONFIG_VP9_HIGHBITDEPTH
3929
3930 // Do compound motion search on the current reference frame.
3931 if (id)
3932 xd->plane[0].pre[0] = ref_yv12[id];
3933 vp10_set_mv_search_range(x, &ref_mv[id].as_mv);
3934
3935 // Use the mv result from the single mode as mv predictor.
3936 tmp_mv = frame_mv[refs[id]].as_mv;
3937
3938 tmp_mv.col >>= 3;
3939 tmp_mv.row >>= 3;
3940
3941 // Small-range full-pixel motion search.
3942 bestsme = vp10_refining_search_8p_c(x, &tmp_mv, sadpb,
3943 search_range,
3944 &cpi->fn_ptr[bsize],
3945 &ref_mv[id].as_mv, second_pred);
3946 if (bestsme < INT_MAX)
3947 bestsme = vp10_get_mvpred_av_var(x, &tmp_mv, &ref_mv[id].as_mv,
3948 second_pred, &cpi->fn_ptr[bsize], 1);
3949
3950 x->mv_col_min = tmp_col_min;
3951 x->mv_col_max = tmp_col_max;
3952 x->mv_row_min = tmp_row_min;
3953 x->mv_row_max = tmp_row_max;
3954
3955 if (bestsme < INT_MAX) {
3956 int dis; /* TODO: use dis in distortion calculation later. */
3957 unsigned int sse;
3958 bestsme = cpi->find_fractional_mv_step(
3959 x, &tmp_mv,
3960 &ref_mv[id].as_mv,
3961 cpi->common.allow_high_precision_mv,
3962 x->errorperbit,
3963 &cpi->fn_ptr[bsize],
3964 0, cpi->sf.mv.subpel_iters_per_step,
3965 NULL,
3966 x->nmvjointcost, x->mvcost,
3967 &dis, &sse, second_pred,
3968 pw, ph);
3969 }
3970
3971 // Restore the pointer to the first (possibly scaled) prediction buffer.
3972 if (id)
3973 xd->plane[0].pre[0] = ref_yv12[0];
3974
3975 if (bestsme < last_besterr[id]) {
3976 frame_mv[refs[id]].as_mv = tmp_mv;
3977 last_besterr[id] = bestsme;
3978 } else {
3979 break;
3980 }
3981 }
3982
3983 *rate_mv = 0;
3984
3985 for (ref = 0; ref < 2; ++ref) {
3986 if (scaled_ref_frame[ref]) {
3987 // Restore the prediction frame pointers to their unscaled versions.
3988 int i;
3989 for (i = 0; i < MAX_MB_PLANE; i++)
3990 xd->plane[i].pre[ref] = backup_yv12[ref][i];
3991 }
3992
Yue Chen1ac85872016-01-07 15:13:52 -08003993#if CONFIG_EXT_INTER
3994 if (bsize >= BLOCK_8X8)
3995#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003996 *rate_mv += vp10_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
3997 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
3998 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yue Chen1ac85872016-01-07 15:13:52 -08003999#if CONFIG_EXT_INTER
4000 else
4001 *rate_mv += vp10_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
4002 &ref_mv_sub8x8[ref]->as_mv,
4003 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
4004#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004005 }
4006}
4007
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004008static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07004009 int_mv *best_ref_mv,
4010 int_mv *second_best_ref_mv,
4011 int64_t best_rd, int *returntotrate,
4012 int *returnyrate,
4013 int64_t *returndistortion,
4014 int *skippable, int64_t *psse,
4015 int mvthresh,
Yue Chen1ac85872016-01-07 15:13:52 -08004016#if CONFIG_EXT_INTER
4017 int_mv seg_mvs[4][2][MAX_REF_FRAMES],
4018 int_mv compound_seg_newmvs[4][2],
4019#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004020 int_mv seg_mvs[4][MAX_REF_FRAMES],
Yue Chen1ac85872016-01-07 15:13:52 -08004021#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004022 BEST_SEG_INFO *bsi_buf, int filter_idx,
4023 int mi_row, int mi_col) {
4024 int i;
4025 BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
4026 MACROBLOCKD *xd = &x->e_mbd;
4027 MODE_INFO *mi = xd->mi[0];
4028 MB_MODE_INFO *mbmi = &mi->mbmi;
4029 int mode_idx;
4030 int k, br = 0, idx, idy;
4031 int64_t bd = 0, block_sse = 0;
4032 PREDICTION_MODE this_mode;
Yaowu Xufc7cbd12015-08-13 09:36:53 -07004033 VP10_COMMON *cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07004034 struct macroblock_plane *const p = &x->plane[0];
4035 struct macroblockd_plane *const pd = &xd->plane[0];
4036 const int label_count = 4;
4037 int64_t this_segment_rd = 0;
4038 int label_mv_thresh;
4039 int segmentyrate = 0;
4040 const BLOCK_SIZE bsize = mbmi->sb_type;
4041 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
4042 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
4043 ENTROPY_CONTEXT t_above[2], t_left[2];
4044 int subpelmv = 1, have_ref = 0;
4045 const int has_second_rf = has_second_ref(mbmi);
4046 const int inter_mode_mask = cpi->sf.inter_mode_mask[bsize];
4047 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4048
4049 vp10_zero(*bsi);
4050
4051 bsi->segment_rd = best_rd;
4052 bsi->ref_mv[0] = best_ref_mv;
4053 bsi->ref_mv[1] = second_best_ref_mv;
4054 bsi->mvp.as_int = best_ref_mv->as_int;
4055 bsi->mvthresh = mvthresh;
4056
4057 for (i = 0; i < 4; i++)
4058 bsi->modes[i] = ZEROMV;
4059
4060 memcpy(t_above, pd->above_context, sizeof(t_above));
4061 memcpy(t_left, pd->left_context, sizeof(t_left));
4062
4063 // 64 makes this threshold really big effectively
4064 // making it so that we very rarely check mvs on
4065 // segments. setting this to 1 would make mv thresh
4066 // roughly equal to what it is for macroblocks
4067 label_mv_thresh = 1 * bsi->mvthresh / label_count;
4068
4069 // Segmentation method overheads
4070 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
4071 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
4072 // TODO(jingning,rbultje): rewrite the rate-distortion optimization
4073 // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
4074 int_mv mode_mv[MB_MODE_COUNT][2];
4075 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
4076 PREDICTION_MODE mode_selected = ZEROMV;
4077 int64_t best_rd = INT64_MAX;
4078 const int i = idy * 2 + idx;
4079 int ref;
Yue Chen1ac85872016-01-07 15:13:52 -08004080#if CONFIG_EXT_INTER
4081 int mv_idx;
4082 int_mv ref_mvs_sub8x8[2][2];
4083#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004084
4085 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
4086 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
Yue Chen1ac85872016-01-07 15:13:52 -08004087#if CONFIG_EXT_INTER
4088 int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
4089 vp10_update_mv_context(cm, xd, mi, frame, mv_ref_list, i,
4090 mi_row, mi_col, NULL);
4091#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004092 frame_mv[ZEROMV][frame].as_int = 0;
4093 vp10_append_sub8x8_mvs_for_idx(cm, xd, i, ref, mi_row, mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08004094#if CONFIG_EXT_INTER
4095 mv_ref_list,
4096#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004097 &frame_mv[NEARESTMV][frame],
Jingning Han40cedd62015-11-25 13:42:59 -08004098 &frame_mv[NEARMV][frame]);
Yue Chen1ac85872016-01-07 15:13:52 -08004099#if CONFIG_EXT_INTER
4100 mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
4101 mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
4102 vp10_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
4103 &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
Yue Chen968bbc72016-01-19 16:45:45 -08004104
4105 if (has_second_rf) {
4106 frame_mv[ZERO_ZEROMV][frame].as_int = 0;
4107 frame_mv[NEAREST_NEARESTMV][frame].as_int =
4108 frame_mv[NEARESTMV][frame].as_int;
4109
4110 if (ref == 0) {
4111 frame_mv[NEAREST_NEARMV][frame].as_int =
4112 frame_mv[NEARESTMV][frame].as_int;
4113 frame_mv[NEAR_NEARESTMV][frame].as_int =
4114 frame_mv[NEARMV][frame].as_int;
4115 frame_mv[NEAREST_NEWMV][frame].as_int =
4116 frame_mv[NEARESTMV][frame].as_int;
4117 frame_mv[NEAR_NEWMV][frame].as_int =
4118 frame_mv[NEARMV][frame].as_int;
4119 } else if (ref == 1) {
4120 frame_mv[NEAREST_NEARMV][frame].as_int =
4121 frame_mv[NEARMV][frame].as_int;
4122 frame_mv[NEAR_NEARESTMV][frame].as_int =
4123 frame_mv[NEARESTMV][frame].as_int;
4124 frame_mv[NEW_NEARESTMV][frame].as_int =
4125 frame_mv[NEARESTMV][frame].as_int;
4126 frame_mv[NEW_NEARMV][frame].as_int =
4127 frame_mv[NEARMV][frame].as_int;
4128 }
4129 }
Yue Chen1ac85872016-01-07 15:13:52 -08004130#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004131 }
4132
4133 // search for the best motion vector on this segment
Yue Chen1ac85872016-01-07 15:13:52 -08004134#if CONFIG_EXT_INTER
Yue Chen968bbc72016-01-19 16:45:45 -08004135 for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
4136 this_mode <= (has_second_rf ? NEW_NEWMV : NEWFROMNEARMV);
4137 ++this_mode) {
Yue Chen1ac85872016-01-07 15:13:52 -08004138#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004139 for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
Yue Chen1ac85872016-01-07 15:13:52 -08004140#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004141 const struct buf_2d orig_src = x->plane[0].src;
4142 struct buf_2d orig_pre[2];
4143
4144 mode_idx = INTER_OFFSET(this_mode);
Yue Chen1ac85872016-01-07 15:13:52 -08004145#if CONFIG_EXT_INTER
4146 mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
Yue Chen968bbc72016-01-19 16:45:45 -08004147
Yue Chen1ac85872016-01-07 15:13:52 -08004148 for (ref = 0; ref < 1 + has_second_rf; ++ref)
4149 bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[mv_idx][ref].as_int;
4150#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004151 bsi->rdstat[i][mode_idx].brdcost = INT64_MAX;
4152 if (!(inter_mode_mask & (1 << this_mode)))
4153 continue;
4154
Yue Chen968bbc72016-01-19 16:45:45 -08004155 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
4156#if CONFIG_REF_MV && CONFIG_EXT_INTER
4157 mbmi_ext->compound_mode_context,
4158#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4159 frame_mv,
Jingning Han387a10e2015-12-09 09:07:39 -08004160 this_mode, mbmi->ref_frame, bsize, i))
Jingning Han3ee6db62015-08-05 19:00:31 -07004161 continue;
4162
4163 memcpy(orig_pre, pd->pre, sizeof(orig_pre));
4164 memcpy(bsi->rdstat[i][mode_idx].ta, t_above,
4165 sizeof(bsi->rdstat[i][mode_idx].ta));
4166 memcpy(bsi->rdstat[i][mode_idx].tl, t_left,
4167 sizeof(bsi->rdstat[i][mode_idx].tl));
4168
4169 // motion search for newmv (single predictor case only)
Yue Chen1ac85872016-01-07 15:13:52 -08004170 if (!has_second_rf &&
4171#if CONFIG_EXT_INTER
4172 have_newmv_in_inter_mode(this_mode) &&
4173 seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV
4174#else
4175 this_mode == NEWMV &&
4176 seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV
4177#endif // CONFIG_EXT_INTER
4178 ) {
4179#if CONFIG_EXT_INTER
4180 MV *const new_mv = &mode_mv[this_mode][0].as_mv;
4181#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004182 MV *const new_mv = &mode_mv[NEWMV][0].as_mv;
Yue Chen1ac85872016-01-07 15:13:52 -08004183#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004184 int step_param = 0;
paulwilkins4e692bb2015-12-08 15:48:24 +00004185 int bestsme = INT_MAX;
Jingning Han3ee6db62015-08-05 19:00:31 -07004186 int sadpb = x->sadperbit4;
4187 MV mvp_full;
4188 int max_mv;
4189 int cost_list[5];
4190
4191 /* Is the best so far sufficiently good that we cant justify doing
4192 * and new motion search. */
4193 if (best_rd < label_mv_thresh)
4194 break;
4195
4196 if (cpi->oxcf.mode != BEST) {
Yue Chen1ac85872016-01-07 15:13:52 -08004197#if CONFIG_EXT_INTER
4198 bsi->mvp.as_int = bsi->ref_mv[0]->as_int;
4199#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004200 // use previous block's result as next block's MV predictor.
4201 if (i > 0) {
4202 bsi->mvp.as_int = mi->bmi[i - 1].as_mv[0].as_int;
4203 if (i == 2)
4204 bsi->mvp.as_int = mi->bmi[i - 2].as_mv[0].as_int;
4205 }
Yue Chen1ac85872016-01-07 15:13:52 -08004206#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004207 }
4208 if (i == 0)
4209 max_mv = x->max_mv_context[mbmi->ref_frame[0]];
4210 else
James Zern5e16d392015-08-17 18:19:22 -07004211 max_mv =
4212 VPXMAX(abs(bsi->mvp.as_mv.row), abs(bsi->mvp.as_mv.col)) >> 3;
Jingning Han3ee6db62015-08-05 19:00:31 -07004213
4214 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
4215 // Take wtd average of the step_params based on the last frame's
4216 // max mv magnitude and the best ref mvs of the current block for
4217 // the given reference.
4218 step_param = (vp10_init_search_range(max_mv) +
4219 cpi->mv_step_param) / 2;
4220 } else {
4221 step_param = cpi->mv_step_param;
4222 }
4223
4224 mvp_full.row = bsi->mvp.as_mv.row >> 3;
4225 mvp_full.col = bsi->mvp.as_mv.col >> 3;
4226
4227 if (cpi->sf.adaptive_motion_search) {
4228 mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
4229 mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
James Zern5e16d392015-08-17 18:19:22 -07004230 step_param = VPXMAX(step_param, 8);
Jingning Han3ee6db62015-08-05 19:00:31 -07004231 }
4232
4233 // adjust src pointer for this block
4234 mi_buf_shift(x, i);
4235
4236 vp10_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
4237
4238 bestsme = vp10_full_pixel_search(
4239 cpi, x, bsize, &mvp_full, step_param, sadpb,
4240 cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
4241 &bsi->ref_mv[0]->as_mv, new_mv,
4242 INT_MAX, 1);
4243
Jingning Han3ee6db62015-08-05 19:00:31 -07004244 if (bestsme < INT_MAX) {
4245 int distortion;
4246 cpi->find_fractional_mv_step(
4247 x,
4248 new_mv,
4249 &bsi->ref_mv[0]->as_mv,
4250 cm->allow_high_precision_mv,
4251 x->errorperbit, &cpi->fn_ptr[bsize],
4252 cpi->sf.mv.subpel_force_stop,
4253 cpi->sf.mv.subpel_iters_per_step,
4254 cond_cost_list(cpi, cost_list),
4255 x->nmvjointcost, x->mvcost,
4256 &distortion,
4257 &x->pred_sse[mbmi->ref_frame[0]],
4258 NULL, 0, 0);
4259
4260 // save motion search result for use in compound prediction
Yue Chen1ac85872016-01-07 15:13:52 -08004261#if CONFIG_EXT_INTER
4262 seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_mv = *new_mv;
4263#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004264 seg_mvs[i][mbmi->ref_frame[0]].as_mv = *new_mv;
Yue Chen1ac85872016-01-07 15:13:52 -08004265#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004266 }
4267
4268 if (cpi->sf.adaptive_motion_search)
4269 x->pred_mv[mbmi->ref_frame[0]] = *new_mv;
4270
4271 // restore src pointers
4272 mi_buf_restore(x, orig_src, orig_pre);
4273 }
4274
4275 if (has_second_rf) {
Yue Chen1ac85872016-01-07 15:13:52 -08004276#if CONFIG_EXT_INTER
4277 if (seg_mvs[i][mv_idx][mbmi->ref_frame[1]].as_int == INVALID_MV ||
4278 seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
4279#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004280 if (seg_mvs[i][mbmi->ref_frame[1]].as_int == INVALID_MV ||
4281 seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yue Chen1ac85872016-01-07 15:13:52 -08004282#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004283 continue;
4284 }
4285
Yue Chen968bbc72016-01-19 16:45:45 -08004286 if (has_second_rf &&
4287#if CONFIG_EXT_INTER
4288 this_mode == NEW_NEWMV &&
4289#else
4290 this_mode == NEWMV &&
4291#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004292 mbmi->interp_filter == EIGHTTAP) {
4293 // adjust src pointers
4294 mi_buf_shift(x, i);
4295 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
4296 int rate_mv;
4297 joint_motion_search(cpi, x, bsize, frame_mv[this_mode],
Yue Chen1ac85872016-01-07 15:13:52 -08004298 mi_row, mi_col,
4299#if CONFIG_EXT_INTER
4300 bsi->ref_mv,
4301 seg_mvs[i][mv_idx],
4302#else
4303 seg_mvs[i],
4304#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004305 &rate_mv);
Yue Chen1ac85872016-01-07 15:13:52 -08004306#if CONFIG_EXT_INTER
4307 compound_seg_newmvs[i][0].as_int =
4308 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
4309 compound_seg_newmvs[i][1].as_int =
4310 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
4311#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004312 seg_mvs[i][mbmi->ref_frame[0]].as_int =
4313 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
4314 seg_mvs[i][mbmi->ref_frame[1]].as_int =
4315 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08004316#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004317 }
4318 // restore src pointers
4319 mi_buf_restore(x, orig_src, orig_pre);
4320 }
4321
4322 bsi->rdstat[i][mode_idx].brate =
4323 set_and_cost_bmi_mvs(cpi, x, xd, i, this_mode, mode_mv[this_mode],
Yue Chen1ac85872016-01-07 15:13:52 -08004324 frame_mv,
4325#if CONFIG_EXT_INTER
4326 seg_mvs[i][mv_idx],
4327 compound_seg_newmvs[i],
4328#else
4329 seg_mvs[i],
4330#endif // CONFIG_EXT_INTER
4331 bsi->ref_mv,
Jingning Han3ee6db62015-08-05 19:00:31 -07004332 x->nmvjointcost, x->mvcost);
4333
4334 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
4335 bsi->rdstat[i][mode_idx].mvs[ref].as_int =
4336 mode_mv[this_mode][ref].as_int;
4337 if (num_4x4_blocks_wide > 1)
4338 bsi->rdstat[i + 1][mode_idx].mvs[ref].as_int =
4339 mode_mv[this_mode][ref].as_int;
4340 if (num_4x4_blocks_high > 1)
4341 bsi->rdstat[i + 2][mode_idx].mvs[ref].as_int =
4342 mode_mv[this_mode][ref].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08004343#if CONFIG_EXT_INTER
4344 bsi->rdstat[i][mode_idx].ref_mv[ref].as_int =
4345 bsi->ref_mv[ref]->as_int;
4346 if (num_4x4_blocks_wide > 1)
4347 bsi->rdstat[i + 1][mode_idx].ref_mv[ref].as_int =
4348 bsi->ref_mv[ref]->as_int;
4349 if (num_4x4_blocks_high > 1)
4350 bsi->rdstat[i + 2][mode_idx].ref_mv[ref].as_int =
4351 bsi->ref_mv[ref]->as_int;
4352#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004353 }
4354
4355 // Trap vectors that reach beyond the UMV borders
4356 if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
4357 (has_second_rf &&
4358 mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
4359 continue;
4360
4361 if (filter_idx > 0) {
4362 BEST_SEG_INFO *ref_bsi = bsi_buf;
4363 subpelmv = 0;
4364 have_ref = 1;
4365
4366 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
4367 subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
Yue Chen1ac85872016-01-07 15:13:52 -08004368#if CONFIG_EXT_INTER
4369 if (have_newmv_in_inter_mode(this_mode))
4370 have_ref &= (
4371 (mode_mv[this_mode][ref].as_int ==
4372 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int) &&
4373 (bsi->ref_mv[ref]->as_int ==
4374 ref_bsi->rdstat[i][mode_idx].ref_mv[ref].as_int));
4375 else
4376#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004377 have_ref &= mode_mv[this_mode][ref].as_int ==
4378 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
4379 }
4380
4381 if (filter_idx > 1 && !subpelmv && !have_ref) {
4382 ref_bsi = bsi_buf + 1;
4383 have_ref = 1;
4384 for (ref = 0; ref < 1 + has_second_rf; ++ref)
Yue Chen1ac85872016-01-07 15:13:52 -08004385#if CONFIG_EXT_INTER
4386 if (have_newmv_in_inter_mode(this_mode))
4387 have_ref &= (
4388 (mode_mv[this_mode][ref].as_int ==
4389 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int) &&
4390 (bsi->ref_mv[ref]->as_int ==
4391 ref_bsi->rdstat[i][mode_idx].ref_mv[ref].as_int));
4392 else
4393#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004394 have_ref &= mode_mv[this_mode][ref].as_int ==
4395 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
4396 }
4397
4398 if (!subpelmv && have_ref &&
4399 ref_bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) {
4400 memcpy(&bsi->rdstat[i][mode_idx], &ref_bsi->rdstat[i][mode_idx],
4401 sizeof(SEG_RDSTAT));
4402 if (num_4x4_blocks_wide > 1)
4403 bsi->rdstat[i + 1][mode_idx].eobs =
4404 ref_bsi->rdstat[i + 1][mode_idx].eobs;
4405 if (num_4x4_blocks_high > 1)
4406 bsi->rdstat[i + 2][mode_idx].eobs =
4407 ref_bsi->rdstat[i + 2][mode_idx].eobs;
4408
4409 if (bsi->rdstat[i][mode_idx].brdcost < best_rd) {
4410 mode_selected = this_mode;
4411 best_rd = bsi->rdstat[i][mode_idx].brdcost;
4412 }
4413 continue;
4414 }
4415 }
4416
4417 bsi->rdstat[i][mode_idx].brdcost =
4418 encode_inter_mb_segment(cpi, x,
4419 bsi->segment_rd - this_segment_rd, i,
4420 &bsi->rdstat[i][mode_idx].byrate,
4421 &bsi->rdstat[i][mode_idx].bdist,
4422 &bsi->rdstat[i][mode_idx].bsse,
4423 bsi->rdstat[i][mode_idx].ta,
4424 bsi->rdstat[i][mode_idx].tl,
Yaowu Xu7c514e22015-09-28 15:55:46 -07004425 idy, idx,
Jingning Han3ee6db62015-08-05 19:00:31 -07004426 mi_row, mi_col);
4427 if (bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) {
4428 bsi->rdstat[i][mode_idx].brdcost += RDCOST(x->rdmult, x->rddiv,
4429 bsi->rdstat[i][mode_idx].brate, 0);
4430 bsi->rdstat[i][mode_idx].brate += bsi->rdstat[i][mode_idx].byrate;
4431 bsi->rdstat[i][mode_idx].eobs = p->eobs[i];
4432 if (num_4x4_blocks_wide > 1)
4433 bsi->rdstat[i + 1][mode_idx].eobs = p->eobs[i + 1];
4434 if (num_4x4_blocks_high > 1)
4435 bsi->rdstat[i + 2][mode_idx].eobs = p->eobs[i + 2];
4436 }
4437
4438 if (bsi->rdstat[i][mode_idx].brdcost < best_rd) {
4439 mode_selected = this_mode;
4440 best_rd = bsi->rdstat[i][mode_idx].brdcost;
4441 }
4442 } /*for each 4x4 mode*/
4443
4444 if (best_rd == INT64_MAX) {
4445 int iy, midx;
4446 for (iy = i + 1; iy < 4; ++iy)
Yue Chen968bbc72016-01-19 16:45:45 -08004447#if CONFIG_EXT_INTER
4448 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
4449#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004450 for (midx = 0; midx < INTER_MODES; ++midx)
Yue Chen968bbc72016-01-19 16:45:45 -08004451#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004452 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
4453 bsi->segment_rd = INT64_MAX;
4454 return INT64_MAX;
4455 }
4456
4457 mode_idx = INTER_OFFSET(mode_selected);
4458 memcpy(t_above, bsi->rdstat[i][mode_idx].ta, sizeof(t_above));
4459 memcpy(t_left, bsi->rdstat[i][mode_idx].tl, sizeof(t_left));
4460
Yue Chen1ac85872016-01-07 15:13:52 -08004461#if CONFIG_EXT_INTER
4462 mv_idx = (mode_selected == NEWFROMNEARMV) ? 1 : 0;
4463 bsi->ref_mv[0]->as_int = bsi->rdstat[i][mode_idx].ref_mv[0].as_int;
4464 if (has_second_rf)
4465 bsi->ref_mv[1]->as_int = bsi->rdstat[i][mode_idx].ref_mv[1].as_int;
4466#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004467 set_and_cost_bmi_mvs(cpi, x, xd, i, mode_selected, mode_mv[mode_selected],
Yue Chen1ac85872016-01-07 15:13:52 -08004468 frame_mv,
4469#if CONFIG_EXT_INTER
4470 seg_mvs[i][mv_idx],
4471 compound_seg_newmvs[i],
4472#else
4473 seg_mvs[i],
4474#endif // CONFIG_EXT_INTER
4475 bsi->ref_mv, x->nmvjointcost, x->mvcost);
Jingning Han3ee6db62015-08-05 19:00:31 -07004476
4477 br += bsi->rdstat[i][mode_idx].brate;
4478 bd += bsi->rdstat[i][mode_idx].bdist;
4479 block_sse += bsi->rdstat[i][mode_idx].bsse;
4480 segmentyrate += bsi->rdstat[i][mode_idx].byrate;
4481 this_segment_rd += bsi->rdstat[i][mode_idx].brdcost;
4482
4483 if (this_segment_rd > bsi->segment_rd) {
4484 int iy, midx;
4485 for (iy = i + 1; iy < 4; ++iy)
Yue Chen968bbc72016-01-19 16:45:45 -08004486#if CONFIG_EXT_INTER
4487 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
4488#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004489 for (midx = 0; midx < INTER_MODES; ++midx)
Yue Chen968bbc72016-01-19 16:45:45 -08004490#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004491 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
4492 bsi->segment_rd = INT64_MAX;
4493 return INT64_MAX;
4494 }
4495 }
4496 } /* for each label */
4497
4498 bsi->r = br;
4499 bsi->d = bd;
4500 bsi->segment_yrate = segmentyrate;
4501 bsi->segment_rd = this_segment_rd;
4502 bsi->sse = block_sse;
4503
4504 // update the coding decisions
4505 for (k = 0; k < 4; ++k)
4506 bsi->modes[k] = mi->bmi[k].as_mode;
4507
4508 if (bsi->segment_rd > best_rd)
4509 return INT64_MAX;
4510 /* set it to the best */
4511 for (i = 0; i < 4; i++) {
4512 mode_idx = INTER_OFFSET(bsi->modes[i]);
4513 mi->bmi[i].as_mv[0].as_int = bsi->rdstat[i][mode_idx].mvs[0].as_int;
4514 if (has_second_ref(mbmi))
4515 mi->bmi[i].as_mv[1].as_int = bsi->rdstat[i][mode_idx].mvs[1].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08004516#if CONFIG_EXT_INTER
4517 mi->bmi[i].ref_mv[0].as_int = bsi->rdstat[i][mode_idx].ref_mv[0].as_int;
4518 if (has_second_rf)
4519 mi->bmi[i].ref_mv[1].as_int = bsi->rdstat[i][mode_idx].ref_mv[1].as_int;
4520#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004521 x->plane[0].eobs[i] = bsi->rdstat[i][mode_idx].eobs;
4522 mi->bmi[i].as_mode = bsi->modes[i];
4523 }
4524
4525 /*
4526 * used to set mbmi->mv.as_int
4527 */
4528 *returntotrate = bsi->r;
4529 *returndistortion = bsi->d;
4530 *returnyrate = bsi->segment_yrate;
4531 *skippable = vp10_is_skippable_in_plane(x, BLOCK_8X8, 0);
4532 *psse = bsi->sse;
4533 mbmi->mode = bsi->modes[3];
4534
4535 return bsi->segment_rd;
4536}
4537
Yaowu Xufc7cbd12015-08-13 09:36:53 -07004538static void estimate_ref_frame_costs(const VP10_COMMON *cm,
Jingning Han3ee6db62015-08-05 19:00:31 -07004539 const MACROBLOCKD *xd,
4540 int segment_id,
4541 unsigned int *ref_costs_single,
4542 unsigned int *ref_costs_comp,
4543 vpx_prob *comp_mode_p) {
4544 int seg_ref_active = segfeature_active(&cm->seg, segment_id,
4545 SEG_LVL_REF_FRAME);
4546 if (seg_ref_active) {
4547 memset(ref_costs_single, 0, MAX_REF_FRAMES * sizeof(*ref_costs_single));
4548 memset(ref_costs_comp, 0, MAX_REF_FRAMES * sizeof(*ref_costs_comp));
4549 *comp_mode_p = 128;
4550 } else {
4551 vpx_prob intra_inter_p = vp10_get_intra_inter_prob(cm, xd);
4552 vpx_prob comp_inter_p = 128;
4553
4554 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
4555 comp_inter_p = vp10_get_reference_mode_prob(cm, xd);
4556 *comp_mode_p = comp_inter_p;
4557 } else {
4558 *comp_mode_p = 128;
4559 }
4560
4561 ref_costs_single[INTRA_FRAME] = vp10_cost_bit(intra_inter_p, 0);
4562
4563 if (cm->reference_mode != COMPOUND_REFERENCE) {
4564 vpx_prob ref_single_p1 = vp10_get_pred_prob_single_ref_p1(cm, xd);
4565 vpx_prob ref_single_p2 = vp10_get_pred_prob_single_ref_p2(cm, xd);
Zoe Liu3ec16012015-11-12 02:12:17 -08004566#if CONFIG_EXT_REFS
4567 vpx_prob ref_single_p3 = vp10_get_pred_prob_single_ref_p3(cm, xd);
4568 vpx_prob ref_single_p4 = vp10_get_pred_prob_single_ref_p4(cm, xd);
4569 vpx_prob ref_single_p5 = vp10_get_pred_prob_single_ref_p5(cm, xd);
4570#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07004571 unsigned int base_cost = vp10_cost_bit(intra_inter_p, 1);
4572
4573 if (cm->reference_mode == REFERENCE_MODE_SELECT)
4574 base_cost += vp10_cost_bit(comp_inter_p, 0);
4575
Zoe Liu3ec16012015-11-12 02:12:17 -08004576 ref_costs_single[LAST_FRAME] =
4577#if CONFIG_EXT_REFS
4578 ref_costs_single[LAST2_FRAME] =
4579 ref_costs_single[LAST3_FRAME] =
4580 ref_costs_single[LAST4_FRAME] =
4581#endif // CONFIG_EXT_REFS
4582 ref_costs_single[GOLDEN_FRAME] =
Jingning Han3ee6db62015-08-05 19:00:31 -07004583 ref_costs_single[ALTREF_FRAME] = base_cost;
Zoe Liu3ec16012015-11-12 02:12:17 -08004584
4585#if CONFIG_EXT_REFS
4586 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p1, 0);
4587 ref_costs_single[LAST2_FRAME] += vp10_cost_bit(ref_single_p1, 0);
4588 ref_costs_single[LAST3_FRAME] += vp10_cost_bit(ref_single_p1, 0);
4589 ref_costs_single[LAST4_FRAME] += vp10_cost_bit(ref_single_p1, 0);
4590 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p1, 1);
4591 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p1, 1);
4592
4593 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p3, 0);
4594 ref_costs_single[LAST2_FRAME] += vp10_cost_bit(ref_single_p3, 0);
4595 ref_costs_single[LAST3_FRAME] += vp10_cost_bit(ref_single_p3, 1);
4596 ref_costs_single[LAST4_FRAME] += vp10_cost_bit(ref_single_p3, 1);
4597 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p2, 0);
4598 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p2, 1);
4599
4600 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p4, 0);
4601 ref_costs_single[LAST2_FRAME] += vp10_cost_bit(ref_single_p4, 1);
4602 ref_costs_single[LAST3_FRAME] += vp10_cost_bit(ref_single_p5, 0);
4603 ref_costs_single[LAST4_FRAME] += vp10_cost_bit(ref_single_p5, 1);
4604#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004605 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p1, 0);
4606 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p1, 1);
4607 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p1, 1);
4608 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p2, 0);
4609 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p2, 1);
Zoe Liu3ec16012015-11-12 02:12:17 -08004610#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07004611 } else {
4612 ref_costs_single[LAST_FRAME] = 512;
Zoe Liu3ec16012015-11-12 02:12:17 -08004613#if CONFIG_EXT_REFS
4614 ref_costs_single[LAST2_FRAME] = 512;
4615 ref_costs_single[LAST3_FRAME] = 512;
4616 ref_costs_single[LAST4_FRAME] = 512;
4617#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07004618 ref_costs_single[GOLDEN_FRAME] = 512;
4619 ref_costs_single[ALTREF_FRAME] = 512;
4620 }
Zoe Liu3ec16012015-11-12 02:12:17 -08004621
Jingning Han3ee6db62015-08-05 19:00:31 -07004622 if (cm->reference_mode != SINGLE_REFERENCE) {
4623 vpx_prob ref_comp_p = vp10_get_pred_prob_comp_ref_p(cm, xd);
Zoe Liu3ec16012015-11-12 02:12:17 -08004624#if CONFIG_EXT_REFS
4625 vpx_prob ref_comp_p1 = vp10_get_pred_prob_comp_ref_p1(cm, xd);
4626 vpx_prob ref_comp_p2 = vp10_get_pred_prob_comp_ref_p2(cm, xd);
4627 vpx_prob ref_comp_p3 = vp10_get_pred_prob_comp_ref_p3(cm, xd);
4628#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07004629 unsigned int base_cost = vp10_cost_bit(intra_inter_p, 1);
4630
4631 if (cm->reference_mode == REFERENCE_MODE_SELECT)
4632 base_cost += vp10_cost_bit(comp_inter_p, 1);
4633
Zoe Liu3ec16012015-11-12 02:12:17 -08004634 ref_costs_comp[LAST_FRAME] =
4635#if CONFIG_EXT_REFS
4636 ref_costs_comp[LAST2_FRAME] =
4637 ref_costs_comp[LAST3_FRAME] =
4638 ref_costs_comp[LAST4_FRAME] =
4639#endif // CONFIG_EXT_REFS
4640 ref_costs_comp[GOLDEN_FRAME] = base_cost;
4641
4642#if CONFIG_EXT_REFS
4643 ref_costs_comp[LAST_FRAME] += vp10_cost_bit(ref_comp_p, 0);
4644 ref_costs_comp[LAST2_FRAME] += vp10_cost_bit(ref_comp_p, 0);
4645 ref_costs_comp[LAST3_FRAME] += vp10_cost_bit(ref_comp_p, 1);
4646 ref_costs_comp[LAST4_FRAME] += vp10_cost_bit(ref_comp_p, 1);
4647 ref_costs_comp[GOLDEN_FRAME] += vp10_cost_bit(ref_comp_p, 1);
4648
4649 ref_costs_comp[LAST_FRAME] += vp10_cost_bit(ref_comp_p1, 1);
4650 ref_costs_comp[LAST2_FRAME] += vp10_cost_bit(ref_comp_p1, 0);
4651 ref_costs_comp[LAST3_FRAME] += vp10_cost_bit(ref_comp_p2, 0);
4652 ref_costs_comp[LAST4_FRAME] += vp10_cost_bit(ref_comp_p2, 0);
4653 ref_costs_comp[GOLDEN_FRAME] += vp10_cost_bit(ref_comp_p2, 1);
4654
4655 ref_costs_comp[LAST3_FRAME] += vp10_cost_bit(ref_comp_p3, 1);
4656 ref_costs_comp[LAST4_FRAME] += vp10_cost_bit(ref_comp_p3, 0);
4657#else
4658 ref_costs_comp[LAST_FRAME] += vp10_cost_bit(ref_comp_p, 0);
4659 ref_costs_comp[GOLDEN_FRAME] += vp10_cost_bit(ref_comp_p, 1);
4660#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07004661 } else {
4662 ref_costs_comp[LAST_FRAME] = 512;
Zoe Liu3ec16012015-11-12 02:12:17 -08004663#if CONFIG_EXT_REFS
4664 ref_costs_comp[LAST2_FRAME] = 512;
4665 ref_costs_comp[LAST3_FRAME] = 512;
4666 ref_costs_comp[LAST4_FRAME] = 512;
4667#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07004668 ref_costs_comp[GOLDEN_FRAME] = 512;
4669 }
4670 }
4671}
4672
4673static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
4674 int mode_index,
4675 int64_t comp_pred_diff[REFERENCE_MODES],
4676 int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS],
4677 int skippable) {
4678 MACROBLOCKD *const xd = &x->e_mbd;
4679
4680 // Take a snapshot of the coding context so it can be
4681 // restored if we decide to encode this way
4682 ctx->skip = x->skip;
4683 ctx->skippable = skippable;
4684 ctx->best_mode_index = mode_index;
4685 ctx->mic = *xd->mi[0];
4686 ctx->mbmi_ext = *x->mbmi_ext;
4687 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
4688 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
4689 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
4690
4691 memcpy(ctx->best_filter_diff, best_filter_diff,
4692 sizeof(*best_filter_diff) * SWITCHABLE_FILTER_CONTEXTS);
4693}
4694
Zoe Liu3ec16012015-11-12 02:12:17 -08004695static void setup_buffer_inter(
4696 VP10_COMP *cpi, MACROBLOCK *x,
4697 MV_REFERENCE_FRAME ref_frame,
4698 BLOCK_SIZE block_size,
4699 int mi_row, int mi_col,
4700 int_mv frame_nearest_mv[MAX_REF_FRAMES],
4701 int_mv frame_near_mv[MAX_REF_FRAMES],
4702 struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE]) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07004703 const VP10_COMMON *cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07004704 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
4705 MACROBLOCKD *const xd = &x->e_mbd;
4706 MODE_INFO *const mi = xd->mi[0];
4707 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
4708 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
4709 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4710
4711 assert(yv12 != NULL);
4712
4713 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
4714 // use the UV scaling factors.
4715 vp10_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
4716
4717 // Gets an initial list of candidate vectors from neighbours and orders them
Jingning Hane5c57c52015-11-23 15:05:18 -08004718 vp10_find_mv_refs(cm, xd, mi, ref_frame,
4719#if CONFIG_REF_MV
4720 &mbmi_ext->ref_mv_count[ref_frame],
4721 mbmi_ext->ref_mv_stack[ref_frame],
Yue Chen968bbc72016-01-19 16:45:45 -08004722#if CONFIG_EXT_INTER
4723 mbmi_ext->compound_mode_context,
4724#endif // CONFIG_EXT_INTER
Jingning Hane5c57c52015-11-23 15:05:18 -08004725#endif
4726 candidates, mi_row, mi_col,
4727 NULL, NULL, mbmi_ext->mode_context);
Jingning Han3ee6db62015-08-05 19:00:31 -07004728
4729 // Candidate refinement carried out at encoder and decoder
Ronald S. Bultje5b4805d2015-10-02 11:51:54 -04004730 vp10_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
4731 &frame_nearest_mv[ref_frame],
4732 &frame_near_mv[ref_frame]);
Jingning Han3ee6db62015-08-05 19:00:31 -07004733
4734 // Further refinement that is encode side only to test the top few candidates
4735 // in full and choose the best as the centre point for subsequent searches.
4736 // The current implementation doesn't support scaling.
4737 if (!vp10_is_scaled(sf) && block_size >= BLOCK_8X8)
4738 vp10_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride,
4739 ref_frame, block_size);
4740}
4741
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004742static void single_motion_search(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07004743 BLOCK_SIZE bsize,
4744 int mi_row, int mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08004745#if CONFIG_EXT_INTER
4746 int ref_idx,
4747 int mv_idx,
4748#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004749 int_mv *tmp_mv, int *rate_mv) {
4750 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xufc7cbd12015-08-13 09:36:53 -07004751 const VP10_COMMON *cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07004752 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4753 struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0, 0}};
4754 int bestsme = INT_MAX;
4755 int step_param;
4756 int sadpb = x->sadperbit16;
4757 MV mvp_full;
Yue Chen1ac85872016-01-07 15:13:52 -08004758#if CONFIG_EXT_INTER
4759 int ref = mbmi->ref_frame[ref_idx];
4760 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
4761#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004762 int ref = mbmi->ref_frame[0];
4763 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
Yue Chen1ac85872016-01-07 15:13:52 -08004764#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004765
4766 int tmp_col_min = x->mv_col_min;
4767 int tmp_col_max = x->mv_col_max;
4768 int tmp_row_min = x->mv_row_min;
4769 int tmp_row_max = x->mv_row_max;
4770 int cost_list[5];
4771
4772 const YV12_BUFFER_CONFIG *scaled_ref_frame = vp10_get_scaled_ref_frame(cpi,
4773 ref);
4774
4775 MV pred_mv[3];
4776 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
4777 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
4778 pred_mv[2] = x->pred_mv[ref];
4779
4780 if (scaled_ref_frame) {
4781 int i;
4782 // Swap out the reference frame for a version that's been scaled to
4783 // match the resolution of the current frame, allowing the existing
4784 // motion search code to be used without additional modifications.
4785 for (i = 0; i < MAX_MB_PLANE; i++)
4786 backup_yv12[i] = xd->plane[i].pre[0];
4787
4788 vp10_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
4789 }
4790
4791 vp10_set_mv_search_range(x, &ref_mv);
4792
4793 // Work out the size of the first step in the mv step search.
James Zern5e16d392015-08-17 18:19:22 -07004794 // 0 here is maximum length first step. 1 is VPXMAX >> 1 etc.
Jingning Han3ee6db62015-08-05 19:00:31 -07004795 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
4796 // Take wtd average of the step_params based on the last frame's
4797 // max mv magnitude and that based on the best ref mvs of the current
4798 // block for the given reference.
4799 step_param = (vp10_init_search_range(x->max_mv_context[ref]) +
4800 cpi->mv_step_param) / 2;
4801 } else {
4802 step_param = cpi->mv_step_param;
4803 }
4804
4805 if (cpi->sf.adaptive_motion_search && bsize < BLOCK_64X64) {
James Zern5e16d392015-08-17 18:19:22 -07004806 int boffset =
4807 2 * (b_width_log2_lookup[BLOCK_64X64] -
4808 VPXMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
4809 step_param = VPXMAX(step_param, boffset);
Jingning Han3ee6db62015-08-05 19:00:31 -07004810 }
4811
4812 if (cpi->sf.adaptive_motion_search) {
4813 int bwl = b_width_log2_lookup[bsize];
4814 int bhl = b_height_log2_lookup[bsize];
4815 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
4816
4817 if (tlevel < 5)
4818 step_param += 2;
4819
4820 // prev_mv_sad is not setup for dynamically scaled frames.
4821 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
4822 int i;
4823 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
4824 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
4825 x->pred_mv[ref].row = 0;
4826 x->pred_mv[ref].col = 0;
4827 tmp_mv->as_int = INVALID_MV;
4828
4829 if (scaled_ref_frame) {
4830 int i;
4831 for (i = 0; i < MAX_MB_PLANE; ++i)
4832 xd->plane[i].pre[0] = backup_yv12[i];
4833 }
4834 return;
4835 }
4836 }
4837 }
4838 }
4839
4840 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
4841
4842 mvp_full.col >>= 3;
4843 mvp_full.row >>= 3;
4844
4845 bestsme = vp10_full_pixel_search(cpi, x, bsize, &mvp_full, step_param, sadpb,
4846 cond_cost_list(cpi, cost_list),
4847 &ref_mv, &tmp_mv->as_mv, INT_MAX, 1);
4848
4849 x->mv_col_min = tmp_col_min;
4850 x->mv_col_max = tmp_col_max;
4851 x->mv_row_min = tmp_row_min;
4852 x->mv_row_max = tmp_row_max;
4853
4854 if (bestsme < INT_MAX) {
4855 int dis; /* TODO: use dis in distortion calculation later. */
4856 cpi->find_fractional_mv_step(x, &tmp_mv->as_mv, &ref_mv,
4857 cm->allow_high_precision_mv,
4858 x->errorperbit,
4859 &cpi->fn_ptr[bsize],
4860 cpi->sf.mv.subpel_force_stop,
4861 cpi->sf.mv.subpel_iters_per_step,
4862 cond_cost_list(cpi, cost_list),
4863 x->nmvjointcost, x->mvcost,
4864 &dis, &x->pred_sse[ref], NULL, 0, 0);
4865 }
4866 *rate_mv = vp10_mv_bit_cost(&tmp_mv->as_mv, &ref_mv,
4867 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
4868
4869 if (cpi->sf.adaptive_motion_search)
4870 x->pred_mv[ref] = tmp_mv->as_mv;
4871
4872 if (scaled_ref_frame) {
4873 int i;
4874 for (i = 0; i < MAX_MB_PLANE; i++)
4875 xd->plane[i].pre[0] = backup_yv12[i];
4876 }
4877}
4878
Jingning Han3ee6db62015-08-05 19:00:31 -07004879static INLINE void restore_dst_buf(MACROBLOCKD *xd,
4880 uint8_t *orig_dst[MAX_MB_PLANE],
4881 int orig_dst_stride[MAX_MB_PLANE]) {
4882 int i;
4883 for (i = 0; i < MAX_MB_PLANE; i++) {
4884 xd->plane[i].dst.buf = orig_dst[i];
4885 xd->plane[i].dst.stride = orig_dst_stride[i];
4886 }
4887}
4888
4889// In some situations we want to discount tha pparent cost of a new motion
4890// vector. Where there is a subtle motion field and especially where there is
4891// low spatial complexity then it can be hard to cover the cost of a new motion
4892// vector in a single block, even if that motion vector reduces distortion.
4893// However, once established that vector may be usable through the nearest and
4894// near mv modes to reduce distortion in subsequent blocks and also improve
4895// visual quality.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004896static int discount_newmv_test(const VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07004897 int this_mode,
4898 int_mv this_mv,
4899 int_mv (*mode_mv)[MAX_REF_FRAMES],
4900 int ref_frame) {
4901 return (!cpi->rc.is_src_frame_alt_ref &&
4902 (this_mode == NEWMV) &&
4903 (this_mv.as_int != 0) &&
4904 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
4905 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
4906 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
4907 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
4908}
4909
Ronald S. Bultje5b4805d2015-10-02 11:51:54 -04004910#define LEFT_TOP_MARGIN ((VP9_ENC_BORDER_IN_PIXELS - VP9_INTERP_EXTEND) << 3)
4911#define RIGHT_BOTTOM_MARGIN ((VP9_ENC_BORDER_IN_PIXELS -\
4912 VP9_INTERP_EXTEND) << 3)
4913
4914// TODO(jingning): this mv clamping function should be block size dependent.
4915static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
4916 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
4917 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
4918 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
4919 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
4920}
4921
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004922static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07004923 BLOCK_SIZE bsize,
4924 int *rate2, int64_t *distortion,
4925 int *skippable,
4926 int *rate_y, int *rate_uv,
4927 int *disable_skip,
4928 int_mv (*mode_mv)[MAX_REF_FRAMES],
4929 int mi_row, int mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08004930#if CONFIG_EXT_INTER
4931 int_mv single_newmvs[2][MAX_REF_FRAMES],
4932#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004933 int_mv single_newmv[MAX_REF_FRAMES],
Yue Chen1ac85872016-01-07 15:13:52 -08004934#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004935 INTERP_FILTER (*single_filter)[MAX_REF_FRAMES],
4936 int (*single_skippable)[MAX_REF_FRAMES],
4937 int64_t *psse,
4938 const int64_t ref_best_rd,
4939 int64_t *mask_filter,
4940 int64_t filter_cache[]) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07004941 VP10_COMMON *cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07004942 MACROBLOCKD *xd = &x->e_mbd;
4943 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4944 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4945 const int is_comp_pred = has_second_ref(mbmi);
4946 const int this_mode = mbmi->mode;
4947 int_mv *frame_mv = mode_mv[this_mode];
4948 int i;
4949 int refs[2] = { mbmi->ref_frame[0],
4950 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
4951 int_mv cur_mv[2];
Yue Chen1ac85872016-01-07 15:13:52 -08004952#if CONFIG_EXT_INTER
4953 int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
4954 int_mv single_newmv[MAX_REF_FRAMES];
Yue Chen968bbc72016-01-19 16:45:45 -08004955#if CONFIG_REF_MV
4956 uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
4957#endif
Yue Chen1ac85872016-01-07 15:13:52 -08004958#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004959#if CONFIG_VP9_HIGHBITDEPTH
4960 DECLARE_ALIGNED(16, uint16_t, tmp_buf16[MAX_MB_PLANE * 64 * 64]);
4961 uint8_t *tmp_buf;
4962#else
4963 DECLARE_ALIGNED(16, uint8_t, tmp_buf[MAX_MB_PLANE * 64 * 64]);
4964#endif // CONFIG_VP9_HIGHBITDEPTH
4965 int pred_exists = 0;
4966 int intpel_mv;
4967 int64_t rd, tmp_rd, best_rd = INT64_MAX;
4968 int best_needs_copy = 0;
4969 uint8_t *orig_dst[MAX_MB_PLANE];
4970 int orig_dst_stride[MAX_MB_PLANE];
4971 int rs = 0;
4972 INTERP_FILTER best_filter = SWITCHABLE;
4973 uint8_t skip_txfm[MAX_MB_PLANE << 2] = {0};
4974 int64_t bsse[MAX_MB_PLANE << 2] = {0};
4975
4976 int bsl = mi_width_log2_lookup[bsize];
4977 int pred_filter_search = cpi->sf.cb_pred_filter_search ?
4978 (((mi_row + mi_col) >> bsl) +
4979 get_chessboard_index(cm->current_video_frame)) & 0x1 : 0;
4980
4981 int skip_txfm_sb = 0;
4982 int64_t skip_sse_sb = INT64_MAX;
4983 int64_t distortion_y = 0, distortion_uv = 0;
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004984 int16_t mode_ctx = mbmi_ext->mode_context[refs[0]];
4985
4986#if CONFIG_REF_MV
Yue Chen968bbc72016-01-19 16:45:45 -08004987#if CONFIG_EXT_INTER
4988 if (is_comp_pred)
4989 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
4990 else
4991#endif // CONFIG_EXT_INTER
Jingning Han387a10e2015-12-09 09:07:39 -08004992 mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
4993 mbmi->ref_frame, bsize, -1);
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004994#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07004995
4996#if CONFIG_VP9_HIGHBITDEPTH
4997 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
4998 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf16);
4999 } else {
5000 tmp_buf = (uint8_t *)tmp_buf16;
5001 }
5002#endif // CONFIG_VP9_HIGHBITDEPTH
5003
5004 if (pred_filter_search) {
5005 INTERP_FILTER af = SWITCHABLE, lf = SWITCHABLE;
5006 if (xd->up_available)
5007 af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
5008 if (xd->left_available)
5009 lf = xd->mi[-1]->mbmi.interp_filter;
5010
Yue Chen1ac85872016-01-07 15:13:52 -08005011#if CONFIG_EXT_INTER
Yue Chen968bbc72016-01-19 16:45:45 -08005012 if ((this_mode != NEWMV && this_mode != NEWFROMNEARMV &&
5013 this_mode != NEW_NEWMV) || (af == lf))
Yue Chen1ac85872016-01-07 15:13:52 -08005014#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005015 if ((this_mode != NEWMV) || (af == lf))
Yue Chen1ac85872016-01-07 15:13:52 -08005016#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005017 best_filter = af;
5018 }
5019
5020 if (is_comp_pred) {
5021 if (frame_mv[refs[0]].as_int == INVALID_MV ||
5022 frame_mv[refs[1]].as_int == INVALID_MV)
5023 return INT64_MAX;
5024
5025 if (cpi->sf.adaptive_mode_search) {
Yue Chen968bbc72016-01-19 16:45:45 -08005026#if CONFIG_EXT_INTER
5027 switch (this_mode) {
5028 case NEAREST_NEARESTMV:
5029 if (single_filter[NEARESTMV][refs[0]] ==
5030 single_filter[NEARESTMV][refs[1]])
5031 best_filter = single_filter[NEARESTMV][refs[0]];
5032 break;
5033 case NEAREST_NEARMV:
5034 if (single_filter[NEARESTMV][refs[0]] ==
5035 single_filter[NEARMV][refs[1]])
5036 best_filter = single_filter[NEARESTMV][refs[0]];
5037 break;
5038 case NEAR_NEARESTMV:
5039 if (single_filter[NEARMV][refs[0]] ==
5040 single_filter[NEARESTMV][refs[1]])
5041 best_filter = single_filter[NEARMV][refs[0]];
5042 break;
5043 case ZERO_ZEROMV:
5044 if (single_filter[ZEROMV][refs[0]] ==
5045 single_filter[ZEROMV][refs[1]])
5046 best_filter = single_filter[ZEROMV][refs[0]];
5047 break;
5048 case NEW_NEWMV:
5049 if (single_filter[NEWMV][refs[0]] ==
5050 single_filter[NEWMV][refs[1]])
5051 best_filter = single_filter[NEWMV][refs[0]];
5052 break;
5053 case NEAREST_NEWMV:
5054 if (single_filter[NEARESTMV][refs[0]] ==
5055 single_filter[NEWMV][refs[1]])
5056 best_filter = single_filter[NEARESTMV][refs[0]];
5057 break;
5058 case NEAR_NEWMV:
5059 if (single_filter[NEARMV][refs[0]] ==
5060 single_filter[NEWMV][refs[1]])
5061 best_filter = single_filter[NEARMV][refs[0]];
5062 break;
5063 case NEW_NEARESTMV:
5064 if (single_filter[NEWMV][refs[0]] ==
5065 single_filter[NEARESTMV][refs[1]])
5066 best_filter = single_filter[NEWMV][refs[0]];
5067 break;
5068 case NEW_NEARMV:
5069 if (single_filter[NEWMV][refs[0]] ==
5070 single_filter[NEARMV][refs[1]])
5071 best_filter = single_filter[NEWMV][refs[0]];
5072 break;
5073 default:
5074 if (single_filter[this_mode][refs[0]] ==
5075 single_filter[this_mode][refs[1]])
5076 best_filter = single_filter[this_mode][refs[0]];
5077 break;
5078 }
5079#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005080 if (single_filter[this_mode][refs[0]] ==
5081 single_filter[this_mode][refs[1]])
5082 best_filter = single_filter[this_mode][refs[0]];
Yue Chen968bbc72016-01-19 16:45:45 -08005083#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005084 }
5085 }
5086
Yue Chen1ac85872016-01-07 15:13:52 -08005087#if CONFIG_EXT_INTER
5088 if (have_newmv_in_inter_mode(this_mode)) {
5089#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005090 if (this_mode == NEWMV) {
Yue Chen1ac85872016-01-07 15:13:52 -08005091#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005092 int rate_mv;
5093 if (is_comp_pred) {
Yue Chen1ac85872016-01-07 15:13:52 -08005094#if CONFIG_EXT_INTER
5095 for (i = 0; i < 2; ++i) {
5096 single_newmv[refs[i]].as_int =
Yue Chen968bbc72016-01-19 16:45:45 -08005097 single_newmvs[mv_idx][refs[i]].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08005098 }
Yue Chen968bbc72016-01-19 16:45:45 -08005099
5100 if (this_mode == NEW_NEWMV) {
5101 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
5102 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
5103
5104 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
5105 joint_motion_search(cpi, x, bsize, frame_mv,
5106 mi_row, mi_col, NULL, single_newmv, &rate_mv);
5107 } else {
5108 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
5109 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
5110 x->nmvjointcost, x->mvcost,
5111 MV_COST_WEIGHT);
5112 rate_mv += vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
5113 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
5114 x->nmvjointcost, x->mvcost,
5115 MV_COST_WEIGHT);
5116 }
5117 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
5118 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
5119 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
5120 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
5121 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5122 } else {
5123 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
5124 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
5125 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
5126 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5127 }
5128#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005129 // Initialize mv using single prediction mode result.
5130 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
5131 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
5132
5133 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
5134 joint_motion_search(cpi, x, bsize, frame_mv,
Yue Chen1ac85872016-01-07 15:13:52 -08005135 mi_row, mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08005136 single_newmv, &rate_mv);
Jingning Han3ee6db62015-08-05 19:00:31 -07005137 } else {
5138 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
5139 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
5140 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5141 rate_mv += vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
5142 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
5143 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5144 }
Yue Chen968bbc72016-01-19 16:45:45 -08005145#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005146 *rate2 += rate_mv;
5147 } else {
5148 int_mv tmp_mv;
5149 single_motion_search(cpi, x, bsize, mi_row, mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08005150#if CONFIG_EXT_INTER
5151 0, mv_idx,
5152#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005153 &tmp_mv, &rate_mv);
5154 if (tmp_mv.as_int == INVALID_MV)
5155 return INT64_MAX;
5156
5157 frame_mv[refs[0]].as_int =
5158 xd->mi[0]->bmi[0].as_mv[0].as_int = tmp_mv.as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08005159#if CONFIG_EXT_INTER
5160 single_newmvs[mv_idx][refs[0]].as_int = tmp_mv.as_int;
5161#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005162 single_newmv[refs[0]].as_int = tmp_mv.as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08005163#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005164
5165 // Estimate the rate implications of a new mv but discount this
5166 // under certain circumstances where we want to help initiate a weak
5167 // motion field, where the distortion gain for a single block may not
5168 // be enough to overcome the cost of a new mv.
5169 if (discount_newmv_test(cpi, this_mode, tmp_mv, mode_mv, refs[0])) {
James Zern5e16d392015-08-17 18:19:22 -07005170 *rate2 += VPXMAX((rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07005171 } else {
5172 *rate2 += rate_mv;
5173 }
5174 }
5175 }
5176
5177 for (i = 0; i < is_comp_pred + 1; ++i) {
5178 cur_mv[i] = frame_mv[refs[i]];
5179 // Clip "next_nearest" so that it does not extend to far out of image
Yue Chen1ac85872016-01-07 15:13:52 -08005180#if CONFIG_EXT_INTER
5181 if (this_mode != NEWMV && this_mode != NEWFROMNEARMV)
5182#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005183 if (this_mode != NEWMV)
Yue Chen1ac85872016-01-07 15:13:52 -08005184#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005185 clamp_mv2(&cur_mv[i].as_mv, xd);
5186
5187 if (mv_check_bounds(x, &cur_mv[i].as_mv))
5188 return INT64_MAX;
5189 mbmi->mv[i].as_int = cur_mv[i].as_int;
5190 }
5191
Jingning Han33cc1bd2016-01-12 15:06:59 -08005192#if CONFIG_REF_MV
Yue Chen968bbc72016-01-19 16:45:45 -08005193#if CONFIG_EXT_INTER
5194 if (this_mode == NEAREST_NEARESTMV) {
5195#else
Jingning Han33cc1bd2016-01-12 15:06:59 -08005196 if (this_mode == NEARESTMV && is_comp_pred) {
5197 uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
Yue Chen968bbc72016-01-19 16:45:45 -08005198#endif // CONFIG_EXT_INTER
Jingning Han3944cfb2016-01-13 09:03:15 -08005199 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
Jingning Han33cc1bd2016-01-12 15:06:59 -08005200 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
5201 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
5202
5203 for (i = 0; i < 2; ++i) {
5204 lower_mv_precision(&cur_mv[i].as_mv, cm->allow_high_precision_mv);
5205 clamp_mv2(&cur_mv[i].as_mv, xd);
5206 if (mv_check_bounds(x, &cur_mv[i].as_mv))
5207 return INT64_MAX;
5208 mbmi->mv[i].as_int = cur_mv[i].as_int;
5209 }
5210 }
5211 }
5212
Yue Chen968bbc72016-01-19 16:45:45 -08005213#if CONFIG_EXT_INTER
5214 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
5215 if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
5216 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
5217
5218 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
5219 clamp_mv2(&cur_mv[0].as_mv, xd);
5220 if (mv_check_bounds(x, &cur_mv[0].as_mv))
5221 return INT64_MAX;
5222 mbmi->mv[0].as_int = cur_mv[0].as_int;
5223 }
5224
5225 if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
5226 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
5227
5228 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
5229 clamp_mv2(&cur_mv[1].as_mv, xd);
5230 if (mv_check_bounds(x, &cur_mv[1].as_mv))
5231 return INT64_MAX;
5232 mbmi->mv[1].as_int = cur_mv[1].as_int;
5233 }
5234 }
5235
5236 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
5237 if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV) {
5238 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][1].this_mv;
5239
5240 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
5241 clamp_mv2(&cur_mv[0].as_mv, xd);
5242 if (mv_check_bounds(x, &cur_mv[0].as_mv))
5243 return INT64_MAX;
5244 mbmi->mv[0].as_int = cur_mv[0].as_int;
5245 }
5246
5247 if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV) {
5248 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][1].comp_mv;
5249
5250 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
5251 clamp_mv2(&cur_mv[1].as_mv, xd);
5252 if (mv_check_bounds(x, &cur_mv[1].as_mv))
5253 return INT64_MAX;
5254 mbmi->mv[1].as_int = cur_mv[1].as_int;
5255 }
5256 }
5257#else
Jingning Han33cc1bd2016-01-12 15:06:59 -08005258 if (this_mode == NEARMV && is_comp_pred) {
5259 uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
5260 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
Jingning Han28e03932016-01-20 17:40:47 -08005261 int ref_mv_idx = mbmi->ref_mv_idx + 1;
5262 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
5263 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
Jingning Han33cc1bd2016-01-12 15:06:59 -08005264
5265 for (i = 0; i < 2; ++i) {
5266 lower_mv_precision(&cur_mv[i].as_mv, cm->allow_high_precision_mv);
5267 clamp_mv2(&cur_mv[i].as_mv, xd);
5268 if (mv_check_bounds(x, &cur_mv[i].as_mv))
5269 return INT64_MAX;
5270 mbmi->mv[i].as_int = cur_mv[i].as_int;
5271 }
5272 }
5273 }
Yue Chen968bbc72016-01-19 16:45:45 -08005274#endif // CONFIG_EXT_INTER
Jingning Han33cc1bd2016-01-12 15:06:59 -08005275#endif
5276
Jingning Han3ee6db62015-08-05 19:00:31 -07005277 // do first prediction into the destination buffer. Do the next
5278 // prediction into a temporary buffer. Then keep track of which one
5279 // of these currently holds the best predictor, and use the other
5280 // one for future predictions. In the end, copy from tmp_buf to
5281 // dst if necessary.
5282 for (i = 0; i < MAX_MB_PLANE; i++) {
5283 orig_dst[i] = xd->plane[i].dst.buf;
5284 orig_dst_stride[i] = xd->plane[i].dst.stride;
5285 }
5286
5287 // We don't include the cost of the second reference here, because there
5288 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
5289 // words if you present them in that order, the second one is always known
5290 // if the first is known.
5291 //
5292 // Under some circumstances we discount the cost of new mv mode to encourage
5293 // initiation of a motion field.
5294 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]],
5295 mode_mv, refs[0])) {
Yue Chen1ac85872016-01-07 15:13:52 -08005296#if CONFIG_REF_MV && CONFIG_EXT_INTER
5297 *rate2 += VPXMIN(cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx),
5298 cost_mv_ref(cpi, NEARESTMV, is_comp_pred, mode_ctx));
5299#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08005300 *rate2 += VPXMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
5301 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
Yue Chen1ac85872016-01-07 15:13:52 -08005302#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005303 } else {
Yue Chen1ac85872016-01-07 15:13:52 -08005304#if CONFIG_REF_MV && CONFIG_EXT_INTER
5305 *rate2 += cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx);
5306#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08005307 *rate2 += cost_mv_ref(cpi, this_mode, mode_ctx);
Yue Chen1ac85872016-01-07 15:13:52 -08005308#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005309 }
5310
5311 if (RDCOST(x->rdmult, x->rddiv, *rate2, 0) > ref_best_rd &&
Yue Chen968bbc72016-01-19 16:45:45 -08005312#if CONFIG_EXT_INTER
5313 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV)
5314#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005315 mbmi->mode != NEARESTMV)
Yue Chen968bbc72016-01-19 16:45:45 -08005316#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005317 return INT64_MAX;
5318
5319 pred_exists = 0;
5320 // Are all MVs integer pel for Y and UV
5321 intpel_mv = !mv_has_subpel(&mbmi->mv[0].as_mv);
5322 if (is_comp_pred)
5323 intpel_mv &= !mv_has_subpel(&mbmi->mv[1].as_mv);
5324
5325 // Search for best switchable filter by checking the variance of
5326 // pred error irrespective of whether the filter will be used
5327 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
5328 filter_cache[i] = INT64_MAX;
5329
5330 if (cm->interp_filter != BILINEAR) {
5331 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
5332 best_filter = EIGHTTAP;
Debargha Mukherjee85514c42015-10-30 09:19:36 -07005333#if CONFIG_EXT_INTERP
5334 } else if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE) {
5335 best_filter = EIGHTTAP;
5336#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07005337 } else if (best_filter == SWITCHABLE) {
5338 int newbest;
5339 int tmp_rate_sum = 0;
5340 int64_t tmp_dist_sum = 0;
5341
5342 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
5343 int j;
5344 int64_t rs_rd;
5345 int tmp_skip_sb = 0;
5346 int64_t tmp_skip_sse = INT64_MAX;
5347
5348 mbmi->interp_filter = i;
5349 rs = vp10_get_switchable_rate(cpi, xd);
5350 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
5351
Debargha Mukherjee85514c42015-10-30 09:19:36 -07005352 if (i > 0 && intpel_mv && IsInterpolatingFilter(i)) {
Jingning Han3ee6db62015-08-05 19:00:31 -07005353 rd = RDCOST(x->rdmult, x->rddiv, tmp_rate_sum, tmp_dist_sum);
5354 filter_cache[i] = rd;
5355 filter_cache[SWITCHABLE_FILTERS] =
James Zern5e16d392015-08-17 18:19:22 -07005356 VPXMIN(filter_cache[SWITCHABLE_FILTERS], rd + rs_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07005357 if (cm->interp_filter == SWITCHABLE)
5358 rd += rs_rd;
James Zern5e16d392015-08-17 18:19:22 -07005359 *mask_filter = VPXMAX(*mask_filter, rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07005360 } else {
5361 int rate_sum = 0;
5362 int64_t dist_sum = 0;
5363 if (i > 0 && cpi->sf.adaptive_interp_filter_search &&
5364 (cpi->sf.interp_filter_search_mask & (1 << i))) {
5365 rate_sum = INT_MAX;
5366 dist_sum = INT64_MAX;
5367 continue;
5368 }
5369
5370 if ((cm->interp_filter == SWITCHABLE &&
5371 (!i || best_needs_copy)) ||
5372 (cm->interp_filter != SWITCHABLE &&
5373 (cm->interp_filter == mbmi->interp_filter ||
Debargha Mukherjee85514c42015-10-30 09:19:36 -07005374 (i == 0 && intpel_mv && IsInterpolatingFilter(i))))) {
Jingning Han3ee6db62015-08-05 19:00:31 -07005375 restore_dst_buf(xd, orig_dst, orig_dst_stride);
5376 } else {
5377 for (j = 0; j < MAX_MB_PLANE; j++) {
5378 xd->plane[j].dst.buf = tmp_buf + j * 64 * 64;
5379 xd->plane[j].dst.stride = 64;
5380 }
5381 }
5382 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
5383 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
5384 &tmp_skip_sb, &tmp_skip_sse);
5385
5386 rd = RDCOST(x->rdmult, x->rddiv, rate_sum, dist_sum);
5387 filter_cache[i] = rd;
5388 filter_cache[SWITCHABLE_FILTERS] =
James Zern5e16d392015-08-17 18:19:22 -07005389 VPXMIN(filter_cache[SWITCHABLE_FILTERS], rd + rs_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07005390 if (cm->interp_filter == SWITCHABLE)
5391 rd += rs_rd;
James Zern5e16d392015-08-17 18:19:22 -07005392 *mask_filter = VPXMAX(*mask_filter, rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07005393
Debargha Mukherjee85514c42015-10-30 09:19:36 -07005394 if (i == 0 && intpel_mv && IsInterpolatingFilter(i)) {
Jingning Han3ee6db62015-08-05 19:00:31 -07005395 tmp_rate_sum = rate_sum;
5396 tmp_dist_sum = dist_sum;
5397 }
5398 }
5399
5400 if (i == 0 && cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
5401 if (rd / 2 > ref_best_rd) {
5402 restore_dst_buf(xd, orig_dst, orig_dst_stride);
5403 return INT64_MAX;
5404 }
5405 }
5406 newbest = i == 0 || rd < best_rd;
5407
5408 if (newbest) {
5409 best_rd = rd;
5410 best_filter = mbmi->interp_filter;
Debargha Mukherjee85514c42015-10-30 09:19:36 -07005411 if (cm->interp_filter == SWITCHABLE && i &&
5412 !(intpel_mv && IsInterpolatingFilter(i)))
Jingning Han3ee6db62015-08-05 19:00:31 -07005413 best_needs_copy = !best_needs_copy;
5414 }
5415
5416 if ((cm->interp_filter == SWITCHABLE && newbest) ||
5417 (cm->interp_filter != SWITCHABLE &&
5418 cm->interp_filter == mbmi->interp_filter)) {
5419 pred_exists = 1;
5420 tmp_rd = best_rd;
5421
5422 skip_txfm_sb = tmp_skip_sb;
5423 skip_sse_sb = tmp_skip_sse;
5424 memcpy(skip_txfm, x->skip_txfm, sizeof(skip_txfm));
5425 memcpy(bsse, x->bsse, sizeof(bsse));
5426 }
5427 }
5428 restore_dst_buf(xd, orig_dst, orig_dst_stride);
5429 }
5430 }
Debargha Mukherjee85514c42015-10-30 09:19:36 -07005431
Jingning Han3ee6db62015-08-05 19:00:31 -07005432 // Set the appropriate filter
5433 mbmi->interp_filter = cm->interp_filter != SWITCHABLE ?
5434 cm->interp_filter : best_filter;
5435 rs = cm->interp_filter == SWITCHABLE ? vp10_get_switchable_rate(cpi, xd) : 0;
5436
5437 if (pred_exists) {
5438 if (best_needs_copy) {
5439 // again temporarily set the buffers to local memory to prevent a memcpy
5440 for (i = 0; i < MAX_MB_PLANE; i++) {
5441 xd->plane[i].dst.buf = tmp_buf + i * 64 * 64;
5442 xd->plane[i].dst.stride = 64;
5443 }
5444 }
5445 rd = tmp_rd + RDCOST(x->rdmult, x->rddiv, rs, 0);
5446 } else {
5447 int tmp_rate;
5448 int64_t tmp_dist;
5449 // Handles the special case when a filter that is not in the
5450 // switchable list (ex. bilinear) is indicated at the frame level, or
5451 // skip condition holds.
5452 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
5453 model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist,
5454 &skip_txfm_sb, &skip_sse_sb);
5455 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
5456 memcpy(skip_txfm, x->skip_txfm, sizeof(skip_txfm));
5457 memcpy(bsse, x->bsse, sizeof(bsse));
5458 }
5459
5460 if (!is_comp_pred)
5461 single_filter[this_mode][refs[0]] = mbmi->interp_filter;
5462
5463 if (cpi->sf.adaptive_mode_search)
5464 if (is_comp_pred)
Yue Chen968bbc72016-01-19 16:45:45 -08005465#if CONFIG_EXT_INTER
5466 switch (this_mode) {
5467 case NEAREST_NEARESTMV:
5468 if (single_skippable[NEARESTMV][refs[0]] &&
5469 single_skippable[NEARESTMV][refs[1]])
5470 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5471 break;
5472 case ZERO_ZEROMV:
5473 if (single_skippable[ZEROMV][refs[0]] &&
5474 single_skippable[ZEROMV][refs[1]])
5475 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5476 break;
5477 case NEW_NEWMV:
5478 if (single_skippable[NEWMV][refs[0]] &&
5479 single_skippable[NEWMV][refs[1]])
5480 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5481 break;
5482 case NEAREST_NEWMV:
5483 if (single_skippable[NEARESTMV][refs[0]] &&
5484 single_skippable[NEWMV][refs[1]])
5485 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5486 break;
5487 case NEAR_NEWMV:
5488 if (single_skippable[NEARMV][refs[0]] &&
5489 single_skippable[NEWMV][refs[1]])
5490 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5491 break;
5492 case NEW_NEARESTMV:
5493 if (single_skippable[NEWMV][refs[0]] &&
5494 single_skippable[NEARESTMV][refs[1]])
5495 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5496 break;
5497 case NEW_NEARMV:
5498 if (single_skippable[NEWMV][refs[0]] &&
5499 single_skippable[NEARMV][refs[1]])
5500 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5501 break;
5502 case NEAREST_NEARMV:
5503 if (single_skippable[NEARESTMV][refs[0]] &&
5504 single_skippable[NEARMV][refs[1]])
5505 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5506 break;
5507 case NEAR_NEARESTMV:
5508 if (single_skippable[NEARMV][refs[0]] &&
5509 single_skippable[NEARESTMV][refs[1]])
5510 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5511 break;
5512 default:
5513 if (single_skippable[this_mode][refs[0]] &&
5514 single_skippable[this_mode][refs[1]])
5515 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5516 break;
5517 }
5518#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005519 if (single_skippable[this_mode][refs[0]] &&
5520 single_skippable[this_mode][refs[1]])
5521 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
Yue Chen968bbc72016-01-19 16:45:45 -08005522#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005523
5524 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
5525 // if current pred_error modeled rd is substantially more than the best
5526 // so far, do not bother doing full rd
5527 if (rd / 2 > ref_best_rd) {
5528 restore_dst_buf(xd, orig_dst, orig_dst_stride);
5529 return INT64_MAX;
5530 }
5531 }
5532
5533 if (cm->interp_filter == SWITCHABLE)
5534 *rate2 += rs;
5535
5536 memcpy(x->skip_txfm, skip_txfm, sizeof(skip_txfm));
5537 memcpy(x->bsse, bsse, sizeof(bsse));
5538
5539 if (!skip_txfm_sb) {
5540 int skippable_y, skippable_uv;
5541 int64_t sseuv = INT64_MAX;
5542 int64_t rdcosty = INT64_MAX;
5543
5544 // Y cost and distortion
5545 vp10_subtract_plane(x, bsize, 0);
Jingning Han2cdc1272015-10-09 09:57:42 -07005546#if CONFIG_VAR_TX
Jingning Hanf0dee772015-10-26 12:32:30 -07005547 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
Jingning Han4b594d32015-11-02 12:05:47 -08005548 select_tx_type_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
5549 bsize, ref_best_rd);
Jingning Han2cdc1272015-10-09 09:57:42 -07005550 } else {
Jingning Han0f34e352015-11-15 20:52:51 -08005551 int idx, idy;
Jingning Han2cdc1272015-10-09 09:57:42 -07005552 super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
5553 bsize, ref_best_rd);
Jingning Han0f34e352015-11-15 20:52:51 -08005554 for (idy = 0; idy < xd->n8_h; ++idy)
5555 for (idx = 0; idx < xd->n8_w; ++idx)
5556 mbmi->inter_tx_size[idy * 8 + idx] = mbmi->tx_size;
Jingning Han2cdc1272015-10-09 09:57:42 -07005557 }
5558#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005559 super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
5560 bsize, ref_best_rd);
Debargha Mukherjee9a8a6a12016-01-22 14:52:38 -08005561#endif // CONFIG_VAR_TX
Jingning Han704985e2015-10-08 12:05:03 -07005562
Jingning Han3ee6db62015-08-05 19:00:31 -07005563 if (*rate_y == INT_MAX) {
5564 *rate2 = INT_MAX;
5565 *distortion = INT64_MAX;
5566 restore_dst_buf(xd, orig_dst, orig_dst_stride);
5567 return INT64_MAX;
5568 }
5569
5570 *rate2 += *rate_y;
5571 *distortion += distortion_y;
5572
5573 rdcosty = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
James Zern5e16d392015-08-17 18:19:22 -07005574 rdcosty = VPXMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, *psse));
Jingning Han3ee6db62015-08-05 19:00:31 -07005575
Jingning Hana8dad552015-10-08 16:46:10 -07005576#if CONFIG_VAR_TX
5577 if (!inter_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv,
5578 &sseuv, bsize, ref_best_rd - rdcosty)) {
5579#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005580 if (!super_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv,
5581 &sseuv, bsize, ref_best_rd - rdcosty)) {
Debargha Mukherjee9a8a6a12016-01-22 14:52:38 -08005582#endif // CONFIG_VAR_TX
Jingning Han3ee6db62015-08-05 19:00:31 -07005583 *rate2 = INT_MAX;
5584 *distortion = INT64_MAX;
5585 restore_dst_buf(xd, orig_dst, orig_dst_stride);
5586 return INT64_MAX;
5587 }
5588
5589 *psse += sseuv;
5590 *rate2 += *rate_uv;
5591 *distortion += distortion_uv;
5592 *skippable = skippable_y && skippable_uv;
5593 } else {
5594 x->skip = 1;
5595 *disable_skip = 1;
5596
5597 // The cost of skip bit needs to be added.
5598 *rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
5599
5600 *distortion = skip_sse_sb;
5601 }
5602
5603 if (!is_comp_pred)
5604 single_skippable[this_mode][refs[0]] = *skippable;
5605
5606 restore_dst_buf(xd, orig_dst, orig_dst_stride);
5607 return 0; // The rate-distortion cost will be re-calculated by caller.
5608}
5609
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005610void vp10_rd_pick_intra_mode_sb(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07005611 RD_COST *rd_cost, BLOCK_SIZE bsize,
5612 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07005613 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07005614 MACROBLOCKD *const xd = &x->e_mbd;
5615 struct macroblockd_plane *const pd = xd->plane;
5616 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
5617 int y_skip = 0, uv_skip = 0;
5618 int64_t dist_y = 0, dist_uv = 0;
5619 TX_SIZE max_uv_tx_size;
Jingning Han3ee6db62015-08-05 19:00:31 -07005620 ctx->skip = 0;
5621 xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
5622 xd->mi[0]->mbmi.ref_frame[1] = NONE;
5623
5624 if (bsize >= BLOCK_8X8) {
5625 if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly,
5626 &dist_y, &y_skip, bsize,
5627 best_rd) >= best_rd) {
5628 rd_cost->rate = INT_MAX;
5629 return;
5630 }
5631 } else {
5632 y_skip = 0;
5633 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
5634 &dist_y, best_rd) >= best_rd) {
5635 rd_cost->rate = INT_MAX;
5636 return;
5637 }
5638 }
5639 max_uv_tx_size = get_uv_tx_size_impl(xd->mi[0]->mbmi.tx_size, bsize,
5640 pd[1].subsampling_x,
5641 pd[1].subsampling_y);
5642 rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv, &rate_uv_tokenonly,
James Zern5e16d392015-08-17 18:19:22 -07005643 &dist_uv, &uv_skip, VPXMAX(BLOCK_8X8, bsize),
Jingning Han3ee6db62015-08-05 19:00:31 -07005644 max_uv_tx_size);
5645
5646 if (y_skip && uv_skip) {
5647 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
5648 vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
5649 rd_cost->dist = dist_y + dist_uv;
5650 } else {
5651 rd_cost->rate = rate_y + rate_uv +
5652 vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
5653 rd_cost->dist = dist_y + dist_uv;
5654 }
5655
5656 ctx->mic = *xd->mi[0];
5657 ctx->mbmi_ext = *x->mbmi_ext;
5658 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
5659}
5660
5661// This function is designed to apply a bias or adjustment to an rd value based
5662// on the relative variance of the source and reconstruction.
5663#define LOW_VAR_THRESH 16
5664#define VLOW_ADJ_MAX 25
5665#define VHIGH_ADJ_MAX 8
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005666static void rd_variance_adjustment(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07005667 MACROBLOCK *x,
5668 BLOCK_SIZE bsize,
5669 int64_t *this_rd,
5670 MV_REFERENCE_FRAME ref_frame,
5671 unsigned int source_variance) {
5672 MACROBLOCKD *const xd = &x->e_mbd;
5673 unsigned int recon_variance;
5674 unsigned int absvar_diff = 0;
5675 int64_t var_error = 0;
5676 int64_t var_factor = 0;
5677
5678 if (*this_rd == INT64_MAX)
5679 return;
5680
5681#if CONFIG_VP9_HIGHBITDEPTH
5682 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5683 recon_variance =
5684 vp10_high_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize, xd->bd);
5685 } else {
5686 recon_variance =
5687 vp10_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
5688 }
5689#else
5690 recon_variance =
5691 vp10_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
5692#endif // CONFIG_VP9_HIGHBITDEPTH
5693
5694 if ((source_variance + recon_variance) > LOW_VAR_THRESH) {
5695 absvar_diff = (source_variance > recon_variance)
5696 ? (source_variance - recon_variance)
5697 : (recon_variance - source_variance);
5698
Alex Converseb1fcd172015-11-19 14:53:51 -08005699 var_error = ((int64_t)200 * source_variance * recon_variance) /
5700 (((int64_t)source_variance * source_variance) +
5701 ((int64_t)recon_variance * recon_variance));
Jingning Han3ee6db62015-08-05 19:00:31 -07005702 var_error = 100 - var_error;
5703 }
5704
5705 // Source variance above a threshold and ref frame is intra.
5706 // This case is targeted mainly at discouraging intra modes that give rise
5707 // to a predictor with a low spatial complexity compared to the source.
5708 if ((source_variance > LOW_VAR_THRESH) && (ref_frame == INTRA_FRAME) &&
5709 (source_variance > recon_variance)) {
James Zern5e16d392015-08-17 18:19:22 -07005710 var_factor = VPXMIN(absvar_diff, VPXMIN(VLOW_ADJ_MAX, var_error));
Jingning Han3ee6db62015-08-05 19:00:31 -07005711 // A second possible case of interest is where the source variance
5712 // is very low and we wish to discourage false texture or motion trails.
5713 } else if ((source_variance < (LOW_VAR_THRESH >> 1)) &&
5714 (recon_variance > source_variance)) {
James Zern5e16d392015-08-17 18:19:22 -07005715 var_factor = VPXMIN(absvar_diff, VPXMIN(VHIGH_ADJ_MAX, var_error));
Jingning Han3ee6db62015-08-05 19:00:31 -07005716 }
5717 *this_rd += (*this_rd * var_factor) / 100;
5718}
5719
5720
5721// Do we have an internal image edge (e.g. formatting bars).
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005722int vp10_internal_image_edge(VP10_COMP *cpi) {
Jingning Han3ee6db62015-08-05 19:00:31 -07005723 return (cpi->oxcf.pass == 2) &&
5724 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
5725 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
5726}
5727
5728// Checks to see if a super block is on a horizontal image edge.
5729// In most cases this is the "real" edge unless there are formatting
5730// bars embedded in the stream.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005731int vp10_active_h_edge(VP10_COMP *cpi, int mi_row, int mi_step) {
Jingning Han3ee6db62015-08-05 19:00:31 -07005732 int top_edge = 0;
5733 int bottom_edge = cpi->common.mi_rows;
5734 int is_active_h_edge = 0;
5735
5736 // For two pass account for any formatting bars detected.
5737 if (cpi->oxcf.pass == 2) {
5738 TWO_PASS *twopass = &cpi->twopass;
5739
5740 // The inactive region is specified in MBs not mi units.
5741 // The image edge is in the following MB row.
5742 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
5743
5744 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
James Zern5e16d392015-08-17 18:19:22 -07005745 bottom_edge = VPXMAX(top_edge, bottom_edge);
Jingning Han3ee6db62015-08-05 19:00:31 -07005746 }
5747
5748 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
5749 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
5750 is_active_h_edge = 1;
5751 }
5752 return is_active_h_edge;
5753}
5754
5755// Checks to see if a super block is on a vertical image edge.
5756// In most cases this is the "real" edge unless there are formatting
5757// bars embedded in the stream.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005758int vp10_active_v_edge(VP10_COMP *cpi, int mi_col, int mi_step) {
Jingning Han3ee6db62015-08-05 19:00:31 -07005759 int left_edge = 0;
5760 int right_edge = cpi->common.mi_cols;
5761 int is_active_v_edge = 0;
5762
5763 // For two pass account for any formatting bars detected.
5764 if (cpi->oxcf.pass == 2) {
5765 TWO_PASS *twopass = &cpi->twopass;
5766
5767 // The inactive region is specified in MBs not mi units.
5768 // The image edge is in the following MB row.
5769 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
5770
5771 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
James Zern5e16d392015-08-17 18:19:22 -07005772 right_edge = VPXMAX(left_edge, right_edge);
Jingning Han3ee6db62015-08-05 19:00:31 -07005773 }
5774
5775 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
5776 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
5777 is_active_v_edge = 1;
5778 }
5779 return is_active_v_edge;
5780}
5781
5782// Checks to see if a super block is at the edge of the active image.
5783// In most cases this is the "real" edge unless there are formatting
5784// bars embedded in the stream.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005785int vp10_active_edge_sb(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07005786 int mi_row, int mi_col) {
5787 return vp10_active_h_edge(cpi, mi_row, MI_BLOCK_SIZE) ||
5788 vp10_active_v_edge(cpi, mi_col, MI_BLOCK_SIZE);
5789}
5790
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005791void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
Jingning Han4fa8e732015-09-10 12:24:06 -07005792 TileDataEnc *tile_data,
5793 MACROBLOCK *x,
5794 int mi_row, int mi_col,
Debargha Mukherjee3787b172015-11-19 16:51:16 -08005795 RD_COST *rd_cost,
5796#if CONFIG_SUPERTX
5797 int *returnrate_nocoef,
5798#endif // CONFIG_SUPERTX
5799 BLOCK_SIZE bsize,
Jingning Han4fa8e732015-09-10 12:24:06 -07005800 PICK_MODE_CONTEXT *ctx,
5801 int64_t best_rd_so_far) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07005802 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07005803 RD_OPT *const rd_opt = &cpi->rd;
5804 SPEED_FEATURES *const sf = &cpi->sf;
5805 MACROBLOCKD *const xd = &x->e_mbd;
5806 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
5807 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
5808 const struct segmentation *const seg = &cm->seg;
5809 PREDICTION_MODE this_mode;
5810 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
5811 unsigned char segment_id = mbmi->segment_id;
5812 int comp_pred, i, k;
5813 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
Zoe Liu3ec16012015-11-12 02:12:17 -08005814 struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE];
Yue Chen1ac85872016-01-07 15:13:52 -08005815#if CONFIG_EXT_INTER
5816 int_mv single_newmvs[2][MAX_REF_FRAMES] = { { { 0 } }, { { 0 } } };
5817#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005818 int_mv single_newmv[MAX_REF_FRAMES] = { { 0 } };
Yue Chen1ac85872016-01-07 15:13:52 -08005819#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005820 INTERP_FILTER single_inter_filter[MB_MODE_COUNT][MAX_REF_FRAMES];
5821 int single_skippable[MB_MODE_COUNT][MAX_REF_FRAMES];
Zoe Liu3ec16012015-11-12 02:12:17 -08005822 static const int flag_list[REFS_PER_FRAME + 1] = {
5823 0,
5824 VP9_LAST_FLAG,
5825#if CONFIG_EXT_REFS
5826 VP9_LAST2_FLAG,
5827 VP9_LAST3_FLAG,
5828 VP9_LAST4_FLAG,
5829#endif // CONFIG_EXT_REFS
5830 VP9_GOLD_FLAG,
5831 VP9_ALT_FLAG
5832 };
Jingning Han3ee6db62015-08-05 19:00:31 -07005833 int64_t best_rd = best_rd_so_far;
5834 int64_t best_pred_diff[REFERENCE_MODES];
5835 int64_t best_pred_rd[REFERENCE_MODES];
5836 int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
5837 int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
5838 MB_MODE_INFO best_mbmode;
Jingning Han67cf8902016-01-15 09:05:51 -08005839#if CONFIG_REF_MV
Jingning Han28e03932016-01-20 17:40:47 -08005840 uint8_t best_ref_mv_idx[MODE_CTX_REF_FRAMES] = { 0 };
Jingning Han67cf8902016-01-15 09:05:51 -08005841#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07005842 int best_mode_skippable = 0;
5843 int midx, best_mode_index = -1;
5844 unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
5845 vpx_prob comp_mode_p;
5846 int64_t best_intra_rd = INT64_MAX;
5847 unsigned int best_pred_sse = UINT_MAX;
5848 PREDICTION_MODE best_intra_mode = DC_PRED;
5849 int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES];
5850 int64_t dist_uv[TX_SIZES];
5851 int skip_uv[TX_SIZES];
5852 PREDICTION_MODE mode_uv[TX_SIZES];
hui sube3559b2015-10-07 09:29:02 -07005853#if CONFIG_EXT_INTRA
5854 EXT_INTRA_MODE_INFO ext_intra_mode_info_uv[TX_SIZES];
hui su4aa50c12015-11-10 12:09:59 -08005855 int8_t uv_angle_delta[TX_SIZES];
hui sud7c8bc72015-11-12 19:18:32 -08005856 int is_directional_mode, angle_stats_ready = 0;
hui su4aa50c12015-11-10 12:09:59 -08005857 int rate_overhead, rate_dummy;
hui sud7c8bc72015-11-12 19:18:32 -08005858 uint8_t directional_mode_skip_mask[INTRA_MODES];
hui sube3559b2015-10-07 09:29:02 -07005859#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07005860 const int intra_cost_penalty = vp10_get_intra_cost_penalty(
5861 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
hui su1559afd2015-12-30 10:27:19 -08005862 const int * const intra_mode_cost =
5863 cpi->mbmode_cost[size_group_lookup[bsize]];
Jingning Han3ee6db62015-08-05 19:00:31 -07005864 int best_skip2 = 0;
5865 uint8_t ref_frame_skip_mask[2] = { 0 };
Yue Chen1ac85872016-01-07 15:13:52 -08005866#if CONFIG_EXT_INTER
5867 uint32_t mode_skip_mask[MAX_REF_FRAMES] = { 0 };
5868#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005869 uint16_t mode_skip_mask[MAX_REF_FRAMES] = { 0 };
Yue Chen1ac85872016-01-07 15:13:52 -08005870#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005871 int mode_skip_start = sf->mode_skip_start + 1;
5872 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
5873 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
5874 int64_t mode_threshold[MAX_MODES];
5875 int *mode_map = tile_data->mode_map[bsize];
5876 const int mode_search_skip_flags = sf->mode_search_skip_flags;
5877 int64_t mask_filter = 0;
5878 int64_t filter_cache[SWITCHABLE_FILTER_CONTEXTS];
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08005879 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
5880 const vpx_prob *tx_probs = get_tx_probs2(max_tx_size, xd, &cm->fc->tx_probs);
Jingning Han3ee6db62015-08-05 19:00:31 -07005881
5882 vp10_zero(best_mbmode);
5883
hui sud7c8bc72015-11-12 19:18:32 -08005884#if CONFIG_EXT_INTRA
5885 memset(directional_mode_skip_mask, 0,
5886 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
5887#endif // CONFIG_EXT_INTRA
5888
Jingning Han3ee6db62015-08-05 19:00:31 -07005889 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
5890 filter_cache[i] = INT64_MAX;
5891
5892 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
5893 &comp_mode_p);
5894
5895 for (i = 0; i < REFERENCE_MODES; ++i)
5896 best_pred_rd[i] = INT64_MAX;
5897 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
5898 best_filter_rd[i] = INT64_MAX;
5899 for (i = 0; i < TX_SIZES; i++)
5900 rate_uv_intra[i] = INT_MAX;
5901 for (i = 0; i < MAX_REF_FRAMES; ++i)
5902 x->pred_sse[i] = INT_MAX;
5903 for (i = 0; i < MB_MODE_COUNT; ++i) {
5904 for (k = 0; k < MAX_REF_FRAMES; ++k) {
5905 single_inter_filter[i][k] = SWITCHABLE;
5906 single_skippable[i][k] = 0;
5907 }
5908 }
5909
5910 rd_cost->rate = INT_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08005911#if CONFIG_SUPERTX
5912 *returnrate_nocoef = INT_MAX;
5913#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07005914
5915 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
5916 x->pred_mv_sad[ref_frame] = INT_MAX;
Jingning Han387a10e2015-12-09 09:07:39 -08005917 x->mbmi_ext->mode_context[ref_frame] = 0;
Yue Chen968bbc72016-01-19 16:45:45 -08005918#if CONFIG_REF_MV && CONFIG_EXT_INTER
5919 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
5920#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005921 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
5922 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
5923 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
5924 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
5925 }
5926 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
5927 frame_mv[ZEROMV][ref_frame].as_int = 0;
Yue Chen1ac85872016-01-07 15:13:52 -08005928#if CONFIG_EXT_INTER
5929 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
Yue Chen968bbc72016-01-19 16:45:45 -08005930 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
5931 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
Yue Chen1ac85872016-01-07 15:13:52 -08005932#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005933 }
5934
Jingning Han33cc1bd2016-01-12 15:06:59 -08005935#if CONFIG_REF_MV
5936 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
5937 MODE_INFO *const mi = xd->mi[0];
5938 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
5939 x->mbmi_ext->mode_context[ref_frame] = 0;
5940 vp10_find_mv_refs(cm, xd, mi, ref_frame,
5941#if CONFIG_REF_MV
5942 &mbmi_ext->ref_mv_count[ref_frame],
5943 mbmi_ext->ref_mv_stack[ref_frame],
Yue Chen968bbc72016-01-19 16:45:45 -08005944#if CONFIG_EXT_INTER
5945 mbmi_ext->compound_mode_context,
5946#endif // CONFIG_EXT_INTER
Jingning Han33cc1bd2016-01-12 15:06:59 -08005947#endif
5948 candidates, mi_row, mi_col,
5949 NULL, NULL, mbmi_ext->mode_context);
5950 }
5951#endif
5952
Jingning Han3ee6db62015-08-05 19:00:31 -07005953 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
5954 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
5955 // Skip checking missing references in both single and compound reference
5956 // modes. Note that a mode will be skipped iff both reference frames
5957 // are masked out.
5958 ref_frame_skip_mask[0] |= (1 << ref_frame);
5959 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
Jingning Han1eb760e2015-09-10 12:56:41 -07005960 } else {
Jingning Han3ee6db62015-08-05 19:00:31 -07005961 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
5962 // Skip fixed mv modes for poor references
5963 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
5964 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
5965 break;
5966 }
5967 }
5968 }
5969 // If the segment reference frame feature is enabled....
5970 // then do nothing if the current ref frame is not allowed..
5971 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
5972 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
5973 ref_frame_skip_mask[0] |= (1 << ref_frame);
5974 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
5975 }
5976 }
5977
5978 // Disable this drop out case if the ref frame
5979 // segment level feature is enabled for this segment. This is to
5980 // prevent the possibility that we end up unable to pick any mode.
5981 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
5982 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
5983 // unless ARNR filtering is enabled in which case we want
5984 // an unfiltered alternative. We allow near/nearest as well
5985 // because they may result in zero-zero MVs but be cheaper.
5986 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Zoe Liu3ec16012015-11-12 02:12:17 -08005987 ref_frame_skip_mask[0] =
5988 (1 << LAST_FRAME) |
5989#if CONFIG_EXT_REFS
5990 (1 << LAST2_FRAME) |
5991 (1 << LAST3_FRAME) |
5992 (1 << LAST4_FRAME) |
5993#endif // CONFIG_EXT_REFS
5994 (1 << GOLDEN_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07005995 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
5996 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
5997 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != 0)
5998 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
5999 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != 0)
6000 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
Yue Chen968bbc72016-01-19 16:45:45 -08006001#if CONFIG_EXT_INTER
6002 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != 0)
6003 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
6004 if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != 0)
6005 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
6006 if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != 0)
6007 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
6008#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006009 }
6010 }
6011
6012 if (cpi->rc.is_src_frame_alt_ref) {
6013 if (sf->alt_ref_search_fp) {
6014 mode_skip_mask[ALTREF_FRAME] = 0;
6015 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
6016 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
6017 }
6018 }
6019
6020 if (sf->alt_ref_search_fp)
6021 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
6022 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
6023 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
6024
6025 if (sf->adaptive_mode_search) {
6026 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
6027 cpi->rc.frames_since_golden >= 3)
6028 if (x->pred_mv_sad[GOLDEN_FRAME] > (x->pred_mv_sad[LAST_FRAME] << 1))
6029 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
6030 }
6031
6032 if (bsize > sf->max_intra_bsize) {
6033 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
6034 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
6035 }
6036
6037 mode_skip_mask[INTRA_FRAME] |=
6038 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
6039
6040 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i)
6041 mode_threshold[i] = 0;
6042 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
6043 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
6044
6045 midx = sf->schedule_mode_search ? mode_skip_start : 0;
6046 while (midx > 4) {
6047 uint8_t end_pos = 0;
6048 for (i = 5; i < midx; ++i) {
6049 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
6050 uint8_t tmp = mode_map[i];
6051 mode_map[i] = mode_map[i - 1];
6052 mode_map[i - 1] = tmp;
6053 end_pos = i;
6054 }
6055 }
6056 midx = end_pos;
6057 }
6058
hui suc93e5cc2015-12-07 18:18:57 -08006059 mbmi->palette_mode_info.palette_size[0] = 0;
6060 mbmi->palette_mode_info.palette_size[1] = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07006061 for (midx = 0; midx < MAX_MODES; ++midx) {
6062 int mode_index = mode_map[midx];
6063 int mode_excluded = 0;
6064 int64_t this_rd = INT64_MAX;
6065 int disable_skip = 0;
6066 int compmode_cost = 0;
6067 int rate2 = 0, rate_y = 0, rate_uv = 0;
6068 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
6069 int skippable = 0;
6070 int this_skip2 = 0;
6071 int64_t total_sse = INT64_MAX;
6072 int early_term = 0;
Jingning Han28e03932016-01-20 17:40:47 -08006073#if CONFIG_REF_MV
6074 uint8_t ref_frame_type;
6075#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07006076
6077 this_mode = vp10_mode_order[mode_index].mode;
6078 ref_frame = vp10_mode_order[mode_index].ref_frame[0];
6079 second_ref_frame = vp10_mode_order[mode_index].ref_frame[1];
6080
Yue Chen968bbc72016-01-19 16:45:45 -08006081#if CONFIG_EXT_INTER
6082 if (this_mode == NEAREST_NEARESTMV) {
6083 frame_mv[NEAREST_NEARESTMV][ref_frame].as_int =
6084 frame_mv[NEARESTMV][ref_frame].as_int;
6085 frame_mv[NEAREST_NEARESTMV][second_ref_frame].as_int =
6086 frame_mv[NEARESTMV][second_ref_frame].as_int;
6087 } else if (this_mode == NEAREST_NEARMV) {
6088 frame_mv[NEAREST_NEARMV][ref_frame].as_int =
6089 frame_mv[NEARESTMV][ref_frame].as_int;
6090 frame_mv[NEAREST_NEARMV][second_ref_frame].as_int =
6091 frame_mv[NEARMV][second_ref_frame].as_int;
6092 } else if (this_mode == NEAR_NEARESTMV) {
6093 frame_mv[NEAR_NEARESTMV][ref_frame].as_int =
6094 frame_mv[NEARMV][ref_frame].as_int;
6095 frame_mv[NEAR_NEARESTMV][second_ref_frame].as_int =
6096 frame_mv[NEARESTMV][second_ref_frame].as_int;
6097 } else if (this_mode == NEAREST_NEWMV) {
6098 frame_mv[NEAREST_NEWMV][ref_frame].as_int =
6099 frame_mv[NEARESTMV][ref_frame].as_int;
6100 frame_mv[NEAREST_NEWMV][second_ref_frame].as_int =
6101 frame_mv[NEWMV][second_ref_frame].as_int;
6102 } else if (this_mode == NEW_NEARESTMV) {
6103 frame_mv[NEW_NEARESTMV][ref_frame].as_int =
6104 frame_mv[NEWMV][ref_frame].as_int;
6105 frame_mv[NEW_NEARESTMV][second_ref_frame].as_int =
6106 frame_mv[NEARESTMV][second_ref_frame].as_int;
6107 } else if (this_mode == NEAR_NEWMV) {
6108 frame_mv[NEAR_NEWMV][ref_frame].as_int =
6109 frame_mv[NEARMV][ref_frame].as_int;
6110 frame_mv[NEAR_NEWMV][second_ref_frame].as_int =
6111 frame_mv[NEWMV][second_ref_frame].as_int;
6112 } else if (this_mode == NEW_NEARMV) {
6113 frame_mv[NEW_NEARMV][ref_frame].as_int =
6114 frame_mv[NEWMV][ref_frame].as_int;
6115 frame_mv[NEW_NEARMV][second_ref_frame].as_int =
6116 frame_mv[NEARMV][second_ref_frame].as_int;
6117 } else if (this_mode == NEW_NEWMV) {
6118 frame_mv[NEW_NEWMV][ref_frame].as_int =
6119 frame_mv[NEWMV][ref_frame].as_int;
6120 frame_mv[NEW_NEWMV][second_ref_frame].as_int =
6121 frame_mv[NEWMV][second_ref_frame].as_int;
6122 }
6123#endif // CONFIG_EXT_INTER
6124
Jingning Han3ee6db62015-08-05 19:00:31 -07006125 // Look at the reference frame of the best mode so far and set the
6126 // skip mask to look at a subset of the remaining modes.
6127 if (midx == mode_skip_start && best_mode_index >= 0) {
6128 switch (best_mbmode.ref_frame[0]) {
6129 case INTRA_FRAME:
6130 break;
6131 case LAST_FRAME:
6132 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
6133 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
6134 break;
Zoe Liu3ec16012015-11-12 02:12:17 -08006135#if CONFIG_EXT_REFS
6136 case LAST2_FRAME:
6137 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
6138 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
6139 break;
6140 case LAST3_FRAME:
6141 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
6142 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
6143 break;
6144 case LAST4_FRAME:
6145 ref_frame_skip_mask[0] |= LAST4_FRAME_MODE_MASK;
6146 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
6147 break;
6148#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07006149 case GOLDEN_FRAME:
6150 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
6151 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
6152 break;
6153 case ALTREF_FRAME:
6154 ref_frame_skip_mask[0] |= ALT_REF_MODE_MASK;
6155 break;
6156 case NONE:
6157 case MAX_REF_FRAMES:
6158 assert(0 && "Invalid Reference frame");
6159 break;
6160 }
6161 }
6162
6163 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
James Zern5e16d392015-08-17 18:19:22 -07006164 (ref_frame_skip_mask[1] & (1 << VPXMAX(0, second_ref_frame))))
Jingning Han3ee6db62015-08-05 19:00:31 -07006165 continue;
6166
6167 if (mode_skip_mask[ref_frame] & (1 << this_mode))
6168 continue;
6169
6170 // Test best rd so far against threshold for trying this mode.
6171 if (best_mode_skippable && sf->schedule_mode_search)
6172 mode_threshold[mode_index] <<= 1;
6173
6174 if (best_rd < mode_threshold[mode_index])
6175 continue;
6176
Jingning Han3ee6db62015-08-05 19:00:31 -07006177 comp_pred = second_ref_frame > INTRA_FRAME;
6178 if (comp_pred) {
6179 if (!cpi->allow_comp_inter_inter)
6180 continue;
6181
6182 // Skip compound inter modes if ARF is not available.
6183 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
6184 continue;
6185
6186 // Do not allow compound prediction if the segment level reference frame
6187 // feature is in use as in this case there can only be one reference.
6188 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
6189 continue;
6190
6191 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
6192 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
6193 continue;
6194
6195 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
6196 } else {
6197 if (ref_frame != INTRA_FRAME)
6198 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
6199 }
6200
6201 if (ref_frame == INTRA_FRAME) {
6202 if (sf->adaptive_mode_search)
6203 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
6204 continue;
6205
6206 if (this_mode != DC_PRED) {
6207 // Disable intra modes other than DC_PRED for blocks with low variance
6208 // Threshold for intra skipping based on source variance
6209 // TODO(debargha): Specialize the threshold for super block sizes
6210 const unsigned int skip_intra_var_thresh = 64;
6211 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
6212 x->source_variance < skip_intra_var_thresh)
6213 continue;
6214 // Only search the oblique modes if the best so far is
6215 // one of the neighboring directional modes
6216 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
6217 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
6218 if (best_mode_index >= 0 &&
6219 best_mbmode.ref_frame[0] > INTRA_FRAME)
6220 continue;
6221 }
6222 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
6223 if (conditional_skipintra(this_mode, best_intra_mode))
6224 continue;
6225 }
6226 }
6227 } else {
6228 const MV_REFERENCE_FRAME ref_frames[2] = {ref_frame, second_ref_frame};
Yue Chen968bbc72016-01-19 16:45:45 -08006229 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
6230#if CONFIG_REF_MV && CONFIG_EXT_INTER
6231 mbmi_ext->compound_mode_context,
6232#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
6233 frame_mv,
Jingning Han387a10e2015-12-09 09:07:39 -08006234 this_mode, ref_frames, bsize, -1))
Jingning Han3ee6db62015-08-05 19:00:31 -07006235 continue;
6236 }
6237
6238 mbmi->mode = this_mode;
6239 mbmi->uv_mode = DC_PRED;
6240 mbmi->ref_frame[0] = ref_frame;
6241 mbmi->ref_frame[1] = second_ref_frame;
hui sube3559b2015-10-07 09:29:02 -07006242#if CONFIG_EXT_INTRA
6243 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
6244 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
6245#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07006246 // Evaluate all sub-pel filters irrespective of whether we can use
6247 // them for this frame.
6248 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP
6249 : cm->interp_filter;
6250 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
6251
6252 x->skip = 0;
6253 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
6254
6255 // Select prediction reference frames.
6256 for (i = 0; i < MAX_MB_PLANE; i++) {
6257 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
6258 if (comp_pred)
6259 xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
6260 }
6261
6262 if (ref_frame == INTRA_FRAME) {
6263 TX_SIZE uv_tx;
6264 struct macroblockd_plane *const pd = &xd->plane[1];
6265 memset(x->skip_txfm, 0, sizeof(x->skip_txfm));
hui su4aa50c12015-11-10 12:09:59 -08006266
hui sube3559b2015-10-07 09:29:02 -07006267#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08006268 is_directional_mode = (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED);
6269 if (is_directional_mode) {
hui sud7c8bc72015-11-12 19:18:32 -08006270 if (!angle_stats_ready) {
6271 const int src_stride = x->plane[0].src.stride;
6272 const uint8_t *src = x->plane[0].src.buf;
6273 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
6274 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
6275 double hist[DIRECTIONAL_MODES];
6276 PREDICTION_MODE mode;
6277
6278#if CONFIG_VP9_HIGHBITDEPTH
6279 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
6280 highbd_angle_estimation(src, src_stride, rows, cols, hist);
6281 else
6282#endif
6283 angle_estimation(src, src_stride, rows, cols, hist);
6284 for (mode = 0; mode < INTRA_MODES; ++mode) {
6285 if (mode != DC_PRED && mode != TM_PRED) {
6286 int index = get_angle_index((double)mode_to_angle_map[mode]);
6287 double score, weight = 1.0;
6288 score = hist[index];
6289 if (index > 0) {
6290 score += hist[index - 1] * 0.5;
6291 weight += 0.5;
6292 }
6293 if (index < DIRECTIONAL_MODES - 1) {
6294 score += hist[index + 1] * 0.5;
6295 weight += 0.5;
6296 }
6297 score /= weight;
6298 if (score < ANGLE_SKIP_THRESH)
6299 directional_mode_skip_mask[mode] = 1;
6300 }
6301 }
6302 angle_stats_ready = 1;
6303 }
6304 if (directional_mode_skip_mask[mbmi->mode])
6305 continue;
hui su4aa50c12015-11-10 12:09:59 -08006306 rate_overhead = write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0) +
hui su1559afd2015-12-30 10:27:19 -08006307 intra_mode_cost[mbmi->mode];
hui su4aa50c12015-11-10 12:09:59 -08006308 rate_y = INT_MAX;
6309 this_rd =
6310 rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
6311 &skippable, bsize, rate_overhead, best_rd);
6312 } else {
6313 mbmi->angle_delta[0] = 0;
6314 super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
6315 NULL, bsize, best_rd);
6316 }
6317
hui sube3559b2015-10-07 09:29:02 -07006318 // TODO(huisu): ext-intra is turned off in lossless mode for now to
6319 // avoid a unit test failure
hui su4aa50c12015-11-10 12:09:59 -08006320 if (mbmi->mode == DC_PRED && !xd->lossless[mbmi->segment_id] &&
6321 ALLOW_FILTER_INTRA_MODES) {
hui sube3559b2015-10-07 09:29:02 -07006322 MB_MODE_INFO mbmi_copy = *mbmi;
hui sube3559b2015-10-07 09:29:02 -07006323
6324 if (rate_y != INT_MAX) {
hui su1559afd2015-12-30 10:27:19 -08006325 int this_rate = rate_y + intra_mode_cost[mbmi->mode] +
hui sube3559b2015-10-07 09:29:02 -07006326 vp10_cost_bit(cm->fc->ext_intra_probs[0], 0);
6327 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, distortion_y);
6328 } else {
6329 this_rd = best_rd;
6330 }
6331
6332 if (!rd_pick_ext_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
6333 &skippable, bsize,
hui su1559afd2015-12-30 10:27:19 -08006334 intra_mode_cost[mbmi->mode], &this_rd))
hui sube3559b2015-10-07 09:29:02 -07006335 *mbmi = mbmi_copy;
6336 }
hui su4aa50c12015-11-10 12:09:59 -08006337#else
6338 super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
6339 NULL, bsize, best_rd);
hui sube3559b2015-10-07 09:29:02 -07006340#endif // CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08006341
Jingning Han3ee6db62015-08-05 19:00:31 -07006342 if (rate_y == INT_MAX)
6343 continue;
Jingning Han3ee6db62015-08-05 19:00:31 -07006344 uv_tx = get_uv_tx_size_impl(mbmi->tx_size, bsize, pd->subsampling_x,
6345 pd->subsampling_y);
6346 if (rate_uv_intra[uv_tx] == INT_MAX) {
6347 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx,
6348 &rate_uv_intra[uv_tx], &rate_uv_tokenonly[uv_tx],
6349 &dist_uv[uv_tx], &skip_uv[uv_tx], &mode_uv[uv_tx]);
hui sube3559b2015-10-07 09:29:02 -07006350#if CONFIG_EXT_INTRA
6351 ext_intra_mode_info_uv[uv_tx] = mbmi->ext_intra_mode_info;
hui su4aa50c12015-11-10 12:09:59 -08006352 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui sube3559b2015-10-07 09:29:02 -07006353#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07006354 }
6355
6356 rate_uv = rate_uv_tokenonly[uv_tx];
6357 distortion_uv = dist_uv[uv_tx];
6358 skippable = skippable && skip_uv[uv_tx];
6359 mbmi->uv_mode = mode_uv[uv_tx];
hui sube3559b2015-10-07 09:29:02 -07006360#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08006361 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui sube3559b2015-10-07 09:29:02 -07006362 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
6363 ext_intra_mode_info_uv[uv_tx].use_ext_intra_mode[1];
6364 if (ext_intra_mode_info_uv[uv_tx].use_ext_intra_mode[1]) {
6365 mbmi->ext_intra_mode_info.ext_intra_mode[1] =
6366 ext_intra_mode_info_uv[uv_tx].ext_intra_mode[1];
hui sube3559b2015-10-07 09:29:02 -07006367 }
6368#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07006369
hui su1559afd2015-12-30 10:27:19 -08006370 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv_intra[uv_tx];
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08006371
6372 if (!xd->lossless[mbmi->segment_id]) {
6373 // super_block_yrd above includes the cost of the tx_size in the
6374 // tokenonly rate, but for intra blocks, tx_size is always coded
6375 // (prediction granularity), so we account for it in the full rate,
6376 // not the tokenonly rate.
6377 rate_y -= vp10_cost_tx_size(mbmi->tx_size, max_tx_size, tx_probs);
6378 }
hui sube3559b2015-10-07 09:29:02 -07006379#if CONFIG_EXT_INTRA
hui su3b1c7662016-01-12 16:38:58 -08006380 if (is_directional_mode) {
6381 int p_angle;
6382 const int intra_filter_ctx = vp10_get_pred_context_intra_interp(xd);
hui su4aa50c12015-11-10 12:09:59 -08006383 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
6384 MAX_ANGLE_DELTAS +
6385 mbmi->angle_delta[0]);
hui su3b1c7662016-01-12 16:38:58 -08006386 p_angle = mode_to_angle_map[mbmi->mode] +
6387 mbmi->angle_delta[0] * ANGLE_STEP;
6388 if (pick_intra_filter(p_angle))
6389 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
6390 }
hui su4aa50c12015-11-10 12:09:59 -08006391
6392 if (mbmi->mode == DC_PRED && ALLOW_FILTER_INTRA_MODES) {
hui sube3559b2015-10-07 09:29:02 -07006393 rate2 += vp10_cost_bit(cm->fc->ext_intra_probs[0],
6394 mbmi->ext_intra_mode_info.use_ext_intra_mode[0]);
6395 if (mbmi->ext_intra_mode_info.use_ext_intra_mode[0]) {
6396 EXT_INTRA_MODE ext_intra_mode =
6397 mbmi->ext_intra_mode_info.ext_intra_mode[0];
hui su4aa50c12015-11-10 12:09:59 -08006398 rate2 += write_uniform_cost(FILTER_INTRA_MODES, ext_intra_mode);
hui sube3559b2015-10-07 09:29:02 -07006399 }
6400 }
6401#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07006402 if (this_mode != DC_PRED && this_mode != TM_PRED)
6403 rate2 += intra_cost_penalty;
6404 distortion2 = distortion_y + distortion_uv;
6405 } else {
Jingning Han28e03932016-01-20 17:40:47 -08006406#if CONFIG_REF_MV
6407 mbmi->ref_mv_idx = 0;
6408 ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
6409#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07006410 this_rd = handle_inter_mode(cpi, x, bsize,
6411 &rate2, &distortion2, &skippable,
6412 &rate_y, &rate_uv,
6413 &disable_skip, frame_mv,
6414 mi_row, mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08006415#if CONFIG_EXT_INTER
6416 single_newmvs,
6417#else
6418 single_newmv,
6419#endif // CONFIG_EXT_INTER
6420 single_inter_filter,
Jingning Han3ee6db62015-08-05 19:00:31 -07006421 single_skippable, &total_sse, best_rd,
6422 &mask_filter, filter_cache);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07006423
Jingning Han67cf8902016-01-15 09:05:51 -08006424#if CONFIG_REF_MV
Jingning Han4fb8b212016-01-19 16:36:25 -08006425 // TODO(jingning): This needs some refactoring to improve code quality
6426 // and reduce redundant steps.
Jingning Han28e03932016-01-20 17:40:47 -08006427 if (mbmi->mode == NEARMV &&
6428 mbmi_ext->ref_mv_count[ref_frame_type] > 2) {
Jingning Han67cf8902016-01-15 09:05:51 -08006429 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
6430 int_mv cur_mv = mbmi_ext->ref_mv_stack[ref_frame][2].this_mv;
6431 MB_MODE_INFO backup_mbmi = *mbmi;
6432
Jingning Han4fb8b212016-01-19 16:36:25 -08006433 int64_t tmp_ref_rd = this_rd;
6434 int ref_idx;
Jingning Han28e03932016-01-20 17:40:47 -08006435 int ref_set = VPXMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 2);
6436
Jingning Han49589872016-01-21 18:07:31 -08006437 uint8_t drl0_ctx =
Jingning Hana39e83d2016-02-11 16:38:13 -08006438 vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 1);
Jingning Han49589872016-01-21 18:07:31 -08006439 rate2 += cpi->drl_mode_cost0[drl0_ctx][0];
Jingning Han67cf8902016-01-15 09:05:51 -08006440
Jingning Han590265e2016-01-15 11:33:40 -08006441 if (this_rd < INT64_MAX) {
6442 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
6443 RDCOST(x->rdmult, x->rddiv, 0, total_sse))
6444 tmp_ref_rd = RDCOST(x->rdmult, x->rddiv,
6445 rate2 + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0),
6446 distortion2);
6447 else
6448 tmp_ref_rd = RDCOST(x->rdmult, x->rddiv,
6449 rate2 + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1) -
6450 rate_y - rate_uv,
6451 total_sse);
6452 }
6453
Jingning Han4fb8b212016-01-19 16:36:25 -08006454 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
6455 int64_t tmp_alt_rd = INT64_MAX;
6456 int tmp_rate = 0, tmp_rate_y = 0, tmp_rate_uv = 0;
6457 int tmp_skip = 1;
6458 int64_t tmp_dist = 0, tmp_sse = 0;
Jingning Han590265e2016-01-15 11:33:40 -08006459
Jingning Han4fb8b212016-01-19 16:36:25 -08006460 cur_mv = mbmi_ext->ref_mv_stack[ref_frame][2 + ref_idx].this_mv;
6461 lower_mv_precision(&cur_mv.as_mv, cm->allow_high_precision_mv);
6462 clamp_mv2(&cur_mv.as_mv, xd);
6463
6464 if (!mv_check_bounds(x, &cur_mv.as_mv)) {
6465 int64_t dummy_filter_cache[SWITCHABLE_FILTER_CONTEXTS];
6466 INTERP_FILTER dummy_single_inter_filter[MB_MODE_COUNT]
6467 [MAX_REF_FRAMES];
6468 int dummy_single_skippable[MB_MODE_COUNT][MAX_REF_FRAMES];
6469 int dummy_disable_skip = 0;
6470 int64_t dummy_mask_filter = 0;
6471#if CONFIG_EXT_INTER
6472 int_mv dummy_single_newmvs[2][MAX_REF_FRAMES] =
6473 { { { 0 } }, { { 0 } } };
6474#else
6475 int_mv dummy_single_newmv[MAX_REF_FRAMES] = { { 0 } };
6476#endif
6477
6478
Jingning Han28e03932016-01-20 17:40:47 -08006479 mbmi->ref_mv_idx = 1 + ref_idx;
6480
Jingning Han4fb8b212016-01-19 16:36:25 -08006481 frame_mv[NEARMV][ref_frame] = cur_mv;
6482 tmp_alt_rd = handle_inter_mode(cpi, x, bsize,
6483 &tmp_rate, &tmp_dist, &tmp_skip,
6484 &tmp_rate_y, &tmp_rate_uv,
6485 &dummy_disable_skip, frame_mv,
6486 mi_row, mi_col,
6487#if CONFIG_EXT_INTER
6488 dummy_single_newmvs,
6489#else
6490 dummy_single_newmv,
6491#endif
6492 dummy_single_inter_filter,
6493 dummy_single_skippable,
6494 &tmp_sse, best_rd,
6495 &dummy_mask_filter,
6496 dummy_filter_cache);
6497 }
6498
Jingning Han49589872016-01-21 18:07:31 -08006499 tmp_rate += cpi->drl_mode_cost0[drl0_ctx][1];
6500
6501 if (mbmi_ext->ref_mv_count[ref_frame_type] > 3) {
6502 uint8_t drl1_ctx =
Jingning Hana39e83d2016-02-11 16:38:13 -08006503 vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 2);
Jingning Han49589872016-01-21 18:07:31 -08006504 tmp_rate += cpi->drl_mode_cost1[drl1_ctx][ref_idx];
6505 }
Jingning Han4fb8b212016-01-19 16:36:25 -08006506
6507 if (tmp_alt_rd < INT64_MAX) {
6508 if (RDCOST(x->rdmult, x->rddiv,
6509 tmp_rate_y + tmp_rate_uv, tmp_dist) <
6510 RDCOST(x->rdmult, x->rddiv, 0, tmp_sse))
6511 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv,
6512 tmp_rate + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0),
6513 tmp_dist);
6514 else
6515 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv,
6516 tmp_rate + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1) -
6517 tmp_rate_y - tmp_rate_uv,
6518 tmp_sse);
6519 }
6520
6521 if (tmp_ref_rd > tmp_alt_rd) {
6522 rate2 = tmp_rate;
6523 distortion2 = tmp_dist;
6524 skippable = tmp_skip;
6525 rate_y = tmp_rate_y;
6526 rate_uv = tmp_rate_uv;
6527 total_sse = tmp_sse;
6528 this_rd = tmp_alt_rd;
Jingning Han4fb8b212016-01-19 16:36:25 -08006529 // Indicator of the effective nearmv reference motion vector.
Jingning Han28e03932016-01-20 17:40:47 -08006530 best_ref_mv_idx[ref_frame_type] = 1 + ref_idx;
Jingning Han4fb8b212016-01-19 16:36:25 -08006531 tmp_ref_rd = tmp_alt_rd;
6532 backup_mbmi = *mbmi;
6533 } else {
6534 *mbmi = backup_mbmi;
6535 }
Jingning Han67cf8902016-01-15 09:05:51 -08006536 }
6537
6538 frame_mv[NEARMV][ref_frame] = backup_mv;
Jingning Han67cf8902016-01-15 09:05:51 -08006539 }
6540#endif
6541
Jingning Han3ee6db62015-08-05 19:00:31 -07006542 if (this_rd == INT64_MAX)
6543 continue;
6544
6545 compmode_cost = vp10_cost_bit(comp_mode_p, comp_pred);
6546
6547 if (cm->reference_mode == REFERENCE_MODE_SELECT)
6548 rate2 += compmode_cost;
6549 }
6550
6551 // Estimate the reference frame signaling cost and add it
6552 // to the rolling cost variable.
6553 if (comp_pred) {
6554 rate2 += ref_costs_comp[ref_frame];
6555 } else {
6556 rate2 += ref_costs_single[ref_frame];
6557 }
6558
6559 if (!disable_skip) {
6560 if (skippable) {
6561 // Back out the coefficient coding costs
6562 rate2 -= (rate_y + rate_uv);
Debargha Mukherjee3787b172015-11-19 16:51:16 -08006563 rate_y = 0;
6564 rate_uv = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07006565 // Cost the skip mb case
6566 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07006567
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04006568 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Jingning Han3ee6db62015-08-05 19:00:31 -07006569 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
6570 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
6571 // Add in the cost of the no skip flag.
6572 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
6573 } else {
6574 // FIXME(rbultje) make this work for splitmv also
6575 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
6576 distortion2 = total_sse;
6577 assert(total_sse >= 0);
6578 rate2 -= (rate_y + rate_uv);
6579 this_skip2 = 1;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08006580 rate_y = 0;
6581 rate_uv = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07006582 }
6583 } else {
6584 // Add in the cost of the no skip flag.
6585 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
6586 }
6587
6588 // Calculate the final RD estimate for this mode.
6589 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
6590 }
6591
6592 // Apply an adjustment to the rd value based on the similarity of the
6593 // source variance and reconstructed variance.
6594 rd_variance_adjustment(cpi, x, bsize, &this_rd,
6595 ref_frame, x->source_variance);
6596
6597 if (ref_frame == INTRA_FRAME) {
6598 // Keep record of best intra rd
6599 if (this_rd < best_intra_rd) {
6600 best_intra_rd = this_rd;
6601 best_intra_mode = mbmi->mode;
6602 }
6603 }
6604
6605 if (!disable_skip && ref_frame == INTRA_FRAME) {
6606 for (i = 0; i < REFERENCE_MODES; ++i)
James Zern5e16d392015-08-17 18:19:22 -07006607 best_pred_rd[i] = VPXMIN(best_pred_rd[i], this_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07006608 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
James Zern5e16d392015-08-17 18:19:22 -07006609 best_filter_rd[i] = VPXMIN(best_filter_rd[i], this_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07006610 }
6611
6612 // Did this mode help.. i.e. is it the new best mode
6613 if (this_rd < best_rd || x->skip) {
6614 int max_plane = MAX_MB_PLANE;
6615 if (!mode_excluded) {
6616 // Note index of best mode so far
6617 best_mode_index = mode_index;
6618
6619 if (ref_frame == INTRA_FRAME) {
6620 /* required for left and above block mv */
6621 mbmi->mv[0].as_int = 0;
6622 max_plane = 1;
6623 } else {
6624 best_pred_sse = x->pred_sse[ref_frame];
6625 }
6626
6627 rd_cost->rate = rate2;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08006628#if CONFIG_SUPERTX
6629 *returnrate_nocoef = rate2 - rate_y - rate_uv;
6630 if (!disable_skip) {
6631 *returnrate_nocoef -= vp10_cost_bit(vp10_get_skip_prob(cm, xd),
6632 skippable || this_skip2);
6633 }
6634 *returnrate_nocoef -= vp10_cost_bit(vp10_get_intra_inter_prob(cm, xd),
6635 mbmi->ref_frame[0] != INTRA_FRAME);
6636#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07006637 rd_cost->dist = distortion2;
6638 rd_cost->rdcost = this_rd;
6639 best_rd = this_rd;
6640 best_mbmode = *mbmi;
6641 best_skip2 = this_skip2;
6642 best_mode_skippable = skippable;
6643
6644 if (!x->select_tx_size)
6645 swap_block_ptr(x, ctx, 1, 0, 0, max_plane);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07006646
6647#if CONFIG_VAR_TX
6648 for (i = 0; i < MAX_MB_PLANE; ++i)
6649 memcpy(ctx->blk_skip[i], x->blk_skip[i],
6650 sizeof(uint8_t) * ctx->num_4x4_blk);
6651#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006652 memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
hui su088b05f2015-08-12 10:41:51 -07006653 sizeof(ctx->zcoeff_blk[0]) * ctx->num_4x4_blk);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07006654#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07006655
6656 // TODO(debargha): enhance this test with a better distortion prediction
6657 // based on qp, activity mask and history
6658 if ((mode_search_skip_flags & FLAG_EARLY_TERMINATE) &&
6659 (mode_index > MIN_EARLY_TERM_INDEX)) {
6660 int qstep = xd->plane[0].dequant[1];
6661 // TODO(debargha): Enhance this by specializing for each mode_index
6662 int scale = 4;
6663#if CONFIG_VP9_HIGHBITDEPTH
6664 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6665 qstep >>= (xd->bd - 8);
6666 }
6667#endif // CONFIG_VP9_HIGHBITDEPTH
6668 if (x->source_variance < UINT_MAX) {
6669 const int var_adjust = (x->source_variance < 16);
6670 scale -= var_adjust;
6671 }
6672 if (ref_frame > INTRA_FRAME &&
6673 distortion2 * scale < qstep * qstep) {
6674 early_term = 1;
6675 }
6676 }
6677 }
6678 }
6679
6680 /* keep record of best compound/single-only prediction */
6681 if (!disable_skip && ref_frame != INTRA_FRAME) {
6682 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
6683
6684 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
6685 single_rate = rate2 - compmode_cost;
6686 hybrid_rate = rate2;
6687 } else {
6688 single_rate = rate2;
6689 hybrid_rate = rate2 + compmode_cost;
6690 }
6691
6692 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
6693 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
6694
6695 if (!comp_pred) {
6696 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
6697 best_pred_rd[SINGLE_REFERENCE] = single_rd;
6698 } else {
6699 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
6700 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
6701 }
6702 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
6703 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
6704
6705 /* keep record of best filter type */
6706 if (!mode_excluded && cm->interp_filter != BILINEAR) {
6707 int64_t ref = filter_cache[cm->interp_filter == SWITCHABLE ?
6708 SWITCHABLE_FILTERS : cm->interp_filter];
6709
6710 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
6711 int64_t adj_rd;
6712 if (ref == INT64_MAX)
6713 adj_rd = 0;
6714 else if (filter_cache[i] == INT64_MAX)
6715 // when early termination is triggered, the encoder does not have
6716 // access to the rate-distortion cost. it only knows that the cost
6717 // should be above the maximum valid value. hence it takes the known
6718 // maximum plus an arbitrary constant as the rate-distortion cost.
6719 adj_rd = mask_filter - ref + 10;
6720 else
6721 adj_rd = filter_cache[i] - ref;
6722
6723 adj_rd += this_rd;
James Zern5e16d392015-08-17 18:19:22 -07006724 best_filter_rd[i] = VPXMIN(best_filter_rd[i], adj_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07006725 }
6726 }
6727 }
6728
6729 if (early_term)
6730 break;
6731
6732 if (x->skip && !comp_pred)
6733 break;
6734 }
6735
6736 // The inter modes' rate costs are not calculated precisely in some cases.
6737 // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
6738 // ZEROMV. Here, checks are added for those cases, and the mode decisions
6739 // are corrected.
Yue Chen1ac85872016-01-07 15:13:52 -08006740 if (best_mbmode.mode == NEWMV
6741#if CONFIG_EXT_INTER
6742 || best_mbmode.mode == NEWFROMNEARMV
Yue Chen968bbc72016-01-19 16:45:45 -08006743 || best_mbmode.mode == NEW_NEWMV
Yue Chen1ac85872016-01-07 15:13:52 -08006744#endif // CONFIG_EXT_INTER
6745 ) {
Jingning Han3ee6db62015-08-05 19:00:31 -07006746 const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0],
6747 best_mbmode.ref_frame[1]};
6748 int comp_pred_mode = refs[1] > INTRA_FRAME;
Jingning Han33cc1bd2016-01-12 15:06:59 -08006749#if CONFIG_REF_MV
6750 if (!comp_pred_mode) {
Jingning Han4fb8b212016-01-19 16:36:25 -08006751 if (best_ref_mv_idx[best_mbmode.ref_frame[0]] > 0 &&
Jingning Han67cf8902016-01-15 09:05:51 -08006752 best_mbmode.ref_frame[1] == NONE) {
Jingning Han4fb8b212016-01-19 16:36:25 -08006753 int idx = best_ref_mv_idx[best_mbmode.ref_frame[0]] + 1;
Jingning Han67cf8902016-01-15 09:05:51 -08006754 int_mv cur_mv =
Jingning Han4fb8b212016-01-19 16:36:25 -08006755 mbmi_ext->ref_mv_stack[best_mbmode.ref_frame[0]][idx].this_mv;
Jingning Han67cf8902016-01-15 09:05:51 -08006756 lower_mv_precision(&cur_mv.as_mv, cm->allow_high_precision_mv);
6757 frame_mv[NEARMV][refs[0]] = cur_mv;
6758 }
6759
Jingning Han33cc1bd2016-01-12 15:06:59 -08006760 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
6761 best_mbmode.mode = NEARESTMV;
6762 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
6763 best_mbmode.mode = NEARMV;
6764 else if (best_mbmode.mv[0].as_int == 0)
6765 best_mbmode.mode = ZEROMV;
6766 } else {
6767 uint8_t rf_type = vp10_ref_frame_type(best_mbmode.ref_frame);
Jingning Han3944cfb2016-01-13 09:03:15 -08006768 int i;
6769 const int allow_hp = cm->allow_high_precision_mv;
6770 int_mv nearestmv[2] = { frame_mv[NEARESTMV][refs[0]],
6771 frame_mv[NEARESTMV][refs[1]] };
Jingning Han3ee6db62015-08-05 19:00:31 -07006772
Jingning Han3944cfb2016-01-13 09:03:15 -08006773 int_mv nearmv[2] = { frame_mv[NEARMV][refs[0]],
6774 frame_mv[NEARMV][refs[1]] };
6775
6776 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
Jingning Han33cc1bd2016-01-12 15:06:59 -08006777 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
6778 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
Jingning Han3944cfb2016-01-13 09:03:15 -08006779 }
6780
6781 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
Jingning Han28e03932016-01-20 17:40:47 -08006782 int ref_mv_idx = best_ref_mv_idx[rf_type] + 1;
6783 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][ref_mv_idx].this_mv;
6784 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][ref_mv_idx].comp_mv;
Jingning Han33cc1bd2016-01-12 15:06:59 -08006785 }
Jingning Han3944cfb2016-01-13 09:03:15 -08006786
6787 for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
6788 lower_mv_precision(&nearestmv[i].as_mv, allow_hp);
6789 lower_mv_precision(&nearmv[i].as_mv, allow_hp);
6790 }
6791
6792 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
6793 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
Yue Chen968bbc72016-01-19 16:45:45 -08006794#if CONFIG_EXT_INTER
6795 best_mbmode.mode = NEAREST_NEARESTMV;
6796 else if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
6797 nearmv[1].as_int == best_mbmode.mv[1].as_int)
6798 best_mbmode.mode = NEAREST_NEARMV;
6799 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
6800 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
6801 best_mbmode.mode = NEAR_NEARESTMV;
6802 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
6803 best_mbmode.mode = ZERO_ZEROMV;
6804#else
Jingning Han3944cfb2016-01-13 09:03:15 -08006805 best_mbmode.mode = NEARESTMV;
6806 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
6807 nearmv[1].as_int == best_mbmode.mv[1].as_int)
6808 best_mbmode.mode = NEARMV;
6809 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
6810 best_mbmode.mode = ZEROMV;
Yue Chen968bbc72016-01-19 16:45:45 -08006811#endif // CONFIG_EXT_INTER
Jingning Han33cc1bd2016-01-12 15:06:59 -08006812 }
6813#else
Yue Chen968bbc72016-01-19 16:45:45 -08006814#if CONFIG_EXT_INTER
6815 if (!comp_pred_mode) {
6816#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006817 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
6818 ((comp_pred_mode && frame_mv[NEARESTMV][refs[1]].as_int ==
6819 best_mbmode.mv[1].as_int) || !comp_pred_mode))
6820 best_mbmode.mode = NEARESTMV;
6821 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
6822 ((comp_pred_mode && frame_mv[NEARMV][refs[1]].as_int ==
6823 best_mbmode.mv[1].as_int) || !comp_pred_mode))
6824 best_mbmode.mode = NEARMV;
6825 else if (best_mbmode.mv[0].as_int == 0 &&
6826 ((comp_pred_mode && best_mbmode.mv[1].as_int == 0) || !comp_pred_mode))
6827 best_mbmode.mode = ZEROMV;
Yue Chen968bbc72016-01-19 16:45:45 -08006828#if CONFIG_EXT_INTER
6829 } else {
6830 const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0],
6831 best_mbmode.ref_frame[1]};
6832
6833 if (frame_mv[NEAREST_NEARESTMV][refs[0]].as_int ==
6834 best_mbmode.mv[0].as_int &&
6835 frame_mv[NEAREST_NEARESTMV][refs[1]].as_int ==
6836 best_mbmode.mv[1].as_int)
6837 best_mbmode.mode = NEAREST_NEARESTMV;
6838 else if (frame_mv[NEAREST_NEARMV][refs[0]].as_int ==
6839 best_mbmode.mv[0].as_int &&
6840 frame_mv[NEAREST_NEARMV][refs[1]].as_int ==
6841 best_mbmode.mv[1].as_int)
6842 best_mbmode.mode = NEAREST_NEARMV;
6843 else if (frame_mv[NEAR_NEARESTMV][refs[0]].as_int ==
6844 best_mbmode.mv[0].as_int &&
6845 frame_mv[NEAR_NEARESTMV][refs[1]].as_int ==
6846 best_mbmode.mv[1].as_int)
6847 best_mbmode.mode = NEAR_NEARESTMV;
6848 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
6849 best_mbmode.mode = ZERO_ZEROMV;
6850 }
6851#endif // CONFIG_EXT_INTER
Jingning Han33cc1bd2016-01-12 15:06:59 -08006852#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07006853 }
6854
Jingning Hanaa5d53e2015-12-07 15:54:59 -08006855#if CONFIG_REF_MV
6856 if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
6857 best_mbmode.mv[0].as_int == 0 &&
Yue Chen968bbc72016-01-19 16:45:45 -08006858#if CONFIG_EXT_INTER
6859 best_mbmode.ref_frame[1] == NONE) {
6860#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08006861 (best_mbmode.ref_frame[1] == NONE || best_mbmode.mv[1].as_int == 0)) {
Yue Chen968bbc72016-01-19 16:45:45 -08006862#endif // CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08006863 int16_t mode_ctx = mbmi_ext->mode_context[best_mbmode.ref_frame[0]];
Yue Chen968bbc72016-01-19 16:45:45 -08006864#if !CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08006865 if (best_mbmode.ref_frame[1] > NONE)
6866 mode_ctx &= (mbmi_ext->mode_context[best_mbmode.ref_frame[1]] | 0x00ff);
Yue Chen968bbc72016-01-19 16:45:45 -08006867#endif // !CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08006868
6869 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET))
6870 best_mbmode.mode = ZEROMV;
6871 }
Jingning Han67cf8902016-01-15 09:05:51 -08006872
Jingning Han28e03932016-01-20 17:40:47 -08006873 if (best_mbmode.mode == NEARMV) {
6874 uint8_t ref_frame_type = vp10_ref_frame_type(best_mbmode.ref_frame);
6875 best_mbmode.ref_mv_idx = best_ref_mv_idx[ref_frame_type];
6876 }
Jingning Hanaa5d53e2015-12-07 15:54:59 -08006877#endif
6878
Jingning Han3ee6db62015-08-05 19:00:31 -07006879 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
6880 rd_cost->rate = INT_MAX;
6881 rd_cost->rdcost = INT64_MAX;
6882 return;
6883 }
6884
6885 // If we used an estimate for the uv intra rd in the loop above...
6886 if (sf->use_uv_intra_rd_estimate) {
6887 // Do Intra UV best rd mode selection if best mode choice above was intra.
6888 if (best_mbmode.ref_frame[0] == INTRA_FRAME) {
6889 TX_SIZE uv_tx_size;
6890 *mbmi = best_mbmode;
6891 uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
6892 rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra[uv_tx_size],
6893 &rate_uv_tokenonly[uv_tx_size],
6894 &dist_uv[uv_tx_size],
6895 &skip_uv[uv_tx_size],
6896 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize,
6897 uv_tx_size);
6898 }
6899 }
6900
6901 assert((cm->interp_filter == SWITCHABLE) ||
6902 (cm->interp_filter == best_mbmode.interp_filter) ||
6903 !is_inter_block(&best_mbmode));
6904
6905 if (!cpi->rc.is_src_frame_alt_ref)
6906 vp10_update_rd_thresh_fact(tile_data->thresh_freq_fact,
6907 sf->adaptive_rd_thresh, bsize, best_mode_index);
6908
6909 // macroblock modes
6910 *mbmi = best_mbmode;
6911 x->skip |= best_skip2;
6912
6913 for (i = 0; i < REFERENCE_MODES; ++i) {
6914 if (best_pred_rd[i] == INT64_MAX)
6915 best_pred_diff[i] = INT_MIN;
6916 else
6917 best_pred_diff[i] = best_rd - best_pred_rd[i];
6918 }
6919
6920 if (!x->skip) {
6921 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
6922 if (best_filter_rd[i] == INT64_MAX)
6923 best_filter_diff[i] = 0;
6924 else
6925 best_filter_diff[i] = best_rd - best_filter_rd[i];
6926 }
6927 if (cm->interp_filter == SWITCHABLE)
6928 assert(best_filter_diff[SWITCHABLE_FILTERS] == 0);
6929 } else {
6930 vp10_zero(best_filter_diff);
6931 }
6932
6933 // TODO(yunqingwang): Moving this line in front of the above best_filter_diff
6934 // updating code causes PSNR loss. Need to figure out the confliction.
6935 x->skip |= best_mode_skippable;
6936
6937 if (!x->skip && !x->select_tx_size) {
6938 int has_high_freq_coeff = 0;
6939 int plane;
6940 int max_plane = is_inter_block(&xd->mi[0]->mbmi)
6941 ? MAX_MB_PLANE : 1;
6942 for (plane = 0; plane < max_plane; ++plane) {
6943 x->plane[plane].eobs = ctx->eobs_pbuf[plane][1];
6944 has_high_freq_coeff |= vp10_has_high_freq_in_plane(x, bsize, plane);
6945 }
6946
6947 for (plane = max_plane; plane < MAX_MB_PLANE; ++plane) {
6948 x->plane[plane].eobs = ctx->eobs_pbuf[plane][2];
6949 has_high_freq_coeff |= vp10_has_high_freq_in_plane(x, bsize, plane);
6950 }
6951
6952 best_mode_skippable |= !has_high_freq_coeff;
6953 }
6954
6955 assert(best_mode_index >= 0);
6956
6957 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
6958 best_filter_diff, best_mode_skippable);
6959}
6960
Yaowu Xu26a9afc2015-08-13 09:42:27 -07006961void vp10_rd_pick_inter_mode_sb_seg_skip(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07006962 TileDataEnc *tile_data,
6963 MACROBLOCK *x,
6964 RD_COST *rd_cost,
6965 BLOCK_SIZE bsize,
6966 PICK_MODE_CONTEXT *ctx,
6967 int64_t best_rd_so_far) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07006968 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07006969 MACROBLOCKD *const xd = &x->e_mbd;
6970 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6971 unsigned char segment_id = mbmi->segment_id;
6972 const int comp_pred = 0;
6973 int i;
6974 int64_t best_pred_diff[REFERENCE_MODES];
6975 int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
6976 unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
6977 vpx_prob comp_mode_p;
6978 INTERP_FILTER best_filter = SWITCHABLE;
6979 int64_t this_rd = INT64_MAX;
6980 int rate2 = 0;
6981 const int64_t distortion2 = 0;
6982
Jingning Han3ee6db62015-08-05 19:00:31 -07006983 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
6984 &comp_mode_p);
6985
6986 for (i = 0; i < MAX_REF_FRAMES; ++i)
6987 x->pred_sse[i] = INT_MAX;
6988 for (i = LAST_FRAME; i < MAX_REF_FRAMES; ++i)
6989 x->pred_mv_sad[i] = INT_MAX;
6990
6991 rd_cost->rate = INT_MAX;
6992
6993 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
6994
hui suc93e5cc2015-12-07 18:18:57 -08006995 mbmi->palette_mode_info.palette_size[0] = 0;
6996 mbmi->palette_mode_info.palette_size[1] = 0;
hui sube3559b2015-10-07 09:29:02 -07006997#if CONFIG_EXT_INTRA
6998 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
6999 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
7000#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07007001 mbmi->mode = ZEROMV;
7002 mbmi->uv_mode = DC_PRED;
7003 mbmi->ref_frame[0] = LAST_FRAME;
7004 mbmi->ref_frame[1] = NONE;
7005 mbmi->mv[0].as_int = 0;
7006 x->skip = 1;
7007
7008 if (cm->interp_filter != BILINEAR) {
7009 best_filter = EIGHTTAP;
7010 if (cm->interp_filter == SWITCHABLE &&
Debargha Mukherjee85514c42015-10-30 09:19:36 -07007011#if CONFIG_EXT_INTERP
7012 vp10_is_interp_needed(xd) &&
7013#endif // CONFIG_EXT_INTERP
Jingning Han3ee6db62015-08-05 19:00:31 -07007014 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
7015 int rs;
7016 int best_rs = INT_MAX;
7017 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
7018 mbmi->interp_filter = i;
7019 rs = vp10_get_switchable_rate(cpi, xd);
7020 if (rs < best_rs) {
7021 best_rs = rs;
7022 best_filter = mbmi->interp_filter;
7023 }
7024 }
7025 }
7026 }
7027 // Set the appropriate filter
7028 if (cm->interp_filter == SWITCHABLE) {
7029 mbmi->interp_filter = best_filter;
7030 rate2 += vp10_get_switchable_rate(cpi, xd);
7031 } else {
7032 mbmi->interp_filter = cm->interp_filter;
7033 }
7034
7035 if (cm->reference_mode == REFERENCE_MODE_SELECT)
7036 rate2 += vp10_cost_bit(comp_mode_p, comp_pred);
7037
7038 // Estimate the reference frame signaling cost and add it
7039 // to the rolling cost variable.
7040 rate2 += ref_costs_single[LAST_FRAME];
7041 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
7042
7043 rd_cost->rate = rate2;
7044 rd_cost->dist = distortion2;
7045 rd_cost->rdcost = this_rd;
7046
7047 if (this_rd >= best_rd_so_far) {
7048 rd_cost->rate = INT_MAX;
7049 rd_cost->rdcost = INT64_MAX;
7050 return;
7051 }
7052
7053 assert((cm->interp_filter == SWITCHABLE) ||
7054 (cm->interp_filter == mbmi->interp_filter));
7055
7056 vp10_update_rd_thresh_fact(tile_data->thresh_freq_fact,
7057 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
7058
7059 vp10_zero(best_pred_diff);
7060 vp10_zero(best_filter_diff);
7061
7062 if (!x->select_tx_size)
7063 swap_block_ptr(x, ctx, 1, 0, 0, MAX_MB_PLANE);
7064 store_coding_context(x, ctx, THR_ZEROMV,
7065 best_pred_diff, best_filter_diff, 0);
7066}
7067
Debargha Mukherjee3787b172015-11-19 16:51:16 -08007068void vp10_rd_pick_inter_mode_sub8x8(struct VP10_COMP *cpi,
7069 TileDataEnc *tile_data,
7070 struct macroblock *x,
7071 int mi_row, int mi_col,
7072 struct RD_COST *rd_cost,
7073#if CONFIG_SUPERTX
7074 int *returnrate_nocoef,
7075#endif // CONFIG_SUPERTX
7076 BLOCK_SIZE bsize,
7077 PICK_MODE_CONTEXT *ctx,
7078 int64_t best_rd_so_far) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07007079 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07007080 RD_OPT *const rd_opt = &cpi->rd;
7081 SPEED_FEATURES *const sf = &cpi->sf;
7082 MACROBLOCKD *const xd = &x->e_mbd;
7083 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7084 const struct segmentation *const seg = &cm->seg;
7085 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
7086 unsigned char segment_id = mbmi->segment_id;
7087 int comp_pred, i;
7088 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
Zoe Liu3ec16012015-11-12 02:12:17 -08007089 struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE];
7090 static const int flag_list[REFS_PER_FRAME + 1] = {
7091 0,
7092 VP9_LAST_FLAG,
7093#if CONFIG_EXT_REFS
7094 VP9_LAST2_FLAG,
7095 VP9_LAST3_FLAG,
7096 VP9_LAST4_FLAG,
7097#endif // CONFIG_EXT_REFS
7098 VP9_GOLD_FLAG,
7099 VP9_ALT_FLAG
7100 };
Jingning Han3ee6db62015-08-05 19:00:31 -07007101 int64_t best_rd = best_rd_so_far;
7102 int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
7103 int64_t best_pred_diff[REFERENCE_MODES];
7104 int64_t best_pred_rd[REFERENCE_MODES];
7105 int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
7106 int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
7107 MB_MODE_INFO best_mbmode;
7108 int ref_index, best_ref_index = 0;
7109 unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
7110 vpx_prob comp_mode_p;
7111 INTERP_FILTER tmp_best_filter = SWITCHABLE;
7112 int rate_uv_intra, rate_uv_tokenonly;
7113 int64_t dist_uv;
7114 int skip_uv;
7115 PREDICTION_MODE mode_uv = DC_PRED;
7116 const int intra_cost_penalty = vp10_get_intra_cost_penalty(
7117 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
Yue Chen1ac85872016-01-07 15:13:52 -08007118#if CONFIG_EXT_INTER
7119 int_mv seg_mvs[4][2][MAX_REF_FRAMES];
7120#else
Jingning Han3ee6db62015-08-05 19:00:31 -07007121 int_mv seg_mvs[4][MAX_REF_FRAMES];
Yue Chen1ac85872016-01-07 15:13:52 -08007122#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007123 b_mode_info best_bmodes[4];
7124 int best_skip2 = 0;
7125 int ref_frame_skip_mask[2] = { 0 };
7126 int64_t mask_filter = 0;
7127 int64_t filter_cache[SWITCHABLE_FILTER_CONTEXTS];
7128 int internal_active_edge =
7129 vp10_active_edge_sb(cpi, mi_row, mi_col) && vp10_internal_image_edge(cpi);
7130
Debargha Mukherjee3787b172015-11-19 16:51:16 -08007131#if CONFIG_SUPERTX
7132 best_rd_so_far = INT64_MAX;
7133 best_rd = best_rd_so_far;
7134 best_yrd = best_rd_so_far;
7135#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07007136 memset(x->zcoeff_blk[TX_4X4], 0, 4);
7137 vp10_zero(best_mbmode);
7138
hui sube3559b2015-10-07 09:29:02 -07007139#if CONFIG_EXT_INTRA
7140 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
7141 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
7142#endif // CONFIG_EXT_INTRA
7143
Jingning Han3ee6db62015-08-05 19:00:31 -07007144 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
7145 filter_cache[i] = INT64_MAX;
7146
7147 for (i = 0; i < 4; i++) {
7148 int j;
Yue Chen1ac85872016-01-07 15:13:52 -08007149#if CONFIG_EXT_INTER
7150 int k;
7151
7152 for (k = 0; k < 2; k++)
7153 for (j = 0; j < MAX_REF_FRAMES; j++)
7154 seg_mvs[i][k][j].as_int = INVALID_MV;
7155#else
Jingning Han3ee6db62015-08-05 19:00:31 -07007156 for (j = 0; j < MAX_REF_FRAMES; j++)
7157 seg_mvs[i][j].as_int = INVALID_MV;
Yue Chen1ac85872016-01-07 15:13:52 -08007158#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007159 }
7160
7161 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
7162 &comp_mode_p);
7163
7164 for (i = 0; i < REFERENCE_MODES; ++i)
7165 best_pred_rd[i] = INT64_MAX;
7166 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
7167 best_filter_rd[i] = INT64_MAX;
7168 rate_uv_intra = INT_MAX;
7169
7170 rd_cost->rate = INT_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08007171#if CONFIG_SUPERTX
7172 *returnrate_nocoef = INT_MAX;
7173#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07007174
7175 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
Jingning Han387a10e2015-12-09 09:07:39 -08007176 x->mbmi_ext->mode_context[ref_frame] = 0;
Yue Chen968bbc72016-01-19 16:45:45 -08007177#if CONFIG_REF_MV && CONFIG_EXT_INTER
7178 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
7179#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007180 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
7181 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
7182 frame_mv[NEARESTMV], frame_mv[NEARMV],
7183 yv12_mb);
7184 } else {
7185 ref_frame_skip_mask[0] |= (1 << ref_frame);
7186 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7187 }
7188 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Yue Chen1ac85872016-01-07 15:13:52 -08007189#if CONFIG_EXT_INTER
7190 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
7191#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007192 frame_mv[ZEROMV][ref_frame].as_int = 0;
7193 }
7194
hui suc93e5cc2015-12-07 18:18:57 -08007195 mbmi->palette_mode_info.palette_size[0] = 0;
7196 mbmi->palette_mode_info.palette_size[1] = 0;
7197
Jingning Han3ee6db62015-08-05 19:00:31 -07007198 for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
7199 int mode_excluded = 0;
7200 int64_t this_rd = INT64_MAX;
7201 int disable_skip = 0;
7202 int compmode_cost = 0;
7203 int rate2 = 0, rate_y = 0, rate_uv = 0;
7204 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
7205 int skippable = 0;
7206 int i;
7207 int this_skip2 = 0;
7208 int64_t total_sse = INT_MAX;
7209 int early_term = 0;
7210
7211 ref_frame = vp10_ref_order[ref_index].ref_frame[0];
7212 second_ref_frame = vp10_ref_order[ref_index].ref_frame[1];
7213
7214 // Look at the reference frame of the best mode so far and set the
7215 // skip mask to look at a subset of the remaining modes.
7216 if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
7217 if (ref_index == 3) {
7218 switch (best_mbmode.ref_frame[0]) {
7219 case INTRA_FRAME:
7220 break;
7221 case LAST_FRAME:
Zoe Liu3ec16012015-11-12 02:12:17 -08007222 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
7223#if CONFIG_EXT_REFS
7224 (1 << LAST2_FRAME) |
7225 (1 << LAST3_FRAME) |
7226 (1 << LAST4_FRAME) |
7227#endif // CONFIG_EXT_REFS
7228 (1 << ALTREF_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07007229 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7230 break;
Zoe Liu3ec16012015-11-12 02:12:17 -08007231#if CONFIG_EXT_REFS
7232 case LAST2_FRAME:
7233 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
7234 (1 << LAST3_FRAME) |
7235 (1 << LAST4_FRAME) |
7236 (1 << GOLDEN_FRAME) |
7237 (1 << ALTREF_FRAME);
7238 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7239 break;
7240 case LAST3_FRAME:
7241 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
7242 (1 << LAST2_FRAME) |
7243 (1 << LAST4_FRAME) |
7244 (1 << GOLDEN_FRAME) |
7245 (1 << ALTREF_FRAME);
7246 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7247 break;
7248 case LAST4_FRAME:
7249 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
7250 (1 << LAST2_FRAME) |
7251 (1 << LAST3_FRAME) |
7252 (1 << GOLDEN_FRAME) |
7253 (1 << ALTREF_FRAME);
7254 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7255 break;
7256#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07007257 case GOLDEN_FRAME:
Zoe Liu3ec16012015-11-12 02:12:17 -08007258 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
7259#if CONFIG_EXT_REFS
7260 (1 << LAST2_FRAME) |
7261 (1 << LAST3_FRAME) |
7262 (1 << LAST4_FRAME) |
7263#endif // CONFIG_EXT_REFS
7264 (1 << ALTREF_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07007265 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7266 break;
7267 case ALTREF_FRAME:
Zoe Liu3ec16012015-11-12 02:12:17 -08007268 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
7269#if CONFIG_EXT_REFS
7270 (1 << LAST2_FRAME) |
7271 (1 << LAST3_FRAME) |
7272 (1 << LAST4_FRAME) |
7273#endif // CONFIG_EXT_REFS
7274 (1 << LAST_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07007275 break;
7276 case NONE:
7277 case MAX_REF_FRAMES:
7278 assert(0 && "Invalid Reference frame");
7279 break;
7280 }
7281 }
7282 }
7283
7284 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
James Zern5e16d392015-08-17 18:19:22 -07007285 (ref_frame_skip_mask[1] & (1 << VPXMAX(0, second_ref_frame))))
Jingning Han3ee6db62015-08-05 19:00:31 -07007286 continue;
7287
7288 // Test best rd so far against threshold for trying this mode.
7289 if (!internal_active_edge &&
7290 rd_less_than_thresh(best_rd,
7291 rd_opt->threshes[segment_id][bsize][ref_index],
7292 tile_data->thresh_freq_fact[bsize][ref_index]))
7293 continue;
7294
7295 comp_pred = second_ref_frame > INTRA_FRAME;
7296 if (comp_pred) {
7297 if (!cpi->allow_comp_inter_inter)
7298 continue;
7299 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
7300 continue;
7301 // Do not allow compound prediction if the segment level reference frame
7302 // feature is in use as in this case there can only be one reference.
7303 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
7304 continue;
7305
7306 if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
7307 best_mbmode.ref_frame[0] == INTRA_FRAME)
7308 continue;
7309 }
7310
7311 // TODO(jingning, jkoleszar): scaling reference frame not supported for
7312 // sub8x8 blocks.
7313 if (ref_frame > INTRA_FRAME &&
7314 vp10_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
7315 continue;
7316
7317 if (second_ref_frame > INTRA_FRAME &&
7318 vp10_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
7319 continue;
7320
7321 if (comp_pred)
7322 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
7323 else if (ref_frame != INTRA_FRAME)
7324 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
7325
7326 // If the segment reference frame feature is enabled....
7327 // then do nothing if the current ref frame is not allowed..
7328 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
7329 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
7330 continue;
7331 // Disable this drop out case if the ref frame
7332 // segment level feature is enabled for this segment. This is to
7333 // prevent the possibility that we end up unable to pick any mode.
7334 } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
7335 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
7336 // unless ARNR filtering is enabled in which case we want
7337 // an unfiltered alternative. We allow near/nearest as well
7338 // because they may result in zero-zero MVs but be cheaper.
7339 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
7340 continue;
7341 }
7342
7343 mbmi->tx_size = TX_4X4;
7344 mbmi->uv_mode = DC_PRED;
7345 mbmi->ref_frame[0] = ref_frame;
7346 mbmi->ref_frame[1] = second_ref_frame;
7347 // Evaluate all sub-pel filters irrespective of whether we can use
7348 // them for this frame.
7349 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP
7350 : cm->interp_filter;
7351 x->skip = 0;
7352 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
7353
7354 // Select prediction reference frames.
7355 for (i = 0; i < MAX_MB_PLANE; i++) {
7356 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
7357 if (comp_pred)
7358 xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
7359 }
7360
Jingning Han704985e2015-10-08 12:05:03 -07007361#if CONFIG_VAR_TX
Jingning Han0f34e352015-11-15 20:52:51 -08007362 mbmi->inter_tx_size[0] = mbmi->tx_size;
Jingning Han704985e2015-10-08 12:05:03 -07007363#endif
7364
Jingning Han3ee6db62015-08-05 19:00:31 -07007365 if (ref_frame == INTRA_FRAME) {
7366 int rate;
7367 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y,
7368 &distortion_y, best_rd) >= best_rd)
7369 continue;
7370 rate2 += rate;
7371 rate2 += intra_cost_penalty;
7372 distortion2 += distortion_y;
7373
7374 if (rate_uv_intra == INT_MAX) {
7375 choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4,
7376 &rate_uv_intra,
7377 &rate_uv_tokenonly,
7378 &dist_uv, &skip_uv,
7379 &mode_uv);
7380 }
7381 rate2 += rate_uv_intra;
7382 rate_uv = rate_uv_tokenonly;
7383 distortion2 += dist_uv;
7384 distortion_uv = dist_uv;
7385 mbmi->uv_mode = mode_uv;
7386 } else {
7387 int rate;
7388 int64_t distortion;
7389 int64_t this_rd_thresh;
7390 int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
7391 int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
7392 int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
7393 int tmp_best_skippable = 0;
7394 int switchable_filter_index;
7395 int_mv *second_ref = comp_pred ?
7396 &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL;
7397 b_mode_info tmp_best_bmodes[16];
7398 MB_MODE_INFO tmp_best_mbmode;
7399 BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
7400 int pred_exists = 0;
7401 int uv_skippable;
Yue Chen1ac85872016-01-07 15:13:52 -08007402#if CONFIG_EXT_INTER
7403 int_mv compound_seg_newmvs[4][2];
7404 int i;
7405
7406 for (i = 0; i < 4; i++) {
7407 compound_seg_newmvs[i][0].as_int = INVALID_MV;
7408 compound_seg_newmvs[i][1].as_int = INVALID_MV;
7409 }
7410#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007411
7412 this_rd_thresh = (ref_frame == LAST_FRAME) ?
7413 rd_opt->threshes[segment_id][bsize][THR_LAST] :
7414 rd_opt->threshes[segment_id][bsize][THR_ALTR];
Zoe Liu3ec16012015-11-12 02:12:17 -08007415#if CONFIG_EXT_REFS
7416 this_rd_thresh = (ref_frame == LAST2_FRAME) ?
7417 rd_opt->threshes[segment_id][bsize][THR_LAST2] : this_rd_thresh;
7418 this_rd_thresh = (ref_frame == LAST3_FRAME) ?
7419 rd_opt->threshes[segment_id][bsize][THR_LAST3] : this_rd_thresh;
7420 this_rd_thresh = (ref_frame == LAST4_FRAME) ?
7421 rd_opt->threshes[segment_id][bsize][THR_LAST4] : this_rd_thresh;
7422#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07007423 this_rd_thresh = (ref_frame == GOLDEN_FRAME) ?
Zoe Liu3ec16012015-11-12 02:12:17 -08007424 rd_opt->threshes[segment_id][bsize][THR_GOLD] : this_rd_thresh;
Jingning Han3ee6db62015-08-05 19:00:31 -07007425 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
7426 filter_cache[i] = INT64_MAX;
7427
Debargha Mukherjeed46c1f22016-02-08 15:59:17 -08007428 // TODO(any): Add search of the tx_type to improve rd performance at the
7429 // expense of speed.
7430 mbmi->tx_type = DCT_DCT;
7431
Jingning Han3ee6db62015-08-05 19:00:31 -07007432 if (cm->interp_filter != BILINEAR) {
7433 tmp_best_filter = EIGHTTAP;
7434 if (x->source_variance < sf->disable_filter_search_var_thresh) {
7435 tmp_best_filter = EIGHTTAP;
7436 } else if (sf->adaptive_pred_interp_filter == 1 &&
7437 ctx->pred_interp_filter < SWITCHABLE) {
7438 tmp_best_filter = ctx->pred_interp_filter;
7439 } else if (sf->adaptive_pred_interp_filter == 2) {
7440 tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE ?
7441 ctx->pred_interp_filter : 0;
7442 } else {
7443 for (switchable_filter_index = 0;
7444 switchable_filter_index < SWITCHABLE_FILTERS;
7445 ++switchable_filter_index) {
7446 int newbest, rs;
7447 int64_t rs_rd;
7448 MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
7449 mbmi->interp_filter = switchable_filter_index;
7450 tmp_rd = rd_pick_best_sub8x8_mode(cpi, x,
7451 &mbmi_ext->ref_mvs[ref_frame][0],
7452 second_ref, best_yrd, &rate,
7453 &rate_y, &distortion,
7454 &skippable, &total_sse,
7455 (int) this_rd_thresh, seg_mvs,
Yue Chen1ac85872016-01-07 15:13:52 -08007456#if CONFIG_EXT_INTER
7457 compound_seg_newmvs,
7458#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007459 bsi, switchable_filter_index,
7460 mi_row, mi_col);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07007461#if CONFIG_EXT_INTERP
7462 if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
7463 mbmi->interp_filter != EIGHTTAP) // invalid configuration
7464 continue;
7465#endif // CONFIG_EXT_INTERP
Jingning Han3ee6db62015-08-05 19:00:31 -07007466 if (tmp_rd == INT64_MAX)
7467 continue;
7468 rs = vp10_get_switchable_rate(cpi, xd);
7469 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
7470 filter_cache[switchable_filter_index] = tmp_rd;
7471 filter_cache[SWITCHABLE_FILTERS] =
James Zern5e16d392015-08-17 18:19:22 -07007472 VPXMIN(filter_cache[SWITCHABLE_FILTERS], tmp_rd + rs_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07007473 if (cm->interp_filter == SWITCHABLE)
7474 tmp_rd += rs_rd;
7475
James Zern5e16d392015-08-17 18:19:22 -07007476 mask_filter = VPXMAX(mask_filter, tmp_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07007477
7478 newbest = (tmp_rd < tmp_best_rd);
7479 if (newbest) {
7480 tmp_best_filter = mbmi->interp_filter;
7481 tmp_best_rd = tmp_rd;
7482 }
7483 if ((newbest && cm->interp_filter == SWITCHABLE) ||
7484 (mbmi->interp_filter == cm->interp_filter &&
7485 cm->interp_filter != SWITCHABLE)) {
7486 tmp_best_rdu = tmp_rd;
7487 tmp_best_rate = rate;
7488 tmp_best_ratey = rate_y;
7489 tmp_best_distortion = distortion;
7490 tmp_best_sse = total_sse;
7491 tmp_best_skippable = skippable;
7492 tmp_best_mbmode = *mbmi;
7493 for (i = 0; i < 4; i++) {
7494 tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
7495 x->zcoeff_blk[TX_4X4][i] = !x->plane[0].eobs[i];
7496 }
7497 pred_exists = 1;
7498 if (switchable_filter_index == 0 &&
7499 sf->use_rd_breakout &&
7500 best_rd < INT64_MAX) {
7501 if (tmp_best_rdu / 2 > best_rd) {
7502 // skip searching the other filters if the first is
7503 // already substantially larger than the best so far
7504 tmp_best_filter = mbmi->interp_filter;
7505 tmp_best_rdu = INT64_MAX;
7506 break;
7507 }
7508 }
7509 }
7510 } // switchable_filter_index loop
7511 }
7512 }
7513
7514 if (tmp_best_rdu == INT64_MAX && pred_exists)
7515 continue;
7516
7517 mbmi->interp_filter = (cm->interp_filter == SWITCHABLE ?
7518 tmp_best_filter : cm->interp_filter);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07007519
Jingning Han3ee6db62015-08-05 19:00:31 -07007520 if (!pred_exists) {
7521 // Handles the special case when a filter that is not in the
Debargha Mukherjee85514c42015-10-30 09:19:36 -07007522 // switchable list (bilinear) is indicated at the frame level
Jingning Han3ee6db62015-08-05 19:00:31 -07007523 tmp_rd = rd_pick_best_sub8x8_mode(cpi, x,
7524 &x->mbmi_ext->ref_mvs[ref_frame][0],
7525 second_ref, best_yrd, &rate, &rate_y,
7526 &distortion, &skippable, &total_sse,
Yue Chen1ac85872016-01-07 15:13:52 -08007527 (int) this_rd_thresh, seg_mvs,
7528#if CONFIG_EXT_INTER
7529 compound_seg_newmvs,
7530#endif // CONFIG_EXT_INTER
7531 bsi, 0,
Jingning Han3ee6db62015-08-05 19:00:31 -07007532 mi_row, mi_col);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07007533#if CONFIG_EXT_INTERP
7534 if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
7535 mbmi->interp_filter != EIGHTTAP) {
7536 mbmi->interp_filter = EIGHTTAP;
Yue Chen1ac85872016-01-07 15:13:52 -08007537 tmp_rd = rd_pick_best_sub8x8_mode(cpi, x,
7538 &x->mbmi_ext->ref_mvs[ref_frame][0],
7539 second_ref, best_yrd, &rate, &rate_y,
7540 &distortion, &skippable, &total_sse,
7541 (int) this_rd_thresh, seg_mvs,
7542#if CONFIG_EXT_INTER
7543 compound_seg_newmvs,
7544#endif // CONFIG_EXT_INTER
7545 bsi, 0,
7546 mi_row, mi_col);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07007547 }
7548#endif // CONFIG_EXT_INTERP
Jingning Han3ee6db62015-08-05 19:00:31 -07007549 if (tmp_rd == INT64_MAX)
7550 continue;
7551 } else {
7552 total_sse = tmp_best_sse;
7553 rate = tmp_best_rate;
7554 rate_y = tmp_best_ratey;
7555 distortion = tmp_best_distortion;
7556 skippable = tmp_best_skippable;
7557 *mbmi = tmp_best_mbmode;
7558 for (i = 0; i < 4; i++)
7559 xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
7560 }
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08007561 // Add in the cost of the transform type
7562 if (!xd->lossless[mbmi->segment_id]) {
7563 int rate_tx_type = 0;
7564#if CONFIG_EXT_TX
7565 if (get_ext_tx_types(mbmi->tx_size, bsize, 1) > 1) {
7566 const int eset = get_ext_tx_set(mbmi->tx_size, bsize, 1);
7567 rate_tx_type =
7568 cpi->inter_tx_type_costs[eset][mbmi->tx_size][mbmi->tx_type];
7569 }
7570#else
7571 if (mbmi->tx_size < TX_32X32) {
7572 rate_tx_type = cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
7573 }
7574#endif
7575 rate += rate_tx_type;
7576 rate_y += rate_tx_type;
7577 }
Jingning Han3ee6db62015-08-05 19:00:31 -07007578
7579 rate2 += rate;
7580 distortion2 += distortion;
7581
7582 if (cm->interp_filter == SWITCHABLE)
7583 rate2 += vp10_get_switchable_rate(cpi, xd);
7584
7585 if (!mode_excluded)
7586 mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
7587 : cm->reference_mode == COMPOUND_REFERENCE;
7588
7589 compmode_cost = vp10_cost_bit(comp_mode_p, comp_pred);
7590
7591 tmp_best_rdu = best_rd -
James Zern5e16d392015-08-17 18:19:22 -07007592 VPXMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
7593 RDCOST(x->rdmult, x->rddiv, 0, total_sse));
Jingning Han3ee6db62015-08-05 19:00:31 -07007594
7595 if (tmp_best_rdu > 0) {
7596 // If even the 'Y' rd value of split is higher than best so far
7597 // then dont bother looking at UV
7598 vp10_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col,
7599 BLOCK_8X8);
7600 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
Jingning Hana8dad552015-10-08 16:46:10 -07007601#if CONFIG_VAR_TX
7602 if (!inter_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
7603 &uv_sse, BLOCK_8X8, tmp_best_rdu))
7604 continue;
7605#else
Jingning Han3ee6db62015-08-05 19:00:31 -07007606 if (!super_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
7607 &uv_sse, BLOCK_8X8, tmp_best_rdu))
7608 continue;
Jingning Hana8dad552015-10-08 16:46:10 -07007609#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07007610 rate2 += rate_uv;
7611 distortion2 += distortion_uv;
7612 skippable = skippable && uv_skippable;
7613 total_sse += uv_sse;
7614 }
7615 }
7616
7617 if (cm->reference_mode == REFERENCE_MODE_SELECT)
7618 rate2 += compmode_cost;
7619
7620 // Estimate the reference frame signaling cost and add it
7621 // to the rolling cost variable.
7622 if (second_ref_frame > INTRA_FRAME) {
7623 rate2 += ref_costs_comp[ref_frame];
7624 } else {
7625 rate2 += ref_costs_single[ref_frame];
7626 }
7627
7628 if (!disable_skip) {
7629 // Skip is never coded at the segment level for sub8x8 blocks and instead
7630 // always coded in the bitstream at the mode info level.
7631
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04007632 if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Jingning Han3ee6db62015-08-05 19:00:31 -07007633 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
7634 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
7635 // Add in the cost of the no skip flag.
7636 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
7637 } else {
7638 // FIXME(rbultje) make this work for splitmv also
7639 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
7640 distortion2 = total_sse;
7641 assert(total_sse >= 0);
7642 rate2 -= (rate_y + rate_uv);
7643 rate_y = 0;
7644 rate_uv = 0;
7645 this_skip2 = 1;
7646 }
7647 } else {
7648 // Add in the cost of the no skip flag.
7649 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
7650 }
7651
7652 // Calculate the final RD estimate for this mode.
7653 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
7654 }
7655
7656 if (!disable_skip && ref_frame == INTRA_FRAME) {
7657 for (i = 0; i < REFERENCE_MODES; ++i)
James Zern5e16d392015-08-17 18:19:22 -07007658 best_pred_rd[i] = VPXMIN(best_pred_rd[i], this_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07007659 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
James Zern5e16d392015-08-17 18:19:22 -07007660 best_filter_rd[i] = VPXMIN(best_filter_rd[i], this_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07007661 }
7662
7663 // Did this mode help.. i.e. is it the new best mode
7664 if (this_rd < best_rd || x->skip) {
7665 if (!mode_excluded) {
7666 int max_plane = MAX_MB_PLANE;
7667 // Note index of best mode so far
7668 best_ref_index = ref_index;
7669
7670 if (ref_frame == INTRA_FRAME) {
7671 /* required for left and above block mv */
7672 mbmi->mv[0].as_int = 0;
7673 max_plane = 1;
7674 }
7675
7676 rd_cost->rate = rate2;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08007677#if CONFIG_SUPERTX
7678 *returnrate_nocoef = rate2 - rate_y - rate_uv;
7679 if (!disable_skip)
7680 *returnrate_nocoef -= vp10_cost_bit(vp10_get_skip_prob(cm, xd),
7681 this_skip2);
7682 *returnrate_nocoef -= vp10_cost_bit(vp10_get_intra_inter_prob(cm, xd),
7683 mbmi->ref_frame[0] != INTRA_FRAME);
7684 assert(*returnrate_nocoef > 0);
7685#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07007686 rd_cost->dist = distortion2;
7687 rd_cost->rdcost = this_rd;
7688 best_rd = this_rd;
7689 best_yrd = best_rd -
7690 RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
7691 best_mbmode = *mbmi;
7692 best_skip2 = this_skip2;
7693 if (!x->select_tx_size)
7694 swap_block_ptr(x, ctx, 1, 0, 0, max_plane);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07007695
7696#if CONFIG_VAR_TX
7697 for (i = 0; i < MAX_MB_PLANE; ++i)
7698 memset(ctx->blk_skip[i], 0, sizeof(uint8_t) * ctx->num_4x4_blk);
7699#else
Jingning Han3ee6db62015-08-05 19:00:31 -07007700 memcpy(ctx->zcoeff_blk, x->zcoeff_blk[TX_4X4],
hui su088b05f2015-08-12 10:41:51 -07007701 sizeof(ctx->zcoeff_blk[0]) * ctx->num_4x4_blk);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07007702#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07007703
7704 for (i = 0; i < 4; i++)
7705 best_bmodes[i] = xd->mi[0]->bmi[i];
7706
7707 // TODO(debargha): enhance this test with a better distortion prediction
7708 // based on qp, activity mask and history
7709 if ((sf->mode_search_skip_flags & FLAG_EARLY_TERMINATE) &&
7710 (ref_index > MIN_EARLY_TERM_INDEX)) {
7711 int qstep = xd->plane[0].dequant[1];
7712 // TODO(debargha): Enhance this by specializing for each mode_index
7713 int scale = 4;
7714#if CONFIG_VP9_HIGHBITDEPTH
7715 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
7716 qstep >>= (xd->bd - 8);
7717 }
7718#endif // CONFIG_VP9_HIGHBITDEPTH
7719 if (x->source_variance < UINT_MAX) {
7720 const int var_adjust = (x->source_variance < 16);
7721 scale -= var_adjust;
7722 }
7723 if (ref_frame > INTRA_FRAME &&
7724 distortion2 * scale < qstep * qstep) {
7725 early_term = 1;
7726 }
7727 }
7728 }
7729 }
7730
7731 /* keep record of best compound/single-only prediction */
7732 if (!disable_skip && ref_frame != INTRA_FRAME) {
7733 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
7734
7735 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
7736 single_rate = rate2 - compmode_cost;
7737 hybrid_rate = rate2;
7738 } else {
7739 single_rate = rate2;
7740 hybrid_rate = rate2 + compmode_cost;
7741 }
7742
7743 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
7744 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
7745
7746 if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE])
7747 best_pred_rd[SINGLE_REFERENCE] = single_rd;
7748 else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE])
7749 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
7750
7751 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
7752 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
7753 }
7754
7755 /* keep record of best filter type */
7756 if (!mode_excluded && !disable_skip && ref_frame != INTRA_FRAME &&
7757 cm->interp_filter != BILINEAR) {
7758 int64_t ref = filter_cache[cm->interp_filter == SWITCHABLE ?
7759 SWITCHABLE_FILTERS : cm->interp_filter];
7760 int64_t adj_rd;
7761 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
7762 if (ref == INT64_MAX)
7763 adj_rd = 0;
7764 else if (filter_cache[i] == INT64_MAX)
7765 // when early termination is triggered, the encoder does not have
7766 // access to the rate-distortion cost. it only knows that the cost
7767 // should be above the maximum valid value. hence it takes the known
7768 // maximum plus an arbitrary constant as the rate-distortion cost.
7769 adj_rd = mask_filter - ref + 10;
7770 else
7771 adj_rd = filter_cache[i] - ref;
7772
7773 adj_rd += this_rd;
James Zern5e16d392015-08-17 18:19:22 -07007774 best_filter_rd[i] = VPXMIN(best_filter_rd[i], adj_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07007775 }
7776 }
7777
7778 if (early_term)
7779 break;
7780
7781 if (x->skip && !comp_pred)
7782 break;
7783 }
7784
7785 if (best_rd >= best_rd_so_far) {
7786 rd_cost->rate = INT_MAX;
7787 rd_cost->rdcost = INT64_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08007788#if CONFIG_SUPERTX
7789 *returnrate_nocoef = INT_MAX;
7790#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07007791 return;
7792 }
7793
7794 // If we used an estimate for the uv intra rd in the loop above...
7795 if (sf->use_uv_intra_rd_estimate) {
7796 // Do Intra UV best rd mode selection if best mode choice above was intra.
7797 if (best_mbmode.ref_frame[0] == INTRA_FRAME) {
7798 *mbmi = best_mbmode;
7799 rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra,
7800 &rate_uv_tokenonly,
7801 &dist_uv,
7802 &skip_uv,
7803 BLOCK_8X8, TX_4X4);
7804 }
7805 }
7806
7807 if (best_rd == INT64_MAX) {
7808 rd_cost->rate = INT_MAX;
7809 rd_cost->dist = INT64_MAX;
7810 rd_cost->rdcost = INT64_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08007811#if CONFIG_SUPERTX
7812 *returnrate_nocoef = INT_MAX;
7813#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07007814 return;
7815 }
7816
7817 assert((cm->interp_filter == SWITCHABLE) ||
7818 (cm->interp_filter == best_mbmode.interp_filter) ||
7819 !is_inter_block(&best_mbmode));
7820
7821 vp10_update_rd_thresh_fact(tile_data->thresh_freq_fact,
7822 sf->adaptive_rd_thresh, bsize, best_ref_index);
7823
7824 // macroblock modes
7825 *mbmi = best_mbmode;
7826 x->skip |= best_skip2;
7827 if (!is_inter_block(&best_mbmode)) {
7828 for (i = 0; i < 4; i++)
7829 xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
7830 } else {
7831 for (i = 0; i < 4; ++i)
7832 memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
7833
7834 mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
7835 mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
7836 }
7837
7838 for (i = 0; i < REFERENCE_MODES; ++i) {
7839 if (best_pred_rd[i] == INT64_MAX)
7840 best_pred_diff[i] = INT_MIN;
7841 else
7842 best_pred_diff[i] = best_rd - best_pred_rd[i];
7843 }
7844
7845 if (!x->skip) {
7846 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
7847 if (best_filter_rd[i] == INT64_MAX)
7848 best_filter_diff[i] = 0;
7849 else
7850 best_filter_diff[i] = best_rd - best_filter_rd[i];
7851 }
7852 if (cm->interp_filter == SWITCHABLE)
7853 assert(best_filter_diff[SWITCHABLE_FILTERS] == 0);
7854 } else {
7855 vp10_zero(best_filter_diff);
7856 }
7857
7858 store_coding_context(x, ctx, best_ref_index,
7859 best_pred_diff, best_filter_diff, 0);
7860}