blob: bfc0983a8405f1607cda548678c221e7d86f8a3c [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)
Alex Converseb3ad8122016-02-10 14:12:26 -0800414 rate = (square_error * (280 - quantizer)) >> (16 - VP9_PROB_COST_SHIFT);
Jingning Han3ee6db62015-08-05 19:00:31 -0700415 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
Alex Converseb3ad8122016-02-10 14:12:26 -0800526 const int *cat6_high_cost = vp10_get_high_cost_table(xd->bd);
Jingning Han3ee6db62015-08-05 19:00:31 -0700527#else
Alex Converseb3ad8122016-02-10 14:12:26 -0800528 const int *cat6_high_cost = vp10_get_high_cost_table(8);
Jingning Han3ee6db62015-08-05 19:00:31 -0700529#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 struct encode_b_args arg = {x, NULL, &mbmi->skip};
Geza Lore432e8752016-01-22 13:57:28 +0000656#if CONFIG_VAR_TX
Jingning Han71c15602015-10-13 12:40:39 -0700657 vp10_encode_block_intra(plane, block, blk_row, blk_col,
658 plane_bsize, tx_size, &arg);
Geza Loreabd00502016-02-12 16:04:35 +0000659
660 {
Yaowu Xu0c0f3ef2016-02-18 15:42:19 -0800661#if CONFIG_VP9_HIGHBITDEPTH
662 const VP10_COMP *cpi = args->cpi;
663 const uint32_t hbd_shift = (cpi->common.bit_depth - 8) * 2;
664#endif
Geza Loreabd00502016-02-12 16:04:35 +0000665 const int bs = 4 << tx_size;
666 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
667 const vpx_variance_fn_t variance = args->cpi->fn_ptr[tx_bsize].vf;
668
669 const struct macroblock_plane *const p = &x->plane[plane];
670 const struct macroblockd_plane *const pd = &xd->plane[plane];
671
672 const int src_stride = p->src.stride;
673 const int dst_stride = pd->dst.stride;
674 const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
675
676 const uint8_t *src = &p->src.buf[4 * (blk_row * src_stride + blk_col)];
677 const uint8_t *dst = &pd->dst.buf[4 * (blk_row * dst_stride + blk_col)];
678 const int16_t *diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
679
680 unsigned int tmp;
Yaowu Xu0c0f3ef2016-02-18 15:42:19 -0800681#if CONFIG_VP9_HIGHBITDEPTH
682 sse = (int64_t)ROUND_POWER_OF_TWO(
683 vpx_sum_squares_2d_i16(diff, diff_stride, bs), hbd_shift) * 16;
684#else
Geza Loreabd00502016-02-12 16:04:35 +0000685 sse = (int64_t)vpx_sum_squares_2d_i16(diff, diff_stride, bs) * 16;
Yaowu Xu0c0f3ef2016-02-18 15:42:19 -0800686#endif
Geza Loreabd00502016-02-12 16:04:35 +0000687 variance(src, src_stride, dst, dst_stride, &tmp);
688 dist = (int64_t)tmp * 16;
689 }
Jingning Han71c15602015-10-13 12:40:39 -0700690#else
Jingning Hanebc48ef2015-10-07 11:43:48 -0700691 vp10_encode_block_intra(plane, block, blk_row, blk_col,
692 plane_bsize, tx_size, &arg);
Jingning Han3ee6db62015-08-05 19:00:31 -0700693 dist_block(x, plane, block, tx_size, &dist, &sse);
Jingning Han71c15602015-10-13 12:40:39 -0700694#endif
Jingning Han3ee6db62015-08-05 19:00:31 -0700695 } else if (max_txsize_lookup[plane_bsize] == tx_size) {
696 if (x->skip_txfm[(plane << 2) + (block >> (tx_size << 1))] ==
697 SKIP_TXFM_NONE) {
698 // full forward transform and quantization
Jingning Hancaeb10b2015-10-22 17:25:00 -0700699 vp10_xform_quant(x, plane, block, blk_row, blk_col,
Angie Chiang88cae8b2015-11-25 13:07:13 -0800700 plane_bsize, tx_size, VP10_XFORM_QUANT_B);
Jingning Han3ee6db62015-08-05 19:00:31 -0700701 dist_block(x, plane, block, tx_size, &dist, &sse);
702 } else if (x->skip_txfm[(plane << 2) + (block >> (tx_size << 1))] ==
703 SKIP_TXFM_AC_ONLY) {
704 // compute DC coefficient
705 tran_low_t *const coeff = BLOCK_OFFSET(x->plane[plane].coeff, block);
706 tran_low_t *const dqcoeff = BLOCK_OFFSET(xd->plane[plane].dqcoeff, block);
Angie Chiang88cae8b2015-11-25 13:07:13 -0800707 vp10_xform_quant(x, plane, block, blk_row, blk_col,
708 plane_bsize, tx_size, VP10_XFORM_QUANT_DC);
Jingning Han3ee6db62015-08-05 19:00:31 -0700709 sse = x->bsse[(plane << 2) + (block >> (tx_size << 1))] << 4;
710 dist = sse;
711 if (x->plane[plane].eobs[block]) {
712 const int64_t orig_sse = (int64_t)coeff[0] * coeff[0];
713 const int64_t resd_sse = coeff[0] - dqcoeff[0];
714 int64_t dc_correct = orig_sse - resd_sse * resd_sse;
715#if CONFIG_VP9_HIGHBITDEPTH
716 dc_correct >>= ((xd->bd - 8) * 2);
717#endif
718 if (tx_size != TX_32X32)
719 dc_correct >>= 2;
720
James Zern5e16d392015-08-17 18:19:22 -0700721 dist = VPXMAX(0, sse - dc_correct);
Jingning Han3ee6db62015-08-05 19:00:31 -0700722 }
723 } else {
724 // SKIP_TXFM_AC_DC
725 // skip forward transform
726 x->plane[plane].eobs[block] = 0;
727 sse = x->bsse[(plane << 2) + (block >> (tx_size << 1))] << 4;
728 dist = sse;
729 }
730 } else {
731 // full forward transform and quantization
Angie Chiang88cae8b2015-11-25 13:07:13 -0800732 vp10_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
733 VP10_XFORM_QUANT_B);
Jingning Han3ee6db62015-08-05 19:00:31 -0700734 dist_block(x, plane, block, tx_size, &dist, &sse);
735 }
736
737 rd = RDCOST(x->rdmult, x->rddiv, 0, dist);
738 if (args->this_rd + rd > args->best_rd) {
739 args->exit_early = 1;
740 return;
741 }
742
Jingning Hanebc48ef2015-10-07 11:43:48 -0700743 rate = rate_block(plane, block, blk_row, blk_col, tx_size, args);
Jingning Han3ee6db62015-08-05 19:00:31 -0700744 rd1 = RDCOST(x->rdmult, x->rddiv, rate, dist);
745 rd2 = RDCOST(x->rdmult, x->rddiv, 0, sse);
746
747 // TODO(jingning): temporarily enabled only for luma component
James Zern5e16d392015-08-17 18:19:22 -0700748 rd = VPXMIN(rd1, rd2);
Jingning Han3ee6db62015-08-05 19:00:31 -0700749 if (plane == 0)
750 x->zcoeff_blk[tx_size][block] = !x->plane[plane].eobs[block] ||
Ronald S. Bultje60c58b52015-10-12 17:54:25 -0400751 (rd1 > rd2 && !xd->lossless[mbmi->segment_id]);
Jingning Han3ee6db62015-08-05 19:00:31 -0700752
753 args->this_rate += rate;
754 args->this_dist += dist;
755 args->this_sse += sse;
756 args->this_rd += rd;
757
758 if (args->this_rd > args->best_rd) {
759 args->exit_early = 1;
760 return;
761 }
762
763 args->skippable &= !x->plane[plane].eobs[block];
764}
765
766static void txfm_rd_in_plane(MACROBLOCK *x,
Jingning Han71c15602015-10-13 12:40:39 -0700767#if CONFIG_VAR_TX
768 const VP10_COMP *cpi,
769#endif
Jingning Han3ee6db62015-08-05 19:00:31 -0700770 int *rate, int64_t *distortion,
771 int *skippable, int64_t *sse,
772 int64_t ref_best_rd, int plane,
773 BLOCK_SIZE bsize, TX_SIZE tx_size,
774 int use_fast_coef_casting) {
775 MACROBLOCKD *const xd = &x->e_mbd;
776 const struct macroblockd_plane *const pd = &xd->plane[plane];
hui su5eed74e2015-08-18 16:57:07 -0700777 TX_TYPE tx_type;
Jingning Han3ee6db62015-08-05 19:00:31 -0700778 struct rdcost_block_args args;
779 vp10_zero(args);
780 args.x = x;
Jingning Han71c15602015-10-13 12:40:39 -0700781#if CONFIG_VAR_TX
782 args.cpi = cpi;
783#endif
Jingning Han3ee6db62015-08-05 19:00:31 -0700784 args.best_rd = ref_best_rd;
785 args.use_fast_coef_costing = use_fast_coef_casting;
786 args.skippable = 1;
787
788 if (plane == 0)
789 xd->mi[0]->mbmi.tx_size = tx_size;
790
791 vp10_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
792
hui sub3cc3a02015-08-24 14:37:54 -0700793 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -0700794 args.so = get_scan(tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Jingning Han3ee6db62015-08-05 19:00:31 -0700795
796 vp10_foreach_transformed_block_in_plane(xd, bsize, plane,
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -0700797 block_rd_txfm, &args);
Jingning Han3ee6db62015-08-05 19:00:31 -0700798 if (args.exit_early) {
799 *rate = INT_MAX;
800 *distortion = INT64_MAX;
801 *sse = INT64_MAX;
802 *skippable = 0;
803 } else {
804 *distortion = args.this_dist;
805 *rate = args.this_rate;
806 *sse = args.this_sse;
807 *skippable = args.skippable;
808 }
809}
810
Debargha Mukherjee3787b172015-11-19 16:51:16 -0800811#if CONFIG_SUPERTX
812void vp10_txfm_rd_in_plane_supertx(MACROBLOCK *x,
Debargha Mukherjee3787b172015-11-19 16:51:16 -0800813 int *rate, int64_t *distortion,
814 int *skippable, int64_t *sse,
815 int64_t ref_best_rd, int plane,
816 BLOCK_SIZE bsize, TX_SIZE tx_size,
817 int use_fast_coef_casting) {
818 MACROBLOCKD *const xd = &x->e_mbd;
819 const struct macroblockd_plane *const pd = &xd->plane[plane];
820 struct rdcost_block_args args;
821 TX_TYPE tx_type;
822
823 vp10_zero(args);
824 args.x = x;
Debargha Mukherjee3787b172015-11-19 16:51:16 -0800825 args.best_rd = ref_best_rd;
826 args.use_fast_coef_costing = use_fast_coef_casting;
827
828 if (plane == 0)
829 xd->mi[0]->mbmi.tx_size = tx_size;
830
831 vp10_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
832
833 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
834 args.so = get_scan(tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
835
836 block_rd_txfm(plane, 0, 0, 0, get_plane_block_size(bsize, pd),
837 tx_size, &args);
838
839 if (args.exit_early) {
840 *rate = INT_MAX;
841 *distortion = INT64_MAX;
842 *sse = INT64_MAX;
843 *skippable = 0;
844 } else {
845 *distortion = args.this_dist;
846 *rate = args.this_rate;
847 *sse = args.this_sse;
848 *skippable = !x->plane[plane].eobs[0];
849 }
850}
851#endif // CONFIG_SUPERTX
852
Yaowu Xu26a9afc2015-08-13 09:42:27 -0700853static void choose_largest_tx_size(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -0700854 int *rate, int64_t *distortion,
855 int *skip, int64_t *sse,
856 int64_t ref_best_rd,
857 BLOCK_SIZE bs) {
858 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
Yaowu Xufc7cbd12015-08-13 09:36:53 -0700859 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -0700860 const TX_SIZE largest_tx_size = tx_mode_to_biggest_tx_size[cm->tx_mode];
861 MACROBLOCKD *const xd = &x->e_mbd;
862 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700863 TX_TYPE tx_type, best_tx_type = DCT_DCT;
hui su6c81e372015-09-29 12:09:15 -0700864 int r, s;
865 int64_t d, psse, this_rd, best_rd = INT64_MAX;
866 vpx_prob skip_prob = vp10_get_skip_prob(cm, xd);
867 int s0 = vp10_cost_bit(skip_prob, 0);
868 int s1 = vp10_cost_bit(skip_prob, 1);
Yaowu Xu0367f322016-01-11 10:27:35 -0800869#if CONFIG_EXT_TX
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700870 int ext_tx_set;
hui su6c81e372015-09-29 12:09:15 -0700871#endif // CONFIG_EXT_TX
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -0800872 const int is_inter = is_inter_block(mbmi);
Jingning Han3ee6db62015-08-05 19:00:31 -0700873
James Zern5e16d392015-08-17 18:19:22 -0700874 mbmi->tx_size = VPXMIN(max_tx_size, largest_tx_size);
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700875
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -0700876#if CONFIG_EXT_TX
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700877 ext_tx_set = get_ext_tx_set(mbmi->tx_size, bs, is_inter);
878
Debargha Mukherjee8d69a6e2016-01-06 14:36:13 -0800879 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1 &&
Yaowu Xu5a27b3b2015-10-22 12:18:52 -0700880 !xd->lossless[mbmi->segment_id]) {
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700881 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
882 if (is_inter) {
883 if (!ext_tx_used_inter[ext_tx_set][tx_type])
884 continue;
885 } else {
hui sud894d342015-11-18 11:24:26 -0800886 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
Yaowu Xu0367f322016-01-11 10:27:35 -0800887 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode])
hui sud894d342015-11-18 11:24:26 -0800888 continue;
889 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700890 if (!ext_tx_used_intra[ext_tx_set][tx_type])
891 continue;
892 }
893
894 mbmi->tx_type = tx_type;
895 if (ext_tx_set == 1 &&
896 mbmi->tx_type >= DST_ADST && mbmi->tx_type < IDTX &&
hui su4f16f112015-10-02 10:45:27 -0700897 best_tx_type == DCT_DCT) {
898 tx_type = IDTX - 1;
hui su3fa01292015-09-28 18:38:00 -0700899 continue;
900 }
hui su6c81e372015-09-29 12:09:15 -0700901
Jingning Han71c15602015-10-13 12:40:39 -0700902 txfm_rd_in_plane(x,
903#if CONFIG_VAR_TX
904 cpi,
905#endif
906 &r, &d, &s,
hui su6c81e372015-09-29 12:09:15 -0700907 &psse, ref_best_rd, 0, bs, mbmi->tx_size,
908 cpi->sf.use_fast_coef_costing);
909
910 if (r == INT_MAX)
911 continue;
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700912 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1) {
913 if (is_inter) {
914 if (ext_tx_set > 0)
915 r += cpi->inter_tx_type_costs[ext_tx_set]
916 [mbmi->tx_size][mbmi->tx_type];
917 } else {
hui sud894d342015-11-18 11:24:26 -0800918 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700919 r += cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size]
920 [mbmi->mode][mbmi->tx_type];
921 }
hui su3fa01292015-09-28 18:38:00 -0700922 }
hui su6c81e372015-09-29 12:09:15 -0700923
924 if (s)
925 this_rd = RDCOST(x->rdmult, x->rddiv, s1, psse);
926 else
927 this_rd = RDCOST(x->rdmult, x->rddiv, r + s0, d);
Yaowu Xu5a27b3b2015-10-22 12:18:52 -0700928 if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] && !s)
hui su6c81e372015-09-29 12:09:15 -0700929 this_rd = VPXMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, psse));
930
hui su4f16f112015-10-02 10:45:27 -0700931 if (this_rd < ((best_tx_type == DCT_DCT) ? ext_tx_th : 1) * best_rd) {
hui su6c81e372015-09-29 12:09:15 -0700932 best_rd = this_rd;
hui su4f16f112015-10-02 10:45:27 -0700933 best_tx_type = mbmi->tx_type;
hui su6c81e372015-09-29 12:09:15 -0700934 }
935 }
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -0700936 }
hui su6c81e372015-09-29 12:09:15 -0700937
Yaowu Xu0367f322016-01-11 10:27:35 -0800938#else // CONFIG_EXT_TX
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -0800939 if (mbmi->tx_size < TX_32X32 &&
940 !xd->lossless[mbmi->segment_id]) {
941 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
942 mbmi->tx_type = tx_type;
Yaowu Xu0367f322016-01-11 10:27:35 -0800943 txfm_rd_in_plane(x,
944#if CONFIG_VAR_TX
945 cpi,
946#endif
947 &r, &d, &s,
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -0800948 &psse, ref_best_rd, 0, bs, mbmi->tx_size,
949 cpi->sf.use_fast_coef_costing);
950 if (r == INT_MAX)
951 continue;
952 if (is_inter)
953 r += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
954 else
955 r += cpi->intra_tx_type_costs[mbmi->tx_size]
956 [intra_mode_to_tx_type_context[mbmi->mode]]
957 [mbmi->tx_type];
958 if (s)
959 this_rd = RDCOST(x->rdmult, x->rddiv, s1, psse);
960 else
961 this_rd = RDCOST(x->rdmult, x->rddiv, r + s0, d);
962 if (is_inter && !xd->lossless[mbmi->segment_id] && !s)
963 this_rd = VPXMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, psse));
964
965 if (this_rd < ((best_tx_type == DCT_DCT) ? ext_tx_th : 1) * best_rd) {
966 best_rd = this_rd;
967 best_tx_type = mbmi->tx_type;
968 }
969 }
970 }
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -0700971#endif // CONFIG_EXT_TX
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -0800972 mbmi->tx_type = best_tx_type;
Jingning Han3ee6db62015-08-05 19:00:31 -0700973
Jingning Han71c15602015-10-13 12:40:39 -0700974 txfm_rd_in_plane(x,
975#if CONFIG_VAR_TX
976 cpi,
977#endif
978 rate, distortion, skip,
Jingning Han3ee6db62015-08-05 19:00:31 -0700979 sse, ref_best_rd, 0, bs,
980 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -0700981
982#if CONFIG_EXT_TX
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700983 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1 &&
Yaowu Xu5a27b3b2015-10-22 12:18:52 -0700984 !xd->lossless[mbmi->segment_id] && *rate != INT_MAX) {
Debargha Mukherjee8a429242015-10-12 12:30:55 -0700985 int ext_tx_set = get_ext_tx_set(mbmi->tx_size, bs, is_inter);
hui sud894d342015-11-18 11:24:26 -0800986 if (is_inter) {
987 if (ext_tx_set > 0)
988 *rate += cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size]
Debargha Mukherjee8d69a6e2016-01-06 14:36:13 -0800989 [mbmi->tx_type];
hui sud894d342015-11-18 11:24:26 -0800990 } else {
991 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
992 *rate +=
993 cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size]
Debargha Mukherjee8d69a6e2016-01-06 14:36:13 -0800994 [mbmi->mode][mbmi->tx_type];
hui sud894d342015-11-18 11:24:26 -0800995 }
hui su3fa01292015-09-28 18:38:00 -0700996 }
Yaowu Xu0367f322016-01-11 10:27:35 -0800997#else
Debargha Mukherjeea0900fd2016-01-08 12:01:51 -0800998 if (mbmi->tx_size < TX_32X32 && !xd->lossless[mbmi->segment_id] &&
999 *rate != INT_MAX) {
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001000 if (is_inter)
1001 *rate += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
1002 else
1003 *rate += cpi->intra_tx_type_costs[mbmi->tx_size]
1004 [intra_mode_to_tx_type_context[mbmi->mode]]
1005 [mbmi->tx_type];
1006 }
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001007#endif // CONFIG_EXT_TX
Jingning Han3ee6db62015-08-05 19:00:31 -07001008}
1009
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001010static void choose_smallest_tx_size(VP10_COMP *cpi, MACROBLOCK *x,
1011 int *rate, int64_t *distortion,
1012 int *skip, int64_t *sse,
1013 int64_t ref_best_rd,
1014 BLOCK_SIZE bs) {
1015 MACROBLOCKD *const xd = &x->e_mbd;
1016 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1017
1018 mbmi->tx_size = TX_4X4;
Debargha Mukherjee4e406f72016-01-22 03:29:39 -08001019 mbmi->tx_type = DCT_DCT;
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001020
Jingning Han71c15602015-10-13 12:40:39 -07001021 txfm_rd_in_plane(x,
1022#if CONFIG_VAR_TX
1023 cpi,
1024#endif
1025 rate, distortion, skip,
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001026 sse, ref_best_rd, 0, bs,
1027 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
1028}
1029
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08001030static INLINE int vp10_cost_tx_size(TX_SIZE tx_size, TX_SIZE max_tx_size,
1031 const vpx_prob *tx_probs) {
1032 int m;
1033 int r_tx_size = 0;
1034
1035 for (m = 0; m <= tx_size - (tx_size == max_tx_size); ++m) {
1036 if (m == tx_size)
1037 r_tx_size += vp10_cost_zero(tx_probs[m]);
1038 else
1039 r_tx_size += vp10_cost_one(tx_probs[m]);
1040 }
1041
1042 return r_tx_size;
1043}
1044
Yaowu Xu26a9afc2015-08-13 09:42:27 -07001045static void choose_tx_size_from_rd(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07001046 int *rate,
1047 int64_t *distortion,
1048 int *skip,
1049 int64_t *psse,
1050 int64_t ref_best_rd,
1051 BLOCK_SIZE bs) {
1052 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
Yaowu Xufc7cbd12015-08-13 09:36:53 -07001053 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07001054 MACROBLOCKD *const xd = &x->e_mbd;
1055 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1056 vpx_prob skip_prob = vp10_get_skip_prob(cm, xd);
hui su38debe52015-09-20 19:18:00 -07001057 int r, s;
1058 int64_t d, sse;
1059 int64_t rd = INT64_MAX;
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08001060 int n;
Jingning Han3ee6db62015-08-05 19:00:31 -07001061 int s0, s1;
hui su38debe52015-09-20 19:18:00 -07001062 int64_t best_rd = INT64_MAX, last_rd = INT64_MAX;
Jingning Han3ee6db62015-08-05 19:00:31 -07001063 TX_SIZE best_tx = max_tx_size;
1064 int start_tx, end_tx;
hui su38debe52015-09-20 19:18:00 -07001065 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001066 TX_TYPE tx_type, best_tx_type = DCT_DCT;
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001067 const int is_inter = is_inter_block(mbmi);
Yaowu Xu0367f322016-01-11 10:27:35 -08001068#if CONFIG_EXT_TX
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001069 int ext_tx_set;
hui su07154b02015-09-22 10:34:18 -07001070#endif // CONFIG_EXT_TX
1071
Jingning Han3ee6db62015-08-05 19:00:31 -07001072 const vpx_prob *tx_probs = get_tx_probs2(max_tx_size, xd, &cm->fc->tx_probs);
1073 assert(skip_prob > 0);
1074 s0 = vp10_cost_bit(skip_prob, 0);
1075 s1 = vp10_cost_bit(skip_prob, 1);
1076
hui su38debe52015-09-20 19:18:00 -07001077 if (tx_select) {
Jingning Han3ee6db62015-08-05 19:00:31 -07001078 start_tx = max_tx_size;
1079 end_tx = 0;
1080 } else {
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001081 const TX_SIZE chosen_tx_size =
1082 VPXMIN(max_tx_size, tx_mode_to_biggest_tx_size[cm->tx_mode]);
Jingning Han3ee6db62015-08-05 19:00:31 -07001083 start_tx = chosen_tx_size;
1084 end_tx = chosen_tx_size;
1085 }
1086
hui su38debe52015-09-20 19:18:00 -07001087 *distortion = INT64_MAX;
1088 *rate = INT_MAX;
1089 *skip = 0;
1090 *psse = INT64_MAX;
1091
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001092 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001093 last_rd = INT64_MAX;
hui su07154b02015-09-22 10:34:18 -07001094 for (n = start_tx; n >= end_tx; --n) {
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08001095 const int r_tx_size = vp10_cost_tx_size(n, max_tx_size, tx_probs);
hui su329e3402016-02-10 10:52:14 -08001096 if (FIXED_TX_TYPE && tx_type != get_default_tx_type(0, xd, 0, n))
1097 continue;
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001098#if CONFIG_EXT_TX
1099 ext_tx_set = get_ext_tx_set(n, bs, is_inter);
1100 if (is_inter) {
1101 if (!ext_tx_used_inter[ext_tx_set][tx_type])
1102 continue;
1103 } else {
hui sud894d342015-11-18 11:24:26 -08001104 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
Yaowu Xu0367f322016-01-11 10:27:35 -08001105 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode])
hui sud894d342015-11-18 11:24:26 -08001106 continue;
1107 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001108 if (!ext_tx_used_intra[ext_tx_set][tx_type])
1109 continue;
1110 }
1111 mbmi->tx_type = tx_type;
1112 if (ext_tx_set == 1 &&
1113 mbmi->tx_type >= DST_ADST && mbmi->tx_type < IDTX &&
1114 best_tx_type == DCT_DCT) {
1115 tx_type = IDTX - 1;
1116 break;
1117 }
Jingning Han71c15602015-10-13 12:40:39 -07001118 txfm_rd_in_plane(x,
1119#if CONFIG_VAR_TX
1120 cpi,
1121#endif
1122 &r, &d, &s,
hui su07154b02015-09-22 10:34:18 -07001123 &sse, ref_best_rd, 0, bs, n,
1124 cpi->sf.use_fast_coef_costing);
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001125 if (get_ext_tx_types(n, bs, is_inter) > 1 &&
1126 !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1127 r != INT_MAX) {
1128 if (is_inter) {
1129 if (ext_tx_set > 0)
1130 r += cpi->inter_tx_type_costs[ext_tx_set]
1131 [mbmi->tx_size][mbmi->tx_type];
1132 } else {
hui sud894d342015-11-18 11:24:26 -08001133 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001134 r += cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size]
1135 [mbmi->mode][mbmi->tx_type];
1136 }
hui su3fa01292015-09-28 18:38:00 -07001137 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001138#else // CONFIG_EXT_TX
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001139 if (n >= TX_32X32 && tx_type != DCT_DCT) {
1140 continue;
1141 }
1142 mbmi->tx_type = tx_type;
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001143 txfm_rd_in_plane(x,
1144#if CONFIG_VAR_TX
1145 cpi,
1146#endif
1147 &r, &d, &s,
1148 &sse, ref_best_rd, 0, bs, n,
1149 cpi->sf.use_fast_coef_costing);
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001150 if (n < TX_32X32 &&
1151 !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
hui su329e3402016-02-10 10:52:14 -08001152 r != INT_MAX && !FIXED_TX_TYPE) {
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001153 if (is_inter)
1154 r += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
1155 else
1156 r += cpi->intra_tx_type_costs[mbmi->tx_size]
1157 [intra_mode_to_tx_type_context[mbmi->mode]]
1158 [mbmi->tx_type];
1159 }
hui su07154b02015-09-22 10:34:18 -07001160#endif // CONFIG_EXT_TX
1161
1162 if (r == INT_MAX)
1163 continue;
1164
hui su07154b02015-09-22 10:34:18 -07001165 if (s) {
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001166 if (is_inter) {
hui su07154b02015-09-22 10:34:18 -07001167 rd = RDCOST(x->rdmult, x->rddiv, s1, sse);
hui su07154b02015-09-22 10:34:18 -07001168 } else {
1169 rd = RDCOST(x->rdmult, x->rddiv, s1 + r_tx_size * tx_select, sse);
1170 }
1171 } else {
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001172 rd = RDCOST(x->rdmult, x->rddiv, r + s0 + r_tx_size * tx_select, d);
hui su07154b02015-09-22 10:34:18 -07001173 }
1174
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001175 if (tx_select && !(s && is_inter))
1176 r += r_tx_size;
1177
1178 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] && !s)
hui su07154b02015-09-22 10:34:18 -07001179 rd = VPXMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, sse));
1180
1181 // Early termination in transform size search.
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001182 if (cpi->sf.tx_size_search_breakout &&
1183 (rd == INT64_MAX ||
Jingning Han35b3bd32015-11-10 16:02:33 -08001184 (s == 1 && tx_type != DCT_DCT && n < start_tx) ||
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001185 (n < (int) max_tx_size && rd > last_rd)))
hui su07154b02015-09-22 10:34:18 -07001186 break;
1187
1188 last_rd = rd;
hui su4f16f112015-10-02 10:45:27 -07001189 if (rd <
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001190 (is_inter && best_tx_type == DCT_DCT ? ext_tx_th : 1) *
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001191 best_rd) {
hui su07154b02015-09-22 10:34:18 -07001192 best_tx = n;
1193 best_rd = rd;
1194 *distortion = d;
1195 *rate = r;
1196 *skip = s;
1197 *psse = sse;
hui su4f16f112015-10-02 10:45:27 -07001198 best_tx_type = mbmi->tx_type;
hui su07154b02015-09-22 10:34:18 -07001199 }
Jingning Han3ee6db62015-08-05 19:00:31 -07001200 }
Jingning Han3ee6db62015-08-05 19:00:31 -07001201 }
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001202
Jingning Han3ee6db62015-08-05 19:00:31 -07001203 mbmi->tx_size = best_tx;
hui su4f16f112015-10-02 10:45:27 -07001204 mbmi->tx_type = best_tx_type;
Julia Robson9fe188e2016-01-21 17:14:29 +00001205 if (mbmi->tx_size >= TX_32X32)
1206 assert(mbmi->tx_type == DCT_DCT);
Jingning Han71c15602015-10-13 12:40:39 -07001207 txfm_rd_in_plane(x,
1208#if CONFIG_VAR_TX
1209 cpi,
1210#endif
1211 &r, &d, &s,
hui su07154b02015-09-22 10:34:18 -07001212 &sse, ref_best_rd, 0, bs, best_tx,
1213 cpi->sf.use_fast_coef_costing);
Jingning Han3ee6db62015-08-05 19:00:31 -07001214}
1215
Yaowu Xu26a9afc2015-08-13 09:42:27 -07001216static void super_block_yrd(VP10_COMP *cpi, MACROBLOCK *x, int *rate,
Jingning Han3ee6db62015-08-05 19:00:31 -07001217 int64_t *distortion, int *skip,
1218 int64_t *psse, BLOCK_SIZE bs,
1219 int64_t ref_best_rd) {
1220 MACROBLOCKD *xd = &x->e_mbd;
1221 int64_t sse;
1222 int64_t *ret_sse = psse ? psse : &sse;
1223
1224 assert(bs == xd->mi[0]->mbmi.sb_type);
1225
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08001226 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001227 choose_smallest_tx_size(cpi, x, rate, distortion, skip, ret_sse,
1228 ref_best_rd, bs);
hui su66f2f652015-11-16 16:58:15 -08001229 } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
Jingning Han3ee6db62015-08-05 19:00:31 -07001230 choose_largest_tx_size(cpi, x, rate, distortion, skip, ret_sse, ref_best_rd,
1231 bs);
1232 } else {
1233 choose_tx_size_from_rd(cpi, x, rate, distortion, skip, ret_sse,
1234 ref_best_rd, bs);
1235 }
1236}
1237
1238static int conditional_skipintra(PREDICTION_MODE mode,
1239 PREDICTION_MODE best_intra_mode) {
1240 if (mode == D117_PRED &&
1241 best_intra_mode != V_PRED &&
1242 best_intra_mode != D135_PRED)
1243 return 1;
1244 if (mode == D63_PRED &&
1245 best_intra_mode != V_PRED &&
1246 best_intra_mode != D45_PRED)
1247 return 1;
1248 if (mode == D207_PRED &&
1249 best_intra_mode != H_PRED &&
1250 best_intra_mode != D45_PRED)
1251 return 1;
1252 if (mode == D153_PRED &&
1253 best_intra_mode != H_PRED &&
1254 best_intra_mode != D135_PRED)
1255 return 1;
1256 return 0;
1257}
1258
hui suc93e5cc2015-12-07 18:18:57 -08001259void rd_pick_palette_intra_sby(VP10_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
1260 int palette_ctx, int dc_mode_cost,
1261 PALETTE_MODE_INFO *palette_mode_info,
1262 uint8_t *best_palette_color_map,
1263 TX_SIZE *best_tx, PREDICTION_MODE *mode_selected,
1264 int64_t *best_rd) {
1265 MACROBLOCKD *const xd = &x->e_mbd;
1266 MODE_INFO *const mic = xd->mi[0];
1267 int rows = 4 * num_4x4_blocks_high_lookup[bsize];
1268 int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
1269 int this_rate, this_rate_tokenonly, s;
1270 int64_t this_distortion, this_rd;
1271 int colors, n;
1272 int src_stride = x->plane[0].src.stride;
1273 uint8_t *src = x->plane[0].src.buf;
1274
1275#if CONFIG_VP9_HIGHBITDEPTH
1276 if (cpi->common.use_highbitdepth)
1277 colors = vp10_count_colors_highbd(src, src_stride, rows, cols,
1278 cpi->common.bit_depth);
1279 else
1280#endif // CONFIG_VP9_HIGHBITDEPTH
1281 colors = vp10_count_colors(src, src_stride, rows, cols);
1282 palette_mode_info->palette_size[0] = 0;
1283
1284 if (colors > 1 && colors <= 64 && cpi->common.allow_screen_content_tools) {
1285 int r, c, i, j, k;
1286 int max_itr = 50;
1287 int color_ctx, color_idx = 0;
1288 int color_order[PALETTE_MAX_SIZE];
1289 double *data = x->palette_buffer->kmeans_data_buf;
1290 uint8_t *indices = x->palette_buffer->kmeans_indices_buf;
1291 uint8_t *pre_indices = x->palette_buffer->kmeans_pre_indices_buf;
1292 double centroids[PALETTE_MAX_SIZE];
1293 uint8_t *color_map;
1294 double lb, ub, val;
1295 PALETTE_MODE_INFO *pmi = &mic->mbmi.palette_mode_info;
1296#if CONFIG_VP9_HIGHBITDEPTH
1297 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
1298 if (cpi->common.use_highbitdepth)
1299 lb = ub = src16[0];
1300 else
1301#endif // CONFIG_VP9_HIGHBITDEPTH
1302 lb = ub = src[0];
1303
1304#if CONFIG_VP9_HIGHBITDEPTH
1305 if (cpi->common.use_highbitdepth) {
1306 for (r = 0; r < rows; ++r) {
1307 for (c = 0; c < cols; ++c) {
1308 val = src16[r * src_stride + c];
1309 data[r * cols + c] = val;
1310 if (val < lb)
1311 lb = val;
1312 else if (val > ub)
1313 ub = val;
1314 }
1315 }
1316 } else {
1317#endif // CONFIG_VP9_HIGHBITDEPTH
1318 for (r = 0; r < rows; ++r) {
1319 for (c = 0; c < cols; ++c) {
1320 val = src[r * src_stride + c];
1321 data[r * cols + c] = val;
1322 if (val < lb)
1323 lb = val;
1324 else if (val > ub)
1325 ub = val;
1326 }
1327 }
1328#if CONFIG_VP9_HIGHBITDEPTH
1329 }
1330#endif // CONFIG_VP9_HIGHBITDEPTH
1331
1332 mic->mbmi.mode = DC_PRED;
1333
1334 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors;
1335 n >= 2; --n) {
1336 for (i = 0; i < n; ++i)
1337 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
1338 vp10_k_means(data, centroids, indices, pre_indices, rows * cols,
1339 n, 1, max_itr);
1340 vp10_insertion_sort(centroids, n);
1341 for (i = 0; i < n; ++i)
1342 centroids[i] = round(centroids[i]);
1343 // remove duplicates
1344 i = 1;
1345 k = n;
1346 while (i < k) {
1347 if (centroids[i] == centroids[i - 1]) {
1348 j = i;
1349 while (j < k - 1) {
1350 centroids[j] = centroids[j + 1];
1351 ++j;
1352 }
1353 --k;
1354 } else {
1355 ++i;
1356 }
1357 }
1358
1359#if CONFIG_VP9_HIGHBITDEPTH
1360 if (cpi->common.use_highbitdepth)
1361 for (i = 0; i < k; ++i)
Yaowu Xu3c28b4a2016-02-08 09:41:43 -08001362 pmi->palette_colors[i] = clip_pixel_highbd((int)round(centroids[i]),
1363 cpi->common.bit_depth);
hui suc93e5cc2015-12-07 18:18:57 -08001364 else
1365#endif // CONFIG_VP9_HIGHBITDEPTH
1366 for (i = 0; i < k; ++i)
1367 pmi->palette_colors[i] = clip_pixel((int)round(centroids[i]));
1368 pmi->palette_size[0] = k;
1369
1370 vp10_calc_indices(data, centroids, indices, rows * cols, k, 1);
1371 for (r = 0; r < rows; ++r)
1372 for (c = 0; c < cols; ++c)
1373 xd->plane[0].color_index_map[r * cols + c] = indices[r * cols + c];
1374
1375 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
1376 &s, NULL, bsize, *best_rd);
1377 if (this_rate_tokenonly == INT_MAX)
1378 continue;
1379
1380 this_rate = this_rate_tokenonly + dc_mode_cost +
1381 cpi->common.bit_depth * k * vp10_cost_bit(128, 0) +
1382 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - 2];
1383 this_rate +=
1384 vp10_cost_bit(vp10_default_palette_y_mode_prob[bsize - BLOCK_8X8]
1385 [palette_ctx], 1);
1386 color_map = xd->plane[0].color_index_map;
1387 this_rate += write_uniform_cost(k, xd->plane[0].color_index_map[0]);
1388 for (i = 0; i < rows; ++i) {
1389 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
1390 color_ctx = vp10_get_palette_color_context(color_map, cols, i, j,
1391 k, color_order);
1392 for (r = 0; r < k; ++r)
1393 if (color_map[i * cols + j] == color_order[r]) {
1394 color_idx = r;
1395 break;
1396 }
1397 assert(color_idx < k);
1398 this_rate +=
1399 cpi->palette_y_color_cost[k - 2][color_ctx][color_idx];
1400 }
1401 }
1402 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
1403
1404 if (this_rd < *best_rd) {
1405 *best_rd = this_rd;
1406 *palette_mode_info = mic->mbmi.palette_mode_info;
1407 memcpy(best_palette_color_map, xd->plane[0].color_index_map,
1408 rows * cols * sizeof(xd->plane[0].color_index_map[0]));
1409 *mode_selected = DC_PRED;
1410 *best_tx = mic->mbmi.tx_size;
1411 }
1412 }
1413 }
1414}
1415
Yaowu Xu26a9afc2015-08-13 09:42:27 -07001416static int64_t rd_pick_intra4x4block(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07001417 int row, int col,
1418 PREDICTION_MODE *best_mode,
1419 const int *bmode_costs,
1420 ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
1421 int *bestrate, int *bestratey,
1422 int64_t *bestdistortion,
1423 BLOCK_SIZE bsize, int64_t rd_thresh) {
1424 PREDICTION_MODE mode;
1425 MACROBLOCKD *const xd = &x->e_mbd;
1426 int64_t best_rd = rd_thresh;
1427 struct macroblock_plane *p = &x->plane[0];
1428 struct macroblockd_plane *pd = &xd->plane[0];
1429 const int src_stride = p->src.stride;
1430 const int dst_stride = pd->dst.stride;
1431 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
1432 uint8_t *dst_init = &pd->dst.buf[row * 4 * src_stride + col * 4];
1433 ENTROPY_CONTEXT ta[2], tempa[2];
1434 ENTROPY_CONTEXT tl[2], templ[2];
1435 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1436 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1437 int idx, idy;
1438 uint8_t best_dst[8 * 8];
1439#if CONFIG_VP9_HIGHBITDEPTH
1440 uint16_t best_dst16[8 * 8];
1441#endif
1442
1443 memcpy(ta, a, sizeof(ta));
1444 memcpy(tl, l, sizeof(tl));
1445 xd->mi[0]->mbmi.tx_size = TX_4X4;
hui suc93e5cc2015-12-07 18:18:57 -08001446 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07001447
1448#if CONFIG_VP9_HIGHBITDEPTH
1449 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1450 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
1451 int64_t this_rd;
1452 int ratey = 0;
1453 int64_t distortion = 0;
1454 int rate = bmode_costs[mode];
1455
1456 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode)))
1457 continue;
1458
1459 // Only do the oblique modes if the best so far is
1460 // one of the neighboring directional modes
1461 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
1462 if (conditional_skipintra(mode, *best_mode))
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001463 continue;
Jingning Han3ee6db62015-08-05 19:00:31 -07001464 }
1465
1466 memcpy(tempa, ta, sizeof(ta));
1467 memcpy(templ, tl, sizeof(tl));
1468
1469 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
1470 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
1471 const int block = (row + idy) * 2 + (col + idx);
1472 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
1473 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
1474 int16_t *const src_diff = vp10_raster_block_offset_int16(BLOCK_8X8,
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001475 block,
1476 p->src_diff);
Jingning Han3ee6db62015-08-05 19:00:31 -07001477 tran_low_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block);
1478 xd->mi[0]->bmi[block].as_mode = mode;
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001479 vp10_predict_intra_block(xd, 1, 1, TX_4X4, mode, dst, dst_stride,
Jingning Han3ee6db62015-08-05 19:00:31 -07001480 dst, dst_stride,
1481 col + idx, row + idy, 0);
1482 vpx_highbd_subtract_block(4, 4, src_diff, 8, src, src_stride,
1483 dst, dst_stride, xd->bd);
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001484 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
hui sub3cc3a02015-08-24 14:37:54 -07001485 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001486 const scan_order *so = get_scan(TX_4X4, tx_type, 0);
Jingning Han20484042015-10-21 17:38:00 -07001487#if CONFIG_VAR_TX
1488 const int coeff_ctx = combine_entropy_contexts(*(tempa + idx),
1489 *(templ + idy));
Geza Lore432e8752016-01-22 13:57:28 +00001490#endif // CONFIG_VAR_TX
Yaowu Xu7c514e22015-09-28 15:55:46 -07001491 vp10_highbd_fwd_txfm_4x4(src_diff, coeff, 8, DCT_DCT, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07001492 vp10_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
Jingning Han20484042015-10-21 17:38:00 -07001493#if CONFIG_VAR_TX
Geza Lore432e8752016-01-22 13:57:28 +00001494 ratey += cost_coeffs(x, 0, block, coeff_ctx, TX_4X4, so->scan,
1495 so->neighbors, cpi->sf.use_fast_coef_costing);
1496 *(tempa + idx) = !(p->eobs[block] == 0);
1497 *(templ + idy) = !(p->eobs[block] == 0);
Jingning Han20484042015-10-21 17:38:00 -07001498#else
Geza Lore432e8752016-01-22 13:57:28 +00001499 ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy,
Jingning Han20484042015-10-21 17:38:00 -07001500 TX_4X4,
Jingning Han3ee6db62015-08-05 19:00:31 -07001501 so->scan, so->neighbors,
1502 cpi->sf.use_fast_coef_costing);
Geza Lore432e8752016-01-22 13:57:28 +00001503#endif // CONFIG_VAR_TX
Jingning Han3ee6db62015-08-05 19:00:31 -07001504 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1505 goto next_highbd;
hui sud76e5b32015-08-13 16:27:19 -07001506 vp10_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block),
1507 dst, dst_stride, p->eobs[block],
Yaowu Xu7c514e22015-09-28 15:55:46 -07001508 xd->bd, DCT_DCT, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07001509 } else {
1510 int64_t unused;
hui sub3cc3a02015-08-24 14:37:54 -07001511 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001512 const scan_order *so = get_scan(TX_4X4, tx_type, 0);
Jingning Han20484042015-10-21 17:38:00 -07001513#if CONFIG_VAR_TX
1514 const int coeff_ctx = combine_entropy_contexts(*(tempa + idx),
1515 *(templ + idy));
Geza Lore432e8752016-01-22 13:57:28 +00001516#endif // CONFIG_VAR_TX
Yaowu Xu7c514e22015-09-28 15:55:46 -07001517 vp10_highbd_fwd_txfm_4x4(src_diff, coeff, 8, tx_type, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07001518 vp10_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
Jingning Han20484042015-10-21 17:38:00 -07001519#if CONFIG_VAR_TX
Geza Lore432e8752016-01-22 13:57:28 +00001520 ratey += cost_coeffs(x, 0, block, coeff_ctx, TX_4X4, so->scan,
1521 so->neighbors, cpi->sf.use_fast_coef_costing);
1522 *(tempa + idx) = !(p->eobs[block] == 0);
1523 *(templ + idy) = !(p->eobs[block] == 0);
Jingning Han20484042015-10-21 17:38:00 -07001524#else
Geza Lore432e8752016-01-22 13:57:28 +00001525 ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy,
1526 TX_4X4, so->scan, so->neighbors,
Jingning Han3ee6db62015-08-05 19:00:31 -07001527 cpi->sf.use_fast_coef_costing);
Geza Lore432e8752016-01-22 13:57:28 +00001528#endif // CONFIG_VAR_TX
Jingning Han3ee6db62015-08-05 19:00:31 -07001529 distortion += vp10_highbd_block_error(
1530 coeff, BLOCK_OFFSET(pd->dqcoeff, block),
1531 16, &unused, xd->bd) >> 2;
1532 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1533 goto next_highbd;
hui sud76e5b32015-08-13 16:27:19 -07001534 vp10_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block),
1535 dst, dst_stride, p->eobs[block],
Yaowu Xu7c514e22015-09-28 15:55:46 -07001536 xd->bd, tx_type, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07001537 }
1538 }
1539 }
1540
1541 rate += ratey;
1542 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
1543
1544 if (this_rd < best_rd) {
1545 *bestrate = rate;
1546 *bestratey = ratey;
1547 *bestdistortion = distortion;
1548 best_rd = this_rd;
1549 *best_mode = mode;
1550 memcpy(a, tempa, sizeof(tempa));
1551 memcpy(l, templ, sizeof(templ));
1552 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
1553 memcpy(best_dst16 + idy * 8,
1554 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
1555 num_4x4_blocks_wide * 4 * sizeof(uint16_t));
1556 }
1557 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001558next_highbd:
Jingning Han3ee6db62015-08-05 19:00:31 -07001559 {}
1560 }
Geza Lore432e8752016-01-22 13:57:28 +00001561
Jingning Han481b8342015-09-11 08:56:06 -07001562 if (best_rd >= rd_thresh)
Jingning Han3ee6db62015-08-05 19:00:31 -07001563 return best_rd;
1564
1565 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
1566 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
1567 best_dst16 + idy * 8,
1568 num_4x4_blocks_wide * 4 * sizeof(uint16_t));
1569 }
1570
1571 return best_rd;
1572 }
1573#endif // CONFIG_VP9_HIGHBITDEPTH
1574
1575 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
1576 int64_t this_rd;
1577 int ratey = 0;
1578 int64_t distortion = 0;
1579 int rate = bmode_costs[mode];
1580
1581 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode)))
1582 continue;
1583
1584 // Only do the oblique modes if the best so far is
1585 // one of the neighboring directional modes
1586 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
1587 if (conditional_skipintra(mode, *best_mode))
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001588 continue;
Jingning Han3ee6db62015-08-05 19:00:31 -07001589 }
1590
1591 memcpy(tempa, ta, sizeof(ta));
1592 memcpy(templ, tl, sizeof(tl));
1593
1594 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
1595 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
1596 const int block = (row + idy) * 2 + (col + idx);
1597 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
1598 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
1599 int16_t *const src_diff =
1600 vp10_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff);
1601 tran_low_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block);
1602 xd->mi[0]->bmi[block].as_mode = mode;
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001603 vp10_predict_intra_block(xd, 1, 1, TX_4X4, mode, dst, dst_stride,
Jingning Han3ee6db62015-08-05 19:00:31 -07001604 dst, dst_stride, col + idx, row + idy, 0);
1605 vpx_subtract_block(4, 4, src_diff, 8, src, src_stride, dst, dst_stride);
1606
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001607 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
hui sub3cc3a02015-08-24 14:37:54 -07001608 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001609 const scan_order *so = get_scan(TX_4X4, tx_type, 0);
Jingning Han2cdc1272015-10-09 09:57:42 -07001610#if CONFIG_VAR_TX
Geza Lore432e8752016-01-22 13:57:28 +00001611 const int coeff_ctx = combine_entropy_contexts(*(tempa + idx),
1612 *(templ + idy));
Jingning Han2cdc1272015-10-09 09:57:42 -07001613#endif
Yaowu Xu7c514e22015-09-28 15:55:46 -07001614 vp10_fwd_txfm_4x4(src_diff, coeff, 8, DCT_DCT, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07001615 vp10_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
Jingning Han2cdc1272015-10-09 09:57:42 -07001616#if CONFIG_VAR_TX
1617 ratey += cost_coeffs(x, 0, block, coeff_ctx, TX_4X4, so->scan,
1618 so->neighbors, cpi->sf.use_fast_coef_costing);
1619 *(tempa + idx) = !(p->eobs[block] == 0);
1620 *(templ + idy) = !(p->eobs[block] == 0);
1621#else
1622 ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy,
1623 TX_4X4,
Jingning Han3ee6db62015-08-05 19:00:31 -07001624 so->scan, so->neighbors,
1625 cpi->sf.use_fast_coef_costing);
Jingning Han2cdc1272015-10-09 09:57:42 -07001626#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07001627 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1628 goto next;
hui sud76e5b32015-08-13 16:27:19 -07001629 vp10_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block),
Yaowu Xu7c514e22015-09-28 15:55:46 -07001630 dst, dst_stride, p->eobs[block], DCT_DCT, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07001631 } else {
1632 int64_t unused;
hui sub3cc3a02015-08-24 14:37:54 -07001633 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001634 const scan_order *so = get_scan(TX_4X4, tx_type, 0);
Jingning Han2cdc1272015-10-09 09:57:42 -07001635#if CONFIG_VAR_TX
Geza Lore432e8752016-01-22 13:57:28 +00001636 const int coeff_ctx = combine_entropy_contexts(*(tempa + idx),
1637 *(templ + idy));
Jingning Han2cdc1272015-10-09 09:57:42 -07001638#endif
Yaowu Xu7c514e22015-09-28 15:55:46 -07001639 vp10_fwd_txfm_4x4(src_diff, coeff, 8, tx_type, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07001640 vp10_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
Jingning Han2cdc1272015-10-09 09:57:42 -07001641#if CONFIG_VAR_TX
1642 ratey += cost_coeffs(x, 0, block, coeff_ctx, TX_4X4, so->scan,
1643 so->neighbors, cpi->sf.use_fast_coef_costing);
1644 *(tempa + idx) = !(p->eobs[block] == 0);
1645 *(templ + idy) = !(p->eobs[block] == 0);
1646#else
1647 ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy,
1648 TX_4X4, so->scan, so->neighbors,
1649 cpi->sf.use_fast_coef_costing);
1650#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07001651 distortion += vp10_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, block),
1652 16, &unused) >> 2;
1653 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1654 goto next;
hui sud76e5b32015-08-13 16:27:19 -07001655 vp10_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block),
Yaowu Xu7c514e22015-09-28 15:55:46 -07001656 dst, dst_stride, p->eobs[block], tx_type, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07001657 }
1658 }
1659 }
1660
1661 rate += ratey;
1662 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
1663
1664 if (this_rd < best_rd) {
1665 *bestrate = rate;
1666 *bestratey = ratey;
1667 *bestdistortion = distortion;
1668 best_rd = this_rd;
1669 *best_mode = mode;
1670 memcpy(a, tempa, sizeof(tempa));
1671 memcpy(l, templ, sizeof(templ));
1672 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
1673 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
1674 num_4x4_blocks_wide * 4);
1675 }
1676 next:
1677 {}
1678 }
1679
Jingning Hanf1376972015-09-10 12:42:21 -07001680 if (best_rd >= rd_thresh)
Jingning Han3ee6db62015-08-05 19:00:31 -07001681 return best_rd;
1682
1683 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
1684 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
1685 num_4x4_blocks_wide * 4);
1686
1687 return best_rd;
1688}
1689
Yaowu Xu26a9afc2015-08-13 09:42:27 -07001690static int64_t rd_pick_intra_sub_8x8_y_mode(VP10_COMP *cpi, MACROBLOCK *mb,
Jingning Han3ee6db62015-08-05 19:00:31 -07001691 int *rate, int *rate_y,
1692 int64_t *distortion,
1693 int64_t best_rd) {
1694 int i, j;
1695 const MACROBLOCKD *const xd = &mb->e_mbd;
1696 MODE_INFO *const mic = xd->mi[0];
1697 const MODE_INFO *above_mi = xd->above_mi;
1698 const MODE_INFO *left_mi = xd->left_mi;
1699 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
1700 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1701 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1702 int idx, idy;
1703 int cost = 0;
1704 int64_t total_distortion = 0;
1705 int tot_rate_y = 0;
1706 int64_t total_rd = 0;
1707 ENTROPY_CONTEXT t_above[4], t_left[4];
hui su1559afd2015-12-30 10:27:19 -08001708 const int *bmode_costs = cpi->mbmode_cost[0];
Jingning Han3ee6db62015-08-05 19:00:31 -07001709
1710 memcpy(t_above, xd->plane[0].above_context, sizeof(t_above));
1711 memcpy(t_left, xd->plane[0].left_context, sizeof(t_left));
1712
hui sube3559b2015-10-07 09:29:02 -07001713#if CONFIG_EXT_INTRA
1714 mic->mbmi.ext_intra_mode_info.use_ext_intra_mode[0] = 0;
hui su3b1c7662016-01-12 16:38:58 -08001715 mic->mbmi.intra_filter = INTRA_FILTER_LINEAR;
hui sube3559b2015-10-07 09:29:02 -07001716#endif // CONFIG_EXT_INTRA
1717
Debargha Mukherjeed46c1f22016-02-08 15:59:17 -08001718 // TODO(any): Add search of the tx_type to improve rd performance at the
1719 // expense of speed.
1720 mic->mbmi.tx_type = DCT_DCT;
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08001721 mic->mbmi.tx_size = TX_4X4;
Debargha Mukherjeed46c1f22016-02-08 15:59:17 -08001722
Jingning Han3ee6db62015-08-05 19:00:31 -07001723 // Pick modes for each sub-block (of size 4x4, 4x8, or 8x4) in an 8x8 block.
1724 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
1725 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
1726 PREDICTION_MODE best_mode = DC_PRED;
1727 int r = INT_MAX, ry = INT_MAX;
1728 int64_t d = INT64_MAX, this_rd = INT64_MAX;
1729 i = idy * 2 + idx;
1730 if (cpi->common.frame_type == KEY_FRAME) {
1731 const PREDICTION_MODE A = vp10_above_block_mode(mic, above_mi, i);
1732 const PREDICTION_MODE L = vp10_left_block_mode(mic, left_mi, i);
1733
1734 bmode_costs = cpi->y_mode_costs[A][L];
1735 }
1736
1737 this_rd = rd_pick_intra4x4block(cpi, mb, idy, idx, &best_mode,
1738 bmode_costs, t_above + idx, t_left + idy,
1739 &r, &ry, &d, bsize, best_rd - total_rd);
1740 if (this_rd >= best_rd - total_rd)
1741 return INT64_MAX;
1742
1743 total_rd += this_rd;
1744 cost += r;
1745 total_distortion += d;
1746 tot_rate_y += ry;
1747
1748 mic->bmi[i].as_mode = best_mode;
1749 for (j = 1; j < num_4x4_blocks_high; ++j)
1750 mic->bmi[i + j * 2].as_mode = best_mode;
1751 for (j = 1; j < num_4x4_blocks_wide; ++j)
1752 mic->bmi[i + j].as_mode = best_mode;
1753
1754 if (total_rd >= best_rd)
1755 return INT64_MAX;
1756 }
1757 }
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08001758 mic->mbmi.mode = mic->bmi[3].as_mode;
1759
1760 // Add in the cost of the transform type
1761 if (!xd->lossless[mic->mbmi.segment_id]) {
1762 int rate_tx_type = 0;
1763#if CONFIG_EXT_TX
1764 if (get_ext_tx_types(TX_4X4, bsize, 0) > 1) {
1765 const int eset = get_ext_tx_set(TX_4X4, bsize, 0);
1766 rate_tx_type =
1767 cpi->intra_tx_type_costs[eset][TX_4X4]
1768 [mic->mbmi.mode][mic->mbmi.tx_type];
1769 }
1770#else
1771 rate_tx_type =
1772 cpi->intra_tx_type_costs[TX_4X4]
1773 [intra_mode_to_tx_type_context[mic->mbmi.mode]]
1774 [mic->mbmi.tx_type];
1775#endif
1776 assert(mic->mbmi.tx_size == TX_4X4);
1777 cost += rate_tx_type;
1778 tot_rate_y += rate_tx_type;
1779 }
Jingning Han3ee6db62015-08-05 19:00:31 -07001780
1781 *rate = cost;
1782 *rate_y = tot_rate_y;
1783 *distortion = total_distortion;
Jingning Han3ee6db62015-08-05 19:00:31 -07001784
1785 return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
1786}
1787
hui sube3559b2015-10-07 09:29:02 -07001788#if CONFIG_EXT_INTRA
1789// Return 1 if an ext intra mode is selected; return 0 otherwise.
1790static int rd_pick_ext_intra_sby(VP10_COMP *cpi, MACROBLOCK *x,
1791 int *rate, int *rate_tokenonly,
1792 int64_t *distortion, int *skippable,
1793 BLOCK_SIZE bsize, int mode_cost,
1794 int64_t *best_rd) {
1795 MACROBLOCKD *const xd = &x->e_mbd;
1796 MODE_INFO *const mic = xd->mi[0];
1797 MB_MODE_INFO *mbmi = &mic->mbmi;
1798 int this_rate, this_rate_tokenonly, s;
1799 int ext_intra_selected_flag = 0;
hui su4aa50c12015-11-10 12:09:59 -08001800 int64_t this_distortion, this_rd;
hui sube3559b2015-10-07 09:29:02 -07001801 EXT_INTRA_MODE mode;
1802 TX_SIZE best_tx_size = TX_4X4;
1803 EXT_INTRA_MODE_INFO ext_intra_mode_info;
hui sube3559b2015-10-07 09:29:02 -07001804 TX_TYPE best_tx_type;
hui sube3559b2015-10-07 09:29:02 -07001805
1806 vp10_zero(ext_intra_mode_info);
1807 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 1;
1808 mbmi->mode = DC_PRED;
1809
hui su4aa50c12015-11-10 12:09:59 -08001810 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
1811 mbmi->ext_intra_mode_info.ext_intra_mode[0] = mode;
1812 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
1813 &s, NULL, bsize, *best_rd);
1814 if (this_rate_tokenonly == INT_MAX)
1815 continue;
hui sube3559b2015-10-07 09:29:02 -07001816
hui su4aa50c12015-11-10 12:09:59 -08001817 this_rate = this_rate_tokenonly +
1818 vp10_cost_bit(cpi->common.fc->ext_intra_probs[0], 1) +
1819 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
1820 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui sube3559b2015-10-07 09:29:02 -07001821
hui su4aa50c12015-11-10 12:09:59 -08001822 if (this_rd < *best_rd) {
1823 *best_rd = this_rd;
1824 best_tx_size = mic->mbmi.tx_size;
1825 ext_intra_mode_info = mbmi->ext_intra_mode_info;
hui su4aa50c12015-11-10 12:09:59 -08001826 best_tx_type = mic->mbmi.tx_type;
hui su4aa50c12015-11-10 12:09:59 -08001827 *rate = this_rate;
1828 *rate_tokenonly = this_rate_tokenonly;
1829 *distortion = this_distortion;
1830 *skippable = s;
1831 ext_intra_selected_flag = 1;
hui sube3559b2015-10-07 09:29:02 -07001832 }
1833 }
1834
1835 if (ext_intra_selected_flag) {
1836 mbmi->mode = DC_PRED;
1837 mbmi->tx_size = best_tx_size;
1838 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] =
1839 ext_intra_mode_info.use_ext_intra_mode[0];
1840 mbmi->ext_intra_mode_info.ext_intra_mode[0] =
1841 ext_intra_mode_info.ext_intra_mode[0];
hui sube3559b2015-10-07 09:29:02 -07001842 mbmi->tx_type = best_tx_type;
hui sube3559b2015-10-07 09:29:02 -07001843 return 1;
1844 } else {
1845 return 0;
1846 }
1847}
hui su4aa50c12015-11-10 12:09:59 -08001848
hui su5a7c8d82016-02-08 10:39:17 -08001849static void pick_intra_angle_routine_sby(VP10_COMP *cpi, MACROBLOCK *x,
1850 int *rate, int *rate_tokenonly,
1851 int64_t *distortion, int *skippable,
1852 int *best_angle_delta,
1853 TX_SIZE *best_tx_size,
1854 TX_TYPE *best_tx_type,
1855 INTRA_FILTER *best_filter,
1856 BLOCK_SIZE bsize, int rate_overhead,
1857 int64_t *best_rd) {
1858 int this_rate, this_rate_tokenonly, s;
1859 int64_t this_distortion, this_rd;
1860 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
1861 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
1862 &s, NULL, bsize, *best_rd);
1863 if (this_rate_tokenonly == INT_MAX)
1864 return;
1865
1866 this_rate = this_rate_tokenonly + rate_overhead;
1867 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
1868
1869 if (this_rd < *best_rd) {
1870 *best_rd = this_rd;
1871 *best_angle_delta = mbmi->angle_delta[0];
1872 *best_tx_size = mbmi->tx_size;
1873 *best_filter = mbmi->intra_filter;
1874 *best_tx_type = mbmi->tx_type;
1875 *rate = this_rate;
1876 *rate_tokenonly = this_rate_tokenonly;
1877 *distortion = this_distortion;
1878 *skippable = s;
1879 }
1880}
1881
hui su4aa50c12015-11-10 12:09:59 -08001882static int64_t rd_pick_intra_angle_sby(VP10_COMP *cpi, MACROBLOCK *x,
1883 int *rate, int *rate_tokenonly,
1884 int64_t *distortion, int *skippable,
1885 BLOCK_SIZE bsize, int rate_overhead,
1886 int64_t best_rd) {
1887 MACROBLOCKD *const xd = &x->e_mbd;
1888 MODE_INFO *const mic = xd->mi[0];
1889 MB_MODE_INFO *mbmi = &mic->mbmi;
1890 int this_rate, this_rate_tokenonly, s;
hui su3b1c7662016-01-12 16:38:58 -08001891 int angle_delta, best_angle_delta = 0, p_angle;
1892 const int intra_filter_ctx = vp10_get_pred_context_intra_interp(xd);
1893 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
hui su4aa50c12015-11-10 12:09:59 -08001894 const double rd_adjust = 1.2;
1895 int64_t this_distortion, this_rd, sse_dummy;
1896 TX_SIZE best_tx_size = mic->mbmi.tx_size;
hui su4aa50c12015-11-10 12:09:59 -08001897 TX_TYPE best_tx_type = mbmi->tx_type;
hui su4aa50c12015-11-10 12:09:59 -08001898
1899 if (ANGLE_FAST_SEARCH) {
1900 int deltas_level1[3] = {0, -2, 2};
1901 int deltas_level2[3][2] = {
1902 {-1, 1}, {-3, -1}, {1, 3},
1903 };
1904 const int level1 = 3, level2 = 2;
1905 int i, j, best_i = -1;
1906
1907 for (i = 0; i < level1; ++i) {
1908 mic->mbmi.angle_delta[0] = deltas_level1[i];
hui su3b1c7662016-01-12 16:38:58 -08001909 p_angle = mode_to_angle_map[mbmi->mode] +
1910 mbmi->angle_delta[0] * ANGLE_STEP;
1911 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
hui su5b618b72016-02-03 11:32:25 -08001912 if ((FILTER_FAST_SEARCH || !pick_intra_filter(p_angle)) &&
1913 filter != INTRA_FILTER_LINEAR)
hui su4aa50c12015-11-10 12:09:59 -08001914 continue;
hui su3b1c7662016-01-12 16:38:58 -08001915 mic->mbmi.intra_filter = filter;
hui su4aa50c12015-11-10 12:09:59 -08001916 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
hui su3b1c7662016-01-12 16:38:58 -08001917 &s, NULL, bsize,
1918 (i == 0 && filter == INTRA_FILTER_LINEAR &&
1919 best_rd < INT64_MAX) ? best_rd * rd_adjust : best_rd);
1920 if (this_rate_tokenonly == INT_MAX) {
1921 if (i == 0 && filter == INTRA_FILTER_LINEAR)
1922 return best_rd;
1923 else
1924 continue;
1925 }
1926 this_rate = this_rate_tokenonly + rate_overhead +
1927 cpi->intra_filter_cost[intra_filter_ctx][filter];
hui su4aa50c12015-11-10 12:09:59 -08001928 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui su3b1c7662016-01-12 16:38:58 -08001929 if (i == 0 && filter == INTRA_FILTER_LINEAR &&
1930 best_rd < INT64_MAX && this_rd > best_rd * rd_adjust)
1931 return best_rd;
hui su4aa50c12015-11-10 12:09:59 -08001932 if (this_rd < best_rd) {
hui su3b1c7662016-01-12 16:38:58 -08001933 best_i = i;
hui su4aa50c12015-11-10 12:09:59 -08001934 best_rd = this_rd;
1935 best_angle_delta = mbmi->angle_delta[0];
1936 best_tx_size = mbmi->tx_size;
hui su3b1c7662016-01-12 16:38:58 -08001937 best_filter = mbmi->intra_filter;
hui su4aa50c12015-11-10 12:09:59 -08001938 best_tx_type = mbmi->tx_type;
hui su4aa50c12015-11-10 12:09:59 -08001939 *rate = this_rate;
1940 *rate_tokenonly = this_rate_tokenonly;
1941 *distortion = this_distortion;
1942 *skippable = s;
1943 }
1944 }
1945 }
hui su3b1c7662016-01-12 16:38:58 -08001946
1947 if (best_i >= 0) {
1948 for (j = 0; j < level2; ++j) {
1949 mic->mbmi.angle_delta[0] = deltas_level2[best_i][j];
1950 p_angle = mode_to_angle_map[mbmi->mode] +
1951 mbmi->angle_delta[0] * ANGLE_STEP;
1952 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
1953 mic->mbmi.intra_filter = filter;
hui su5b618b72016-02-03 11:32:25 -08001954 if ((FILTER_FAST_SEARCH || !pick_intra_filter(p_angle)) &&
1955 filter != INTRA_FILTER_LINEAR)
hui su3b1c7662016-01-12 16:38:58 -08001956 continue;
hui su5a7c8d82016-02-08 10:39:17 -08001957 pick_intra_angle_routine_sby(cpi, x, rate, rate_tokenonly,
1958 distortion, skippable,
1959 &best_angle_delta, &best_tx_size,
1960 &best_tx_type, &best_filter, bsize,
1961 rate_overhead +
1962 cpi->intra_filter_cost
1963 [intra_filter_ctx][filter],
1964 &best_rd);
hui su3b1c7662016-01-12 16:38:58 -08001965 }
1966 }
1967 }
hui su4aa50c12015-11-10 12:09:59 -08001968 } else {
1969 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
1970 ++angle_delta) {
hui su3b1c7662016-01-12 16:38:58 -08001971 mbmi->angle_delta[0] = angle_delta;
1972 p_angle = mode_to_angle_map[mbmi->mode] +
1973 mbmi->angle_delta[0] * ANGLE_STEP;
1974 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
1975 mic->mbmi.intra_filter = filter;
hui su5b618b72016-02-03 11:32:25 -08001976 if ((FILTER_FAST_SEARCH || !pick_intra_filter(p_angle)) &&
1977 filter != INTRA_FILTER_LINEAR)
hui su3b1c7662016-01-12 16:38:58 -08001978 continue;
hui su5a7c8d82016-02-08 10:39:17 -08001979 pick_intra_angle_routine_sby(cpi, x, rate, rate_tokenonly,
1980 distortion, skippable,
1981 &best_angle_delta, &best_tx_size,
1982 &best_tx_type, &best_filter, bsize,
1983 rate_overhead +
1984 cpi->intra_filter_cost
1985 [intra_filter_ctx][filter],
1986 &best_rd);
hui su4aa50c12015-11-10 12:09:59 -08001987 }
1988 }
1989 }
1990
hui su5b618b72016-02-03 11:32:25 -08001991 if (FILTER_FAST_SEARCH && *rate_tokenonly < INT_MAX) {
1992 mbmi->angle_delta[0] = best_angle_delta;
1993 p_angle = mode_to_angle_map[mbmi->mode] +
1994 mbmi->angle_delta[0] * ANGLE_STEP;
1995 if (pick_intra_filter(p_angle)) {
1996 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
1997 mic->mbmi.intra_filter = filter;
hui su5a7c8d82016-02-08 10:39:17 -08001998 pick_intra_angle_routine_sby(cpi, x, rate, rate_tokenonly,
1999 distortion, skippable,
2000 &best_angle_delta, &best_tx_size,
2001 &best_tx_type, &best_filter, bsize,
2002 rate_overhead + cpi->intra_filter_cost
2003 [intra_filter_ctx][filter], &best_rd);
hui su5b618b72016-02-03 11:32:25 -08002004 }
2005 }
2006 }
2007
hui su4aa50c12015-11-10 12:09:59 -08002008 mbmi->tx_size = best_tx_size;
2009 mbmi->angle_delta[0] = best_angle_delta;
hui su3b1c7662016-01-12 16:38:58 -08002010 mic->mbmi.intra_filter = best_filter;
hui su4aa50c12015-11-10 12:09:59 -08002011 mbmi->tx_type = best_tx_type;
hui su4aa50c12015-11-10 12:09:59 -08002012
2013 if (*rate_tokenonly < INT_MAX) {
2014 txfm_rd_in_plane(x,
2015#if CONFIG_VAR_TX
2016 cpi,
2017#endif
2018 &this_rate_tokenonly, &this_distortion, &s,
2019 &sse_dummy, INT64_MAX, 0, bsize, mbmi->tx_size,
2020 cpi->sf.use_fast_coef_costing);
2021 }
2022
2023 return best_rd;
2024}
hui sud7c8bc72015-11-12 19:18:32 -08002025
2026static inline int get_angle_index(double angle) {
2027 const double step = 22.5, base = 45;
2028 return (int)round((angle - base) / step);
2029}
2030
2031static void angle_estimation(const uint8_t *src, int src_stride,
2032 int rows, int cols, double *hist) {
2033 int r, c, i, index;
2034 const double pi = 3.1415;
2035 double angle, dx, dy;
2036 double temp, divisor = 0;
2037
2038 for (i = 0; i < DIRECTIONAL_MODES; ++i)
2039 hist[i] = 0;
2040
2041 src += src_stride;
2042 for (r = 1; r < rows; ++r) {
2043 for (c = 1; c < cols; ++c) {
2044 dx = src[c] - src[c - 1];
2045 dy = src[c] - src[c - src_stride];
2046 temp = dx * dx + dy * dy;
2047 if (dy == 0)
2048 angle = 90;
2049 else
2050 angle = (atan((double)dx / (double)dy)) * 180 / pi;
2051 assert(angle >= -90 && angle <= 90);
2052 index = get_angle_index(angle + 180);
2053 if (index < DIRECTIONAL_MODES) {
2054 hist[index] += temp;
2055 divisor += temp;
2056 }
2057 if (angle > 0) {
2058 index = get_angle_index(angle);
2059 if (index >= 0) {
2060 hist[index] += temp;
2061 divisor += temp;
2062 }
2063 }
2064 }
2065 src += src_stride;
2066 }
2067
2068 if (divisor < 1)
2069 divisor = 1;
2070 for (i = 0; i < DIRECTIONAL_MODES; ++i)
2071 hist[i] /= divisor;
2072}
2073
2074#if CONFIG_VP9_HIGHBITDEPTH
2075static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
2076 int rows, int cols, double *hist) {
2077 int r, c, i, index;
2078 const double pi = 3.1415;
2079 double angle, dx, dy;
2080 double temp, divisor = 0;
2081 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
2082
2083 for (i = 0; i < DIRECTIONAL_MODES; ++i)
2084 hist[i] = 0;
2085
2086 src += src_stride;
2087 for (r = 1; r < rows; ++r) {
2088 for (c = 1; c < cols; ++c) {
2089 dx = src[c] - src[c - 1];
2090 dy = src[c] - src[c - src_stride];
2091 temp = dx * dx + dy * dy;
2092 if (dy == 0)
2093 angle = 90;
2094 else
2095 angle = (atan((double)dx / (double)dy)) * 180 / pi;
2096 assert(angle >= -90 && angle <= 90);
2097 index = get_angle_index(angle + 180);
2098 if (index < DIRECTIONAL_MODES) {
2099 hist[index] += temp;
2100 divisor += temp;
2101 }
2102 if (angle > 0) {
2103 index = get_angle_index(angle);
2104 if (index >= 0) {
2105 hist[index] += temp;
2106 divisor += temp;
2107 }
2108 }
2109 }
2110 src += src_stride;
2111 }
2112
2113 if (divisor < 1)
2114 divisor = 1;
2115 for (i = 0; i < DIRECTIONAL_MODES; ++i)
2116 hist[i] /= divisor;
2117}
2118#endif // CONFIG_VP9_HIGHBITDEPTH
hui sube3559b2015-10-07 09:29:02 -07002119#endif // CONFIG_EXT_INTRA
2120
Jingning Han3ee6db62015-08-05 19:00:31 -07002121// This function is used only for intra_only frames
Yaowu Xu26a9afc2015-08-13 09:42:27 -07002122static int64_t rd_pick_intra_sby_mode(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07002123 int *rate, int *rate_tokenonly,
2124 int64_t *distortion, int *skippable,
2125 BLOCK_SIZE bsize,
2126 int64_t best_rd) {
2127 PREDICTION_MODE mode;
2128 PREDICTION_MODE mode_selected = DC_PRED;
2129 MACROBLOCKD *const xd = &x->e_mbd;
2130 MODE_INFO *const mic = xd->mi[0];
2131 int this_rate, this_rate_tokenonly, s;
2132 int64_t this_distortion, this_rd;
2133 TX_SIZE best_tx = TX_4X4;
hui sube3559b2015-10-07 09:29:02 -07002134#if CONFIG_EXT_INTRA
hui su3b1c7662016-01-12 16:38:58 -08002135 const int intra_filter_ctx = vp10_get_pred_context_intra_interp(xd);
hui sube3559b2015-10-07 09:29:02 -07002136 EXT_INTRA_MODE_INFO ext_intra_mode_info;
hui su4aa50c12015-11-10 12:09:59 -08002137 int is_directional_mode, rate_overhead, best_angle_delta = 0;
hui su3b1c7662016-01-12 16:38:58 -08002138 INTRA_FILTER best_filter = INTRA_FILTER_LINEAR;
hui sud7c8bc72015-11-12 19:18:32 -08002139 uint8_t directional_mode_skip_mask[INTRA_MODES];
2140 const int src_stride = x->plane[0].src.stride;
2141 const uint8_t *src = x->plane[0].src.buf;
2142 double hist[DIRECTIONAL_MODES];
hui sube3559b2015-10-07 09:29:02 -07002143#endif // CONFIG_EXT_INTRA
hui su4f16f112015-10-02 10:45:27 -07002144 TX_TYPE best_tx_type = DCT_DCT;
Jingning Han3ee6db62015-08-05 19:00:31 -07002145 int *bmode_costs;
hui suc93e5cc2015-12-07 18:18:57 -08002146 PALETTE_MODE_INFO palette_mode_info;
2147 uint8_t *best_palette_color_map = cpi->common.allow_screen_content_tools ?
2148 x->palette_buffer->best_palette_color_map : NULL;
2149 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
2150 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
2151 int palette_ctx = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07002152 const MODE_INFO *above_mi = xd->above_mi;
2153 const MODE_INFO *left_mi = xd->left_mi;
2154 const PREDICTION_MODE A = vp10_above_block_mode(mic, above_mi, 0);
2155 const PREDICTION_MODE L = vp10_left_block_mode(mic, left_mi, 0);
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08002156 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
2157 const vpx_prob *tx_probs = get_tx_probs2(max_tx_size, xd,
2158 &cpi->common.fc->tx_probs);
Jingning Han3ee6db62015-08-05 19:00:31 -07002159 bmode_costs = cpi->y_mode_costs[A][L];
2160
hui sube3559b2015-10-07 09:29:02 -07002161#if CONFIG_EXT_INTRA
2162 ext_intra_mode_info.use_ext_intra_mode[0] = 0;
2163 mic->mbmi.ext_intra_mode_info.use_ext_intra_mode[0] = 0;
hui su4aa50c12015-11-10 12:09:59 -08002164 mic->mbmi.angle_delta[0] = 0;
hui sud7c8bc72015-11-12 19:18:32 -08002165 memset(directional_mode_skip_mask, 0,
2166 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
2167#if CONFIG_VP9_HIGHBITDEPTH
2168 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
2169 highbd_angle_estimation(src, src_stride, rows, cols, hist);
2170 else
2171#endif
2172 angle_estimation(src, src_stride, rows, cols, hist);
2173
2174 for (mode = 0; mode < INTRA_MODES; ++mode) {
2175 if (mode != DC_PRED && mode != TM_PRED) {
2176 int index = get_angle_index((double)mode_to_angle_map[mode]);
2177 double score, weight = 1.0;
2178 score = hist[index];
2179 if (index > 0) {
2180 score += hist[index - 1] * 0.5;
2181 weight += 0.5;
2182 }
2183 if (index < DIRECTIONAL_MODES - 1) {
2184 score += hist[index + 1] * 0.5;
2185 weight += 0.5;
2186 }
2187 score /= weight;
2188 if (score < ANGLE_SKIP_THRESH)
2189 directional_mode_skip_mask[mode] = 1;
2190 }
2191 }
hui sube3559b2015-10-07 09:29:02 -07002192#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07002193 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
hui suc93e5cc2015-12-07 18:18:57 -08002194 palette_mode_info.palette_size[0] = 0;
2195 mic->mbmi.palette_mode_info.palette_size[0] = 0;
2196 if (above_mi)
2197 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
2198 if (left_mi)
2199 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
hui su5d011cb2015-09-15 12:44:13 -07002200
Jingning Han3ee6db62015-08-05 19:00:31 -07002201 /* Y Search for intra prediction mode */
hui sube3559b2015-10-07 09:29:02 -07002202 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
Jingning Han3ee6db62015-08-05 19:00:31 -07002203 mic->mbmi.mode = mode;
hui su4aa50c12015-11-10 12:09:59 -08002204#if CONFIG_EXT_INTRA
2205 is_directional_mode = (mode != DC_PRED && mode != TM_PRED);
hui sud7c8bc72015-11-12 19:18:32 -08002206 if (is_directional_mode && directional_mode_skip_mask[mode])
2207 continue;
hui su4aa50c12015-11-10 12:09:59 -08002208 if (is_directional_mode) {
hui sud7c8bc72015-11-12 19:18:32 -08002209 rate_overhead = bmode_costs[mode] +
2210 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
2211 this_rate_tokenonly = INT_MAX;
2212 this_rd =
2213 rd_pick_intra_angle_sby(cpi, x, &this_rate, &this_rate_tokenonly,
2214 &this_distortion, &s, bsize, rate_overhead,
2215 best_rd);
hui su4aa50c12015-11-10 12:09:59 -08002216 } else {
2217 mic->mbmi.angle_delta[0] = 0;
2218 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
2219 &s, NULL, bsize, best_rd);
2220 }
2221#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07002222 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
hui su4aa50c12015-11-10 12:09:59 -08002223 &s, NULL, bsize, best_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07002224
2225 if (this_rate_tokenonly == INT_MAX)
2226 continue;
2227
2228 this_rate = this_rate_tokenonly + bmode_costs[mode];
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08002229
2230 if (!xd->lossless[xd->mi[0]->mbmi.segment_id]) {
2231 // super_block_yrd above includes the cost of the tx_size in the
2232 // tokenonly rate, but for intra blocks, tx_size is always coded
2233 // (prediction granularity), so we account for it in the full rate,
2234 // not the tokenonly rate.
2235 this_rate_tokenonly -= vp10_cost_tx_size(mic->mbmi.tx_size, max_tx_size,
2236 tx_probs);
2237 }
hui suc93e5cc2015-12-07 18:18:57 -08002238 if (cpi->common.allow_screen_content_tools && mode == DC_PRED)
2239 this_rate +=
2240 vp10_cost_bit(vp10_default_palette_y_mode_prob[bsize - BLOCK_8X8]
2241 [palette_ctx], 0);
hui sube3559b2015-10-07 09:29:02 -07002242#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08002243 if (mode == DC_PRED && ALLOW_FILTER_INTRA_MODES)
hui sube3559b2015-10-07 09:29:02 -07002244 this_rate += vp10_cost_bit(cpi->common.fc->ext_intra_probs[0], 0);
hui su3b1c7662016-01-12 16:38:58 -08002245 if (is_directional_mode) {
2246 int p_angle;
hui su4aa50c12015-11-10 12:09:59 -08002247 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
2248 MAX_ANGLE_DELTAS +
2249 mic->mbmi.angle_delta[0]);
hui su3b1c7662016-01-12 16:38:58 -08002250 p_angle = mode_to_angle_map[mic->mbmi.mode] +
2251 mic->mbmi.angle_delta[0] * ANGLE_STEP;
2252 if (pick_intra_filter(p_angle))
2253 this_rate +=
2254 cpi->intra_filter_cost[intra_filter_ctx][mic->mbmi.intra_filter];
2255 }
hui sube3559b2015-10-07 09:29:02 -07002256#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07002257 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
2258
2259 if (this_rd < best_rd) {
2260 mode_selected = mode;
2261 best_rd = this_rd;
2262 best_tx = mic->mbmi.tx_size;
hui su4aa50c12015-11-10 12:09:59 -08002263#if CONFIG_EXT_INTRA
2264 best_angle_delta = mic->mbmi.angle_delta[0];
hui su3b1c7662016-01-12 16:38:58 -08002265 best_filter = mic->mbmi.intra_filter;
hui su4aa50c12015-11-10 12:09:59 -08002266#endif // CONFIG_EXT_INTRA
hui su4f16f112015-10-02 10:45:27 -07002267 best_tx_type = mic->mbmi.tx_type;
Jingning Han3ee6db62015-08-05 19:00:31 -07002268 *rate = this_rate;
2269 *rate_tokenonly = this_rate_tokenonly;
2270 *distortion = this_distortion;
2271 *skippable = s;
2272 }
2273 }
2274
hui suc93e5cc2015-12-07 18:18:57 -08002275 if (cpi->common.allow_screen_content_tools)
2276 rd_pick_palette_intra_sby(cpi, x, bsize, palette_ctx, bmode_costs[DC_PRED],
2277 &palette_mode_info, best_palette_color_map,
2278 &best_tx, &mode_selected, &best_rd);
2279
hui sube3559b2015-10-07 09:29:02 -07002280#if CONFIG_EXT_INTRA
hui suc93e5cc2015-12-07 18:18:57 -08002281 if (!palette_mode_info.palette_size[0] > 0 && ALLOW_FILTER_INTRA_MODES) {
2282 if (rd_pick_ext_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
2283 skippable, bsize, bmode_costs[DC_PRED],
2284 &best_rd)) {
2285 mode_selected = mic->mbmi.mode;
2286 best_tx = mic->mbmi.tx_size;
2287 ext_intra_mode_info = mic->mbmi.ext_intra_mode_info;
hui suc93e5cc2015-12-07 18:18:57 -08002288 best_tx_type = mic->mbmi.tx_type;
hui suc93e5cc2015-12-07 18:18:57 -08002289 }
hui sube3559b2015-10-07 09:29:02 -07002290 }
2291
2292 mic->mbmi.ext_intra_mode_info.use_ext_intra_mode[0] =
2293 ext_intra_mode_info.use_ext_intra_mode[0];
2294 if (ext_intra_mode_info.use_ext_intra_mode[0]) {
2295 mic->mbmi.ext_intra_mode_info.ext_intra_mode[0] =
2296 ext_intra_mode_info.ext_intra_mode[0];
hui sube3559b2015-10-07 09:29:02 -07002297 }
2298#endif // CONFIG_EXT_INTRA
2299
Jingning Han3ee6db62015-08-05 19:00:31 -07002300 mic->mbmi.mode = mode_selected;
2301 mic->mbmi.tx_size = best_tx;
hui su4aa50c12015-11-10 12:09:59 -08002302#if CONFIG_EXT_INTRA
2303 mic->mbmi.angle_delta[0] = best_angle_delta;
hui su3b1c7662016-01-12 16:38:58 -08002304 mic->mbmi.intra_filter = best_filter;
hui su4aa50c12015-11-10 12:09:59 -08002305#endif // CONFIG_EXT_INTRA
hui su4f16f112015-10-02 10:45:27 -07002306 mic->mbmi.tx_type = best_tx_type;
hui suc93e5cc2015-12-07 18:18:57 -08002307 mic->mbmi.palette_mode_info.palette_size[0] =
2308 palette_mode_info.palette_size[0];
2309 if (palette_mode_info.palette_size[0] > 0) {
2310 memcpy(mic->mbmi.palette_mode_info.palette_colors,
2311 palette_mode_info.palette_colors,
2312 PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
2313 memcpy(xd->plane[0].color_index_map, best_palette_color_map,
2314 rows * cols * sizeof(best_palette_color_map[0]));
2315 }
Jingning Han3ee6db62015-08-05 19:00:31 -07002316
2317 return best_rd;
2318}
2319
Jingning Hana8dad552015-10-08 16:46:10 -07002320#if CONFIG_VAR_TX
Jingning Han4c6c82a2016-02-09 17:51:49 -08002321void vp10_tx_block_rd_b(const VP10_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
2322 int blk_row, int blk_col, int plane, int block,
2323 int plane_bsize, int coeff_ctx,
2324 int *rate, int64_t *dist, int64_t *bsse, int *skip) {
Jingning Han2cdc1272015-10-09 09:57:42 -07002325 MACROBLOCKD *xd = &x->e_mbd;
2326 const struct macroblock_plane *const p = &x->plane[plane];
2327 struct macroblockd_plane *const pd = &xd->plane[plane];
Jingning Han71c15602015-10-13 12:40:39 -07002328 unsigned int tmp_sse = 0;
Jingning Han2cdc1272015-10-09 09:57:42 -07002329 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
2330 PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
2331 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
2332 const scan_order *const scan_order =
2333 get_scan(tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
2334
Jingning Han71c15602015-10-13 12:40:39 -07002335 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
2336 int bh = 4 * num_4x4_blocks_wide_lookup[txm_bsize];
2337 int src_stride = p->src.stride;
2338 uint8_t *src = &p->src.buf[4 * blk_row * src_stride + 4 * blk_col];
2339 uint8_t *dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
Peter de Rivaz22850492015-12-08 15:58:21 +00002340#if CONFIG_VP9_HIGHBITDEPTH
2341 DECLARE_ALIGNED(16, uint16_t, rec_buffer_alloc_16[32 * 32]);
2342 uint8_t *rec_buffer;
Yaowu Xu0c0f3ef2016-02-18 15:42:19 -08002343 const uint32_t hbd_shift = (cpi->common.bit_depth - 8) * 2;
Peter de Rivaz22850492015-12-08 15:58:21 +00002344#else
Jingning Han71c15602015-10-13 12:40:39 -07002345 DECLARE_ALIGNED(16, uint8_t, rec_buffer[32 * 32]);
Peter de Rivaz22850492015-12-08 15:58:21 +00002346#endif
Geza Loreabd00502016-02-12 16:04:35 +00002347 const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
2348 const int16_t *diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
Jingning Han71c15602015-10-13 12:40:39 -07002349
2350 int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
2351 int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
2352
2353 if (xd->mb_to_bottom_edge < 0)
2354 max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
2355 if (xd->mb_to_right_edge < 0)
2356 max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
2357
Angie Chiang88cae8b2015-11-25 13:07:13 -08002358 vp10_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
2359 VP10_XFORM_QUANT_B);
Jingning Han2cdc1272015-10-09 09:57:42 -07002360
Peter de Rivaz22850492015-12-08 15:58:21 +00002361#if CONFIG_VP9_HIGHBITDEPTH
2362 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2363 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer_alloc_16);
2364 vpx_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, 32,
2365 NULL, 0, NULL, 0, bh, bh, xd->bd);
2366 } else {
2367 rec_buffer = (uint8_t *)rec_buffer_alloc_16;
2368 vpx_convolve_copy(dst, pd->dst.stride, rec_buffer, 32,
2369 NULL, 0, NULL, 0, bh, bh);
2370 }
2371#else
Jingning Han71c15602015-10-13 12:40:39 -07002372 vpx_convolve_copy(dst, pd->dst.stride, rec_buffer, 32,
2373 NULL, 0, NULL, 0, bh, bh);
Peter de Rivaz22850492015-12-08 15:58:21 +00002374#endif
Jingning Han71c15602015-10-13 12:40:39 -07002375
2376 if (blk_row + (bh >> 2) > max_blocks_high ||
2377 blk_col + (bh >> 2) > max_blocks_wide) {
2378 int idx, idy;
Jingning Han71c15602015-10-13 12:40:39 -07002379 int blocks_height = VPXMIN(bh >> 2, max_blocks_high - blk_row);
2380 int blocks_width = VPXMIN(bh >> 2, max_blocks_wide - blk_col);
2381 for (idy = 0; idy < blocks_height; idy += 2) {
2382 for (idx = 0; idx < blocks_width; idx += 2) {
Geza Loreabd00502016-02-12 16:04:35 +00002383 const int16_t *d = diff + 4 * idy * diff_stride + 4 * idx;
Yaowu Xu0c0f3ef2016-02-18 15:42:19 -08002384#if CONFIG_VP9_HIGHBITDEPTH
2385 tmp_sse += ROUND_POWER_OF_TWO(
2386 vpx_sum_squares_2d_i16(d, diff_stride, 8), hbd_shift);
2387#else
Geza Loreabd00502016-02-12 16:04:35 +00002388 tmp_sse += vpx_sum_squares_2d_i16(d, diff_stride, 8);
Yaowu Xu0c0f3ef2016-02-18 15:42:19 -08002389#endif
Jingning Han71c15602015-10-13 12:40:39 -07002390 }
2391 }
2392 } else {
Yaowu Xu0c0f3ef2016-02-18 15:42:19 -08002393#if CONFIG_VP9_HIGHBITDEPTH
2394 tmp_sse = ROUND_POWER_OF_TWO(
2395 vpx_sum_squares_2d_i16(diff, diff_stride, bh), hbd_shift);
2396#else
Geza Loreabd00502016-02-12 16:04:35 +00002397 tmp_sse = vpx_sum_squares_2d_i16(diff, diff_stride, bh);
Yaowu Xu0c0f3ef2016-02-18 15:42:19 -08002398#endif
Jingning Han71c15602015-10-13 12:40:39 -07002399 }
2400
Jingning Han71c15602015-10-13 12:40:39 -07002401 *bsse += (int64_t)tmp_sse * 16;
2402
2403 if (p->eobs[block] > 0) {
Geza Lore432e8752016-01-22 13:57:28 +00002404 const int lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
2405#if CONFIG_VP9_HIGHBITDEPTH
2406 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2407 const int bd = xd->bd;
2408 switch (tx_size) {
2409 case TX_32X32:
2410 vp10_highbd_inv_txfm_add_32x32(dqcoeff, rec_buffer, 32,
2411 p->eobs[block], bd, tx_type);
2412 break;
2413 case TX_16X16:
2414 vp10_highbd_inv_txfm_add_16x16(dqcoeff, rec_buffer, 32,
2415 p->eobs[block], bd, tx_type);
2416 break;
2417 case TX_8X8:
2418 vp10_highbd_inv_txfm_add_8x8(dqcoeff, rec_buffer, 32,
2419 p->eobs[block], bd, tx_type);
2420 break;
2421 case TX_4X4:
2422 vp10_highbd_inv_txfm_add_4x4(dqcoeff, rec_buffer, 32,
2423 p->eobs[block], bd, tx_type, lossless);
2424 break;
2425 default:
2426 assert(0 && "Invalid transform size");
2427 break;
2428 }
2429 } else {
2430#else
2431 {
2432#endif // CONFIG_VP9_HIGHBITDEPTH
2433 switch (tx_size) {
2434 case TX_32X32:
2435 vp10_inv_txfm_add_32x32(dqcoeff, rec_buffer, 32, p->eobs[block],
2436 tx_type);
2437 break;
2438 case TX_16X16:
2439 vp10_inv_txfm_add_16x16(dqcoeff, rec_buffer, 32, p->eobs[block],
2440 tx_type);
2441 break;
2442 case TX_8X8:
2443 vp10_inv_txfm_add_8x8(dqcoeff, rec_buffer, 32, p->eobs[block],
Jingning Han71c15602015-10-13 12:40:39 -07002444 tx_type);
Geza Lore432e8752016-01-22 13:57:28 +00002445 break;
2446 case TX_4X4:
2447 vp10_inv_txfm_add_4x4(dqcoeff, rec_buffer, 32, p->eobs[block],
2448 tx_type, lossless);
2449 break;
2450 default:
2451 assert(0 && "Invalid transform size");
2452 break;
2453 }
Jingning Han71c15602015-10-13 12:40:39 -07002454 }
2455
2456 if ((bh >> 2) + blk_col > max_blocks_wide ||
2457 (bh >> 2) + blk_row > max_blocks_high) {
2458 int idx, idy;
2459 unsigned int this_sse;
2460 int blocks_height = VPXMIN(bh >> 2, max_blocks_high - blk_row);
2461 int blocks_width = VPXMIN(bh >> 2, max_blocks_wide - blk_col);
2462 tmp_sse = 0;
2463 for (idy = 0; idy < blocks_height; idy += 2) {
2464 for (idx = 0; idx < blocks_width; idx += 2) {
2465 cpi->fn_ptr[BLOCK_8X8].vf(src + 4 * idy * src_stride + 4 * idx,
2466 src_stride,
2467 rec_buffer + 4 * idy * 32 + 4 * idx,
2468 32, &this_sse);
2469 tmp_sse += this_sse;
2470 }
2471 }
2472 } else {
2473 cpi->fn_ptr[txm_bsize].vf(src, src_stride,
2474 rec_buffer, 32, &tmp_sse);
2475 }
2476 }
2477 *dist += (int64_t)tmp_sse * 16;
Jingning Han2cdc1272015-10-09 09:57:42 -07002478
2479 *rate += cost_coeffs(x, plane, block, coeff_ctx, tx_size,
2480 scan_order->scan, scan_order->neighbors, 0);
2481 *skip &= (p->eobs[block] == 0);
2482}
2483
2484static void select_tx_block(const VP10_COMP *cpi, MACROBLOCK *x,
2485 int blk_row, int blk_col, int plane, int block,
2486 TX_SIZE tx_size, BLOCK_SIZE plane_bsize,
Jingning Han2cdc1272015-10-09 09:57:42 -07002487 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
Jingning Han3edad6e2015-10-14 09:38:17 -07002488 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
Jingning Han2cdc1272015-10-09 09:57:42 -07002489 int *rate, int64_t *dist,
Jingning Han1e48f742015-10-13 11:59:49 -07002490 int64_t *bsse, int *skip,
2491 int64_t ref_best_rd, int *is_cost_valid) {
Jingning Han2cdc1272015-10-09 09:57:42 -07002492 MACROBLOCKD *const xd = &x->e_mbd;
2493 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2494 struct macroblock_plane *const p = &x->plane[plane];
2495 struct macroblockd_plane *const pd = &xd->plane[plane];
2496 int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
2497 (blk_col >> (1 - pd->subsampling_x));
2498 int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
2499 int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
2500 int64_t this_rd = INT64_MAX;
Jingning Han2cdc1272015-10-09 09:57:42 -07002501 ENTROPY_CONTEXT *pta = ta + blk_col;
2502 ENTROPY_CONTEXT *ptl = tl + blk_row;
Jingning Han3a279612015-10-12 19:20:58 -07002503 ENTROPY_CONTEXT stxa = 0, stxl = 0;
Jingning Han2cdc1272015-10-09 09:57:42 -07002504 int coeff_ctx, i;
Jingning Han3edad6e2015-10-14 09:38:17 -07002505 int ctx = txfm_partition_context(tx_above + (blk_col >> 1),
2506 tx_left + (blk_row >> 1), tx_size);
2507
Jingning Han3a279612015-10-12 19:20:58 -07002508 int64_t sum_dist = 0, sum_bsse = 0;
2509 int64_t sum_rd = INT64_MAX;
Jingning Han3edad6e2015-10-14 09:38:17 -07002510 int sum_rate = vp10_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Jingning Han3a279612015-10-12 19:20:58 -07002511 int all_skip = 1;
Jingning Han1e48f742015-10-13 11:59:49 -07002512 int tmp_eob = 0;
Jingning Hanbfeac5e2015-10-15 23:11:30 -07002513 int zero_blk_rate;
Jingning Han1e48f742015-10-13 11:59:49 -07002514
2515 if (ref_best_rd < 0) {
2516 *is_cost_valid = 0;
2517 return;
2518 }
Jingning Han2cdc1272015-10-09 09:57:42 -07002519
2520 switch (tx_size) {
2521 case TX_4X4:
Jingning Han3a279612015-10-12 19:20:58 -07002522 stxa = pta[0];
2523 stxl = ptl[0];
Jingning Han2cdc1272015-10-09 09:57:42 -07002524 break;
2525 case TX_8X8:
Jingning Han3a279612015-10-12 19:20:58 -07002526 stxa = !!*(const uint16_t *)&pta[0];
2527 stxl = !!*(const uint16_t *)&ptl[0];
Jingning Han2cdc1272015-10-09 09:57:42 -07002528 break;
2529 case TX_16X16:
Jingning Han3a279612015-10-12 19:20:58 -07002530 stxa = !!*(const uint32_t *)&pta[0];
2531 stxl = !!*(const uint32_t *)&ptl[0];
Jingning Han2cdc1272015-10-09 09:57:42 -07002532 break;
2533 case TX_32X32:
Jingning Han3a279612015-10-12 19:20:58 -07002534 stxa = !!*(const uint64_t *)&pta[0];
2535 stxl = !!*(const uint64_t *)&ptl[0];
Jingning Han2cdc1272015-10-09 09:57:42 -07002536 break;
2537 default:
2538 assert(0 && "Invalid transform size.");
2539 break;
2540 }
Jingning Han3a279612015-10-12 19:20:58 -07002541 coeff_ctx = combine_entropy_contexts(stxa, stxl);
Jingning Han2cdc1272015-10-09 09:57:42 -07002542
2543 if (xd->mb_to_bottom_edge < 0)
2544 max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
2545 if (xd->mb_to_right_edge < 0)
2546 max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
2547
2548 *rate = 0;
2549 *dist = 0;
2550 *bsse = 0;
2551 *skip = 1;
2552
2553 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
2554 return;
2555
Jingning Hanbfeac5e2015-10-15 23:11:30 -07002556 zero_blk_rate =
2557 x->token_costs[tx_size][pd->plane_type][1][0][0][coeff_ctx][EOB_TOKEN];
2558
Jingning Han1e48f742015-10-13 11:59:49 -07002559 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
2560 mbmi->inter_tx_size[tx_idx] = tx_size;
Jingning Han4c6c82a2016-02-09 17:51:49 -08002561 vp10_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
2562 plane_bsize, coeff_ctx, rate, dist, bsse, skip);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07002563
Jingning Han47c7fd92015-10-30 13:00:48 -07002564 if ((RDCOST(x->rdmult, x->rddiv, *rate, *dist) >=
2565 RDCOST(x->rdmult, x->rddiv, zero_blk_rate, *bsse) || *skip == 1) &&
Jingning Hanbfeac5e2015-10-15 23:11:30 -07002566 !xd->lossless[mbmi->segment_id]) {
2567 *rate = zero_blk_rate;
2568 *dist = *bsse;
2569 *skip = 1;
2570 x->blk_skip[plane][blk_row * max_blocks_wide + blk_col] = 1;
2571 p->eobs[block] = 0;
2572 } else {
2573 x->blk_skip[plane][blk_row * max_blocks_wide + blk_col] = 0;
2574 *skip = 0;
2575 }
2576
Jingning Han1e48f742015-10-13 11:59:49 -07002577 if (tx_size > TX_4X4)
Jingning Han3edad6e2015-10-14 09:38:17 -07002578 *rate += vp10_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
Jingning Han1e48f742015-10-13 11:59:49 -07002579 this_rd = RDCOST(x->rdmult, x->rddiv, *rate, *dist);
2580 tmp_eob = p->eobs[block];
2581 }
2582
Jingning Han2cdc1272015-10-09 09:57:42 -07002583 if (tx_size > TX_4X4) {
2584 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
Jingning Han3a279612015-10-12 19:20:58 -07002585 int bsl = b_height_log2_lookup[bsize];
Jingning Han2cdc1272015-10-09 09:57:42 -07002586 int sub_step = 1 << (2 * (tx_size - 1));
2587 int i;
Jingning Han3a279612015-10-12 19:20:58 -07002588 int this_rate;
2589 int64_t this_dist;
2590 int64_t this_bsse;
2591 int this_skip;
Jingning Han1e48f742015-10-13 11:59:49 -07002592 int this_cost_valid = 1;
2593 int64_t tmp_rd = 0;
Jingning Han3a279612015-10-12 19:20:58 -07002594
2595 --bsl;
Jingning Han236623c2015-10-26 19:39:30 -07002596 for (i = 0; i < 4 && this_cost_valid; ++i) {
Jingning Han3a279612015-10-12 19:20:58 -07002597 int offsetr = (i >> 1) << bsl;
2598 int offsetc = (i & 0x01) << bsl;
Jingning Han2cdc1272015-10-09 09:57:42 -07002599 select_tx_block(cpi, x, blk_row + offsetr, blk_col + offsetc,
2600 plane, block + i * sub_step, tx_size - 1,
Jingning Han3edad6e2015-10-14 09:38:17 -07002601 plane_bsize, ta, tl, tx_above, tx_left,
2602 &this_rate, &this_dist,
Jingning Han1e48f742015-10-13 11:59:49 -07002603 &this_bsse, &this_skip,
2604 ref_best_rd - tmp_rd, &this_cost_valid);
Jingning Han2cdc1272015-10-09 09:57:42 -07002605 sum_rate += this_rate;
2606 sum_dist += this_dist;
2607 sum_bsse += this_bsse;
2608 all_skip &= this_skip;
Peter de Rivaz2f943132016-01-05 15:35:43 +00002609 tmp_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
Jingning Han1e48f742015-10-13 11:59:49 -07002610 if (this_rd < tmp_rd)
2611 break;
Jingning Han2cdc1272015-10-09 09:57:42 -07002612 }
Jingning Han1e48f742015-10-13 11:59:49 -07002613 if (this_cost_valid)
2614 sum_rd = tmp_rd;
Jingning Han3a279612015-10-12 19:20:58 -07002615 }
2616
2617 if (this_rd < sum_rd) {
Jingning Han79fe7242015-10-23 14:27:21 -07002618 int idx, idy;
Jingning Han3a279612015-10-12 19:20:58 -07002619 for (i = 0; i < (1 << tx_size); ++i)
Jingning Han1e48f742015-10-13 11:59:49 -07002620 pta[i] = ptl[i] = !(tmp_eob == 0);
Jingning Han3edad6e2015-10-14 09:38:17 -07002621 txfm_partition_update(tx_above + (blk_col >> 1),
2622 tx_left + (blk_row >> 1), tx_size);
Jingning Han1e48f742015-10-13 11:59:49 -07002623 mbmi->inter_tx_size[tx_idx] = tx_size;
Jingning Han79fe7242015-10-23 14:27:21 -07002624
2625 for (idy = 0; idy < (1 << tx_size) / 2; ++idy)
2626 for (idx = 0; idx < (1 << tx_size) / 2; ++idx)
2627 mbmi->inter_tx_size[tx_idx + (idy << 3) + idx] = tx_size;
Jingning Han3a279612015-10-12 19:20:58 -07002628 mbmi->tx_size = tx_size;
Jingning Han236623c2015-10-26 19:39:30 -07002629 if (this_rd == INT64_MAX)
2630 *is_cost_valid = 0;
Jingning Hanbfeac5e2015-10-15 23:11:30 -07002631 x->blk_skip[plane][blk_row * max_blocks_wide + blk_col] = *skip;
Jingning Han3a279612015-10-12 19:20:58 -07002632 } else {
2633 *rate = sum_rate;
2634 *dist = sum_dist;
2635 *bsse = sum_bsse;
2636 *skip = all_skip;
Jingning Han236623c2015-10-26 19:39:30 -07002637 if (sum_rd == INT64_MAX)
2638 *is_cost_valid = 0;
Jingning Han2cdc1272015-10-09 09:57:42 -07002639 }
2640}
2641
2642static void inter_block_yrd(const VP10_COMP *cpi, MACROBLOCK *x,
2643 int *rate, int64_t *distortion, int *skippable,
2644 int64_t *sse, BLOCK_SIZE bsize,
2645 int64_t ref_best_rd) {
2646 MACROBLOCKD *const xd = &x->e_mbd;
2647 int is_cost_valid = 1;
Jingning Han1e48f742015-10-13 11:59:49 -07002648 int64_t this_rd = 0;
Jingning Han2cdc1272015-10-09 09:57:42 -07002649
2650 if (ref_best_rd < 0)
2651 is_cost_valid = 0;
2652
2653 *rate = 0;
2654 *distortion = 0;
2655 *sse = 0;
2656 *skippable = 1;
2657
2658 if (is_cost_valid) {
2659 const struct macroblockd_plane *const pd = &xd->plane[0];
2660 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
2661 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
2662 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
2663 BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[plane_bsize]];
2664 int bh = num_4x4_blocks_wide_lookup[txb_size];
2665 int idx, idy;
2666 int block = 0;
2667 int step = 1 << (max_txsize_lookup[plane_bsize] * 2);
2668 ENTROPY_CONTEXT ctxa[16], ctxl[16];
Jingning Han3edad6e2015-10-14 09:38:17 -07002669 TXFM_CONTEXT tx_above[8], tx_left[8];
Jingning Han2cdc1272015-10-09 09:57:42 -07002670
2671 int pnrate = 0, pnskip = 1;
2672 int64_t pndist = 0, pnsse = 0;
2673
2674 vp10_get_entropy_contexts(bsize, TX_4X4, pd, ctxa, ctxl);
Jingning Han3edad6e2015-10-14 09:38:17 -07002675 memcpy(tx_above, xd->above_txfm_context,
2676 sizeof(TXFM_CONTEXT) * (mi_width >> 1));
2677 memcpy(tx_left, xd->left_txfm_context,
2678 sizeof(TXFM_CONTEXT) * (mi_height >> 1));
Jingning Han2cdc1272015-10-09 09:57:42 -07002679
2680 for (idy = 0; idy < mi_height; idy += bh) {
2681 for (idx = 0; idx < mi_width; idx += bh) {
2682 select_tx_block(cpi, x, idy, idx, 0, block,
Jingning Han3a279612015-10-12 19:20:58 -07002683 max_txsize_lookup[plane_bsize], plane_bsize,
Jingning Han3edad6e2015-10-14 09:38:17 -07002684 ctxa, ctxl, tx_above, tx_left,
2685 &pnrate, &pndist, &pnsse, &pnskip,
Jingning Han1e48f742015-10-13 11:59:49 -07002686 ref_best_rd - this_rd, &is_cost_valid);
Jingning Han2cdc1272015-10-09 09:57:42 -07002687 *rate += pnrate;
2688 *distortion += pndist;
2689 *sse += pnsse;
2690 *skippable &= pnskip;
Jingning Han1e48f742015-10-13 11:59:49 -07002691 this_rd += VPXMIN(RDCOST(x->rdmult, x->rddiv, pnrate, pndist),
2692 RDCOST(x->rdmult, x->rddiv, 0, pnsse));
Jingning Han2cdc1272015-10-09 09:57:42 -07002693 block += step;
2694 }
2695 }
2696 }
2697
2698 this_rd = VPXMIN(RDCOST(x->rdmult, x->rddiv, *rate, *distortion),
2699 RDCOST(x->rdmult, x->rddiv, 0, *sse));
2700 if (this_rd > ref_best_rd)
2701 is_cost_valid = 0;
2702
2703 if (!is_cost_valid) {
2704 // reset cost value
2705 *rate = INT_MAX;
2706 *distortion = INT64_MAX;
2707 *sse = INT64_MAX;
2708 *skippable = 0;
2709 }
2710}
2711
Jingning Han4b594d32015-11-02 12:05:47 -08002712static void select_tx_type_yrd(const VP10_COMP *cpi, MACROBLOCK *x,
2713 int *rate, int64_t *distortion, int *skippable,
2714 int64_t *sse, BLOCK_SIZE bsize,
2715 int64_t ref_best_rd) {
2716 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
2717 const VP10_COMMON *const cm = &cpi->common;
2718 MACROBLOCKD *const xd = &x->e_mbd;
2719 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2720 int64_t rd = INT64_MAX;
2721 int64_t best_rd = INT64_MAX;
2722 TX_TYPE tx_type, best_tx_type = DCT_DCT;
Jingning Han4b594d32015-11-02 12:05:47 -08002723 const int is_inter = is_inter_block(mbmi);
2724 vpx_prob skip_prob = vp10_get_skip_prob(cm, xd);
2725 int s0 = vp10_cost_bit(skip_prob, 0);
2726 int s1 = vp10_cost_bit(skip_prob, 1);
Jingning Han696ee002015-11-03 08:56:47 -08002727 TX_SIZE best_tx_size[64];
Jingning Han493d0232015-11-03 12:59:24 -08002728 TX_SIZE best_tx = TX_SIZES;
2729 uint8_t best_blk_skip[256];
2730 const int n4 = 1 << (num_pels_log2_lookup[bsize] - 4);
Jingning Han696ee002015-11-03 08:56:47 -08002731 int idx, idy;
Julia Robson9fe188e2016-01-21 17:14:29 +00002732#if CONFIG_EXT_TX
2733 int ext_tx_set = get_ext_tx_set(max_tx_size, bsize, is_inter);
2734#endif
Jingning Han4b594d32015-11-02 12:05:47 -08002735
2736 *distortion = INT64_MAX;
2737 *rate = INT_MAX;
2738 *skippable = 0;
2739 *sse = INT64_MAX;
2740
2741 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
2742 int this_rate = 0;
2743 int this_skip = 1;
2744 int64_t this_dist = 0;
2745 int64_t this_sse = 0;
Julia Robson9fe188e2016-01-21 17:14:29 +00002746#if CONFIG_EXT_TX
Jingning Han4b594d32015-11-02 12:05:47 -08002747 if (is_inter) {
2748 if (!ext_tx_used_inter[ext_tx_set][tx_type])
2749 continue;
2750 } else {
hui sud894d342015-11-18 11:24:26 -08002751 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
Yaowu Xu0367f322016-01-11 10:27:35 -08002752 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode])
hui sud894d342015-11-18 11:24:26 -08002753 continue;
2754 }
Jingning Han4b594d32015-11-02 12:05:47 -08002755 if (!ext_tx_used_intra[ext_tx_set][tx_type])
2756 continue;
2757 }
2758
2759 mbmi->tx_type = tx_type;
2760
2761 if (ext_tx_set == 1 &&
2762 mbmi->tx_type >= DST_ADST && mbmi->tx_type < IDTX &&
2763 best_tx_type == DCT_DCT) {
2764 tx_type = IDTX - 1;
2765 break;
2766 }
2767
2768 inter_block_yrd(cpi, x, &this_rate, &this_dist, &this_skip, &this_sse,
2769 bsize, ref_best_rd);
2770
2771 if (get_ext_tx_types(max_tx_size, bsize, is_inter) > 1 &&
2772 !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
2773 this_rate != INT_MAX) {
2774 if (is_inter) {
2775 if (ext_tx_set > 0)
2776 this_rate += cpi->inter_tx_type_costs[ext_tx_set]
Jingning Han696ee002015-11-03 08:56:47 -08002777 [max_tx_size][mbmi->tx_type];
Jingning Han4b594d32015-11-02 12:05:47 -08002778 } else {
hui sud894d342015-11-18 11:24:26 -08002779 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Jingning Han696ee002015-11-03 08:56:47 -08002780 this_rate += cpi->intra_tx_type_costs[ext_tx_set][max_tx_size]
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08002781 [mbmi->mode][mbmi->tx_type];
Jingning Han4b594d32015-11-02 12:05:47 -08002782 }
2783 }
Julia Robson9fe188e2016-01-21 17:14:29 +00002784#else // CONFIG_EXT_TX
Jingning Han5c772f32016-02-10 11:33:37 -08002785 if (max_tx_size >= TX_32X32 && tx_type != DCT_DCT)
Julia Robson9fe188e2016-01-21 17:14:29 +00002786 continue;
Jingning Han5c772f32016-02-10 11:33:37 -08002787
Julia Robson9fe188e2016-01-21 17:14:29 +00002788 mbmi->tx_type = tx_type;
2789
2790 inter_block_yrd(cpi, x, &this_rate, &this_dist, &this_skip, &this_sse,
2791 bsize, ref_best_rd);
2792
2793 if (max_tx_size < TX_32X32 &&
2794 !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
2795 this_rate != INT_MAX) {
2796 if (is_inter)
2797 this_rate += cpi->inter_tx_type_costs[max_tx_size][mbmi->tx_type];
2798 else
2799 this_rate += cpi->intra_tx_type_costs[max_tx_size]
2800 [intra_mode_to_tx_type_context[mbmi->mode]]
2801 [mbmi->tx_type];
2802 }
2803#endif // CONFIG_EXT_TX
Jingning Han4b594d32015-11-02 12:05:47 -08002804
2805 if (this_rate == INT_MAX)
2806 continue;
2807
2808 if (this_skip)
2809 rd = RDCOST(x->rdmult, x->rddiv, s1, this_sse);
2810 else
2811 rd = RDCOST(x->rdmult, x->rddiv, this_rate + s0, this_dist);
2812
2813 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] && !this_skip)
2814 rd = VPXMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, this_sse));
2815
Jingning Han5c772f32016-02-10 11:33:37 -08002816 if (rd < (is_inter && best_tx_type == DCT_DCT ? ext_tx_th : 1) * best_rd) {
Jingning Han4b594d32015-11-02 12:05:47 -08002817 best_rd = rd;
2818 *distortion = this_dist;
2819 *rate = this_rate;
2820 *skippable = this_skip;
2821 *sse = this_sse;
2822 best_tx_type = mbmi->tx_type;
Jingning Han493d0232015-11-03 12:59:24 -08002823 best_tx = mbmi->tx_size;
2824 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
Jingning Han696ee002015-11-03 08:56:47 -08002825 for (idy = 0; idy < xd->n8_h; ++idy)
2826 for (idx = 0; idx < xd->n8_w; ++idx)
2827 best_tx_size[idy * 8 + idx] = mbmi->inter_tx_size[idy * 8 + idx];
Jingning Han4b594d32015-11-02 12:05:47 -08002828 }
2829 }
2830
2831 mbmi->tx_type = best_tx_type;
Jingning Han696ee002015-11-03 08:56:47 -08002832 for (idy = 0; idy < xd->n8_h; ++idy)
2833 for (idx = 0; idx < xd->n8_w; ++idx)
2834 mbmi->inter_tx_size[idy * 8 + idx] = best_tx_size[idy * 8 + idx];
Jingning Han493d0232015-11-03 12:59:24 -08002835 mbmi->tx_size = best_tx;
2836 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
Jingning Han4b594d32015-11-02 12:05:47 -08002837}
Jingning Han4b594d32015-11-02 12:05:47 -08002838
Jingning Hana8dad552015-10-08 16:46:10 -07002839static void tx_block_rd(const VP10_COMP *cpi, MACROBLOCK *x,
2840 int blk_row, int blk_col, int plane, int block,
2841 TX_SIZE tx_size, BLOCK_SIZE plane_bsize,
2842 ENTROPY_CONTEXT *above_ctx, ENTROPY_CONTEXT *left_ctx,
2843 int *rate, int64_t *dist, int64_t *bsse, int *skip) {
2844 MACROBLOCKD *const xd = &x->e_mbd;
2845 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Jingning Han2cdc1272015-10-09 09:57:42 -07002846 struct macroblock_plane *const p = &x->plane[plane];
Jingning Hana8dad552015-10-08 16:46:10 -07002847 struct macroblockd_plane *const pd = &xd->plane[plane];
Jingning Han2cdc1272015-10-09 09:57:42 -07002848 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
Jingning Hana8dad552015-10-08 16:46:10 -07002849 int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
2850 (blk_col >> (1 - pd->subsampling_x));
2851 TX_SIZE plane_tx_size = plane ?
Jingning Han2cdc1272015-10-09 09:57:42 -07002852 get_uv_tx_size_impl(mbmi->inter_tx_size[tx_idx], bsize,
2853 0, 0) :
Jingning Hana8dad552015-10-08 16:46:10 -07002854 mbmi->inter_tx_size[tx_idx];
2855
2856 int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
2857 int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
2858
2859 if (xd->mb_to_bottom_edge < 0)
2860 max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
2861 if (xd->mb_to_right_edge < 0)
2862 max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
2863
2864 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
2865 return;
2866
2867 if (tx_size == plane_tx_size) {
Jingning Han2cdc1272015-10-09 09:57:42 -07002868 int coeff_ctx, i;
Jingning Hana8dad552015-10-08 16:46:10 -07002869 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
Jingning Han2cdc1272015-10-09 09:57:42 -07002870 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
Jingning Hana8dad552015-10-08 16:46:10 -07002871 switch (tx_size) {
2872 case TX_4X4:
2873 break;
2874 case TX_8X8:
2875 ta[0] = !!*(const uint16_t *)&ta[0];
2876 tl[0] = !!*(const uint16_t *)&tl[0];
2877 break;
2878 case TX_16X16:
2879 ta[0] = !!*(const uint32_t *)&ta[0];
2880 tl[0] = !!*(const uint32_t *)&tl[0];
2881 break;
2882 case TX_32X32:
2883 ta[0] = !!*(const uint64_t *)&ta[0];
2884 tl[0] = !!*(const uint64_t *)&tl[0];
2885 break;
2886 default:
2887 assert(0 && "Invalid transform size.");
2888 break;
2889 }
Jingning Han2cdc1272015-10-09 09:57:42 -07002890 coeff_ctx = combine_entropy_contexts(ta[0], tl[0]);
Jingning Han4c6c82a2016-02-09 17:51:49 -08002891 vp10_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
2892 plane_bsize, coeff_ctx, rate, dist, bsse, skip);
Jingning Hana8dad552015-10-08 16:46:10 -07002893 for (i = 0; i < (1 << tx_size); ++i) {
Jingning Han2cdc1272015-10-09 09:57:42 -07002894 ta[i] = !(p->eobs[block] == 0);
2895 tl[i] = !(p->eobs[block] == 0);
Jingning Hana8dad552015-10-08 16:46:10 -07002896 }
Jingning Hana8dad552015-10-08 16:46:10 -07002897 } else {
Jingning Hana8dad552015-10-08 16:46:10 -07002898 int bsl = b_width_log2_lookup[bsize];
2899 int step = 1 << (2 * (tx_size - 1));
2900 int i;
2901
2902 assert(bsl > 0);
2903 --bsl;
2904
2905 for (i = 0; i < 4; ++i) {
2906 int offsetr = (i >> 1) << bsl;
2907 int offsetc = (i & 0x01) << bsl;
2908 tx_block_rd(cpi, x, blk_row + offsetr, blk_col + offsetc, plane,
2909 block + i * step, tx_size - 1, plane_bsize,
2910 above_ctx, left_ctx, rate, dist, bsse, skip);
2911 }
2912 }
2913}
2914
2915// Return value 0: early termination triggered, no valid rd cost available;
2916// 1: rd cost values are valid.
2917static int inter_block_uvrd(const VP10_COMP *cpi, MACROBLOCK *x,
2918 int *rate, int64_t *distortion, int *skippable,
2919 int64_t *sse, BLOCK_SIZE bsize,
2920 int64_t ref_best_rd) {
2921 MACROBLOCKD *const xd = &x->e_mbd;
2922 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2923 int plane;
2924 int is_cost_valid = 1;
2925 int64_t this_rd;
2926
2927 if (ref_best_rd < 0)
2928 is_cost_valid = 0;
2929
2930 if (is_inter_block(mbmi) && is_cost_valid) {
2931 int plane;
2932 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
2933 vp10_subtract_plane(x, bsize, plane);
2934 }
2935
2936 *rate = 0;
2937 *distortion = 0;
2938 *sse = 0;
2939 *skippable = 1;
2940
2941 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
2942 const struct macroblockd_plane *const pd = &xd->plane[plane];
2943 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
2944 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
2945 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
2946 BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[plane_bsize]];
2947 int bh = num_4x4_blocks_wide_lookup[txb_size];
2948 int idx, idy;
2949 int block = 0;
2950 int step = 1 << (max_txsize_lookup[plane_bsize] * 2);
2951 int pnrate = 0, pnskip = 1;
2952 int64_t pndist = 0, pnsse = 0;
2953 ENTROPY_CONTEXT ta[16], tl[16];
2954
2955 vp10_get_entropy_contexts(bsize, TX_4X4, pd, ta, tl);
2956
2957 for (idy = 0; idy < mi_height; idy += bh) {
2958 for (idx = 0; idx < mi_width; idx += bh) {
2959 tx_block_rd(cpi, x, idy, idx, plane, block,
2960 max_txsize_lookup[plane_bsize], plane_bsize, ta, tl,
2961 &pnrate, &pndist, &pnsse, &pnskip);
2962 block += step;
2963 }
2964 }
2965
2966 if (pnrate == INT_MAX) {
2967 is_cost_valid = 0;
2968 break;
2969 }
2970
2971 *rate += pnrate;
2972 *distortion += pndist;
2973 *sse += pnsse;
2974 *skippable &= pnskip;
2975
2976 this_rd = VPXMIN(RDCOST(x->rdmult, x->rddiv, *rate, *distortion),
2977 RDCOST(x->rdmult, x->rddiv, 0, *sse));
2978
2979 if (this_rd > ref_best_rd) {
2980 is_cost_valid = 0;
2981 break;
2982 }
2983 }
2984
2985 if (!is_cost_valid) {
2986 // reset cost value
2987 *rate = INT_MAX;
2988 *distortion = INT64_MAX;
2989 *sse = INT64_MAX;
2990 *skippable = 0;
2991 }
2992
2993 return is_cost_valid;
2994}
2995#endif
2996
Jingning Han3ee6db62015-08-05 19:00:31 -07002997// Return value 0: early termination triggered, no valid rd cost available;
2998// 1: rd cost values are valid.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07002999static int super_block_uvrd(const VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003000 int *rate, int64_t *distortion, int *skippable,
3001 int64_t *sse, BLOCK_SIZE bsize,
3002 int64_t ref_best_rd) {
3003 MACROBLOCKD *const xd = &x->e_mbd;
3004 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3005 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
3006 int plane;
3007 int pnrate = 0, pnskip = 1;
3008 int64_t pndist = 0, pnsse = 0;
3009 int is_cost_valid = 1;
3010
3011 if (ref_best_rd < 0)
3012 is_cost_valid = 0;
3013
3014 if (is_inter_block(mbmi) && is_cost_valid) {
3015 int plane;
3016 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
3017 vp10_subtract_plane(x, bsize, plane);
3018 }
3019
3020 *rate = 0;
3021 *distortion = 0;
3022 *sse = 0;
3023 *skippable = 1;
3024
3025 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
Jingning Han71c15602015-10-13 12:40:39 -07003026 txfm_rd_in_plane(x,
3027#if CONFIG_VAR_TX
3028 cpi,
3029#endif
3030 &pnrate, &pndist, &pnskip, &pnsse,
Jingning Han3ee6db62015-08-05 19:00:31 -07003031 ref_best_rd, plane, bsize, uv_tx_size,
3032 cpi->sf.use_fast_coef_costing);
3033 if (pnrate == INT_MAX) {
3034 is_cost_valid = 0;
3035 break;
3036 }
3037 *rate += pnrate;
3038 *distortion += pndist;
3039 *sse += pnsse;
3040 *skippable &= pnskip;
3041 }
3042
3043 if (!is_cost_valid) {
3044 // reset cost value
3045 *rate = INT_MAX;
3046 *distortion = INT64_MAX;
3047 *sse = INT64_MAX;
3048 *skippable = 0;
3049 }
3050
3051 return is_cost_valid;
3052}
3053
hui sube3559b2015-10-07 09:29:02 -07003054#if CONFIG_EXT_INTRA
3055// Return 1 if an ext intra mode is selected; return 0 otherwise.
3056static int rd_pick_ext_intra_sbuv(VP10_COMP *cpi, MACROBLOCK *x,
3057 PICK_MODE_CONTEXT *ctx,
3058 int *rate, int *rate_tokenonly,
3059 int64_t *distortion, int *skippable,
3060 BLOCK_SIZE bsize, int64_t *best_rd) {
3061 MACROBLOCKD *const xd = &x->e_mbd;
3062 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
3063 int ext_intra_selected_flag = 0;
3064 int this_rate_tokenonly, this_rate, s;
hui su4aa50c12015-11-10 12:09:59 -08003065 int64_t this_distortion, this_sse, this_rd;
hui sube3559b2015-10-07 09:29:02 -07003066 EXT_INTRA_MODE mode;
hui sube3559b2015-10-07 09:29:02 -07003067 EXT_INTRA_MODE_INFO ext_intra_mode_info;
3068
3069 vp10_zero(ext_intra_mode_info);
3070 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 1;
3071 mbmi->uv_mode = DC_PRED;
3072
hui su4aa50c12015-11-10 12:09:59 -08003073 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
3074 mbmi->ext_intra_mode_info.ext_intra_mode[1] = mode;
3075 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3076 &this_distortion, &s, &this_sse, bsize, *best_rd))
3077 continue;
hui sube3559b2015-10-07 09:29:02 -07003078
hui su4aa50c12015-11-10 12:09:59 -08003079 this_rate = this_rate_tokenonly +
3080 vp10_cost_bit(cpi->common.fc->ext_intra_probs[1], 1) +
3081 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
3082 write_uniform_cost(FILTER_INTRA_MODES, mode);
3083 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3084 if (this_rd < *best_rd) {
3085 *best_rd = this_rd;
3086 *rate = this_rate;
3087 *rate_tokenonly = this_rate_tokenonly;
3088 *distortion = this_distortion;
3089 *skippable = s;
3090 ext_intra_mode_info = mbmi->ext_intra_mode_info;
3091 ext_intra_selected_flag = 1;
3092 if (!x->select_tx_size)
3093 swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE);
hui sube3559b2015-10-07 09:29:02 -07003094 }
3095 }
3096
hui sube3559b2015-10-07 09:29:02 -07003097
3098 if (ext_intra_selected_flag) {
3099 mbmi->uv_mode = DC_PRED;
3100 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
3101 ext_intra_mode_info.use_ext_intra_mode[1];
3102 mbmi->ext_intra_mode_info.ext_intra_mode[1] =
3103 ext_intra_mode_info.ext_intra_mode[1];
hui sube3559b2015-10-07 09:29:02 -07003104 return 1;
3105 } else {
3106 return 0;
3107 }
3108}
hui su4aa50c12015-11-10 12:09:59 -08003109
hui su5a7c8d82016-02-08 10:39:17 -08003110static void pick_intra_angle_routine_sbuv(VP10_COMP *cpi, MACROBLOCK *x,
3111 int *rate, int *rate_tokenonly,
3112 int64_t *distortion, int *skippable,
3113 int *best_angle_delta,
3114 BLOCK_SIZE bsize, int rate_overhead,
3115 int64_t *best_rd) {
3116 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
3117 int this_rate_tokenonly, this_rate, s;
3118 int64_t this_distortion, this_sse, this_rd;
3119
3120 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3121 &this_distortion, &s, &this_sse, bsize, *best_rd))
3122 return;
3123
3124 this_rate = this_rate_tokenonly + rate_overhead;
3125 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3126 if (this_rd < *best_rd) {
3127 *best_rd = this_rd;
3128 *best_angle_delta = mbmi->angle_delta[1];
3129 *rate = this_rate;
3130 *rate_tokenonly = this_rate_tokenonly;
3131 *distortion = this_distortion;
3132 *skippable = s;
3133 }
3134}
3135
hui su4aa50c12015-11-10 12:09:59 -08003136static int rd_pick_intra_angle_sbuv(VP10_COMP *cpi, MACROBLOCK *x,
3137 PICK_MODE_CONTEXT *ctx,
3138 int *rate, int *rate_tokenonly,
3139 int64_t *distortion, int *skippable,
3140 BLOCK_SIZE bsize, int rate_overhead,
3141 int64_t best_rd) {
3142 MACROBLOCKD *const xd = &x->e_mbd;
3143 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
3144 int this_rate_tokenonly, this_rate, s;
3145 int64_t this_distortion, this_sse, this_rd;
3146 int angle_delta, best_angle_delta = 0;
3147 const double rd_adjust = 1.2;
3148
3149 (void)ctx;
3150 *rate_tokenonly = INT_MAX;
3151 if (ANGLE_FAST_SEARCH) {
3152 int deltas_level1[3] = {0, -2, 2};
3153 int deltas_level2[3][2] = {
3154 {-1, 1}, {-3, -1}, {1, 3},
3155 };
3156 const int level1 = 3, level2 = 2;
3157 int i, j, best_i = -1;
3158
3159 for (i = 0; i < level1; ++i) {
3160 mbmi->angle_delta[1] = deltas_level1[i];
3161 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3162 &this_distortion, &s, &this_sse, bsize,
3163 (i == 0 && best_rd < INT64_MAX) ?
3164 best_rd * rd_adjust : best_rd)) {
3165 if (i == 0)
3166 break;
3167 else
3168 continue;
3169 }
3170 this_rate = this_rate_tokenonly + rate_overhead;
3171 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3172 if (i == 0 && best_rd < INT64_MAX && this_rd > best_rd * rd_adjust)
3173 break;
3174 if (this_rd < best_rd) {
3175 best_i = i;
3176 best_rd = this_rd;
3177 best_angle_delta = mbmi->angle_delta[1];
3178 *rate = this_rate;
3179 *rate_tokenonly = this_rate_tokenonly;
3180 *distortion = this_distortion;
3181 *skippable = s;
3182 }
3183 }
3184
3185 if (best_i >= 0) {
3186 for (j = 0; j < level2; ++j) {
3187 mbmi->angle_delta[1] = deltas_level2[best_i][j];
hui su5a7c8d82016-02-08 10:39:17 -08003188 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly,
3189 distortion, skippable,
3190 &best_angle_delta, bsize,
3191 rate_overhead, &best_rd);
hui su4aa50c12015-11-10 12:09:59 -08003192 }
3193 }
3194 } else {
3195 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
3196 ++angle_delta) {
3197 mbmi->angle_delta[1] = angle_delta;
hui su5a7c8d82016-02-08 10:39:17 -08003198 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly,
3199 distortion, skippable,
3200 &best_angle_delta, bsize,
3201 rate_overhead, &best_rd);
hui su4aa50c12015-11-10 12:09:59 -08003202 }
3203 }
3204
3205 mbmi->angle_delta[1] = best_angle_delta;
3206 if (*rate_tokenonly != INT_MAX)
3207 super_block_uvrd(cpi, x, &this_rate_tokenonly,
3208 &this_distortion, &s, &this_sse, bsize, INT_MAX);
3209 return *rate_tokenonly != INT_MAX;
3210}
hui sube3559b2015-10-07 09:29:02 -07003211#endif // CONFIG_EXT_INTRA
3212
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003213static int64_t rd_pick_intra_sbuv_mode(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003214 PICK_MODE_CONTEXT *ctx,
3215 int *rate, int *rate_tokenonly,
3216 int64_t *distortion, int *skippable,
3217 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
3218 MACROBLOCKD *xd = &x->e_mbd;
hui sube3559b2015-10-07 09:29:02 -07003219 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Jingning Han3ee6db62015-08-05 19:00:31 -07003220 PREDICTION_MODE mode;
3221 PREDICTION_MODE mode_selected = DC_PRED;
3222 int64_t best_rd = INT64_MAX, this_rd;
3223 int this_rate_tokenonly, this_rate, s;
3224 int64_t this_distortion, this_sse;
hui sube3559b2015-10-07 09:29:02 -07003225#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08003226 int is_directional_mode, rate_overhead, best_angle_delta = 0;
hui sube3559b2015-10-07 09:29:02 -07003227 EXT_INTRA_MODE_INFO ext_intra_mode_info;
Jingning Han3ee6db62015-08-05 19:00:31 -07003228
hui sube3559b2015-10-07 09:29:02 -07003229 ext_intra_mode_info.use_ext_intra_mode[1] = 0;
3230 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
3231#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07003232 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
hui suc93e5cc2015-12-07 18:18:57 -08003233 xd->mi[0]->mbmi.palette_mode_info.palette_size[1] = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07003234 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
3235 if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode)))
3236 continue;
3237
hui sube3559b2015-10-07 09:29:02 -07003238 mbmi->uv_mode = mode;
hui su4aa50c12015-11-10 12:09:59 -08003239#if CONFIG_EXT_INTRA
3240 is_directional_mode = (mode != DC_PRED && mode != TM_PRED);
3241 rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
3242 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
3243 mbmi->angle_delta[1] = 0;
3244 if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode) {
3245 if (!rd_pick_intra_angle_sbuv(cpi, x, ctx, &this_rate,
3246 &this_rate_tokenonly, &this_distortion, &s,
3247 bsize, rate_overhead, best_rd))
3248 continue;
3249 } else {
3250 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3251 &this_distortion, &s, &this_sse, bsize, best_rd))
3252 continue;
3253 }
3254 this_rate = this_rate_tokenonly +
3255 cpi->intra_uv_mode_cost[mbmi->mode][mode];
3256 if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode)
3257 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
3258 MAX_ANGLE_DELTAS +
3259 mbmi->angle_delta[1]);
3260 if (mode == DC_PRED && 0)
3261 this_rate += vp10_cost_bit(cpi->common.fc->ext_intra_probs[1], 0);
3262#else
Jingning Han3ee6db62015-08-05 19:00:31 -07003263 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3264 &this_distortion, &s, &this_sse, bsize, best_rd))
3265 continue;
hui su6ab6ac42015-11-06 13:56:51 -08003266 this_rate = this_rate_tokenonly +
3267 cpi->intra_uv_mode_cost[xd->mi[0]->mbmi.mode][mode];
hui sube3559b2015-10-07 09:29:02 -07003268#endif // CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08003269
Jingning Han3ee6db62015-08-05 19:00:31 -07003270 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3271
3272 if (this_rd < best_rd) {
3273 mode_selected = mode;
hui su4aa50c12015-11-10 12:09:59 -08003274#if CONFIG_EXT_INTRA
3275 best_angle_delta = mbmi->angle_delta[1];
3276#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07003277 best_rd = this_rd;
3278 *rate = this_rate;
3279 *rate_tokenonly = this_rate_tokenonly;
3280 *distortion = this_distortion;
3281 *skippable = s;
3282 if (!x->select_tx_size)
3283 swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE);
3284 }
3285 }
3286
hui sube3559b2015-10-07 09:29:02 -07003287#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08003288 if (mbmi->sb_type >= BLOCK_8X8 && ALLOW_FILTER_INTRA_MODES) {
hui sube3559b2015-10-07 09:29:02 -07003289 if (rd_pick_ext_intra_sbuv(cpi, x, ctx, rate, rate_tokenonly, distortion,
3290 skippable, bsize, &best_rd)) {
3291 mode_selected = mbmi->uv_mode;
3292 ext_intra_mode_info = mbmi->ext_intra_mode_info;
3293 }
3294 }
3295
3296 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
3297 ext_intra_mode_info.use_ext_intra_mode[1];
3298 if (ext_intra_mode_info.use_ext_intra_mode[1])
3299 mbmi->ext_intra_mode_info.ext_intra_mode[1] =
3300 ext_intra_mode_info.ext_intra_mode[1];
hui su4aa50c12015-11-10 12:09:59 -08003301 mbmi->angle_delta[1] = best_angle_delta;
hui sube3559b2015-10-07 09:29:02 -07003302#endif // CONFIG_EXT_INTRA
3303 mbmi->uv_mode = mode_selected;
Jingning Han3ee6db62015-08-05 19:00:31 -07003304 return best_rd;
3305}
3306
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003307static int64_t rd_sbuv_dcpred(const VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003308 int *rate, int *rate_tokenonly,
3309 int64_t *distortion, int *skippable,
3310 BLOCK_SIZE bsize) {
Jingning Han3ee6db62015-08-05 19:00:31 -07003311 int64_t unused;
3312
3313 x->e_mbd.mi[0]->mbmi.uv_mode = DC_PRED;
3314 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
3315 super_block_uvrd(cpi, x, rate_tokenonly, distortion,
3316 skippable, &unused, bsize, INT64_MAX);
hui su6ab6ac42015-11-06 13:56:51 -08003317 *rate = *rate_tokenonly +
3318 cpi->intra_uv_mode_cost[x->e_mbd.mi[0]->mbmi.mode][DC_PRED];
Jingning Han3ee6db62015-08-05 19:00:31 -07003319 return RDCOST(x->rdmult, x->rddiv, *rate, *distortion);
3320}
3321
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003322static void choose_intra_uv_mode(VP10_COMP *cpi, MACROBLOCK *const x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003323 PICK_MODE_CONTEXT *ctx,
3324 BLOCK_SIZE bsize, TX_SIZE max_tx_size,
3325 int *rate_uv, int *rate_uv_tokenonly,
3326 int64_t *dist_uv, int *skip_uv,
3327 PREDICTION_MODE *mode_uv) {
3328 // Use an estimated rd for uv_intra based on DC_PRED if the
3329 // appropriate speed flag is set.
3330 if (cpi->sf.use_uv_intra_rd_estimate) {
3331 rd_sbuv_dcpred(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv,
3332 skip_uv, bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize);
3333 // Else do a proper rd search for each possible transform size that may
3334 // be considered in the main rd loop.
3335 } else {
3336 rd_pick_intra_sbuv_mode(cpi, x, ctx,
3337 rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
3338 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
3339 }
3340 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
3341}
3342
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003343static int cost_mv_ref(const VP10_COMP *cpi, PREDICTION_MODE mode,
Yue Chen1ac85872016-01-07 15:13:52 -08003344#if CONFIG_REF_MV && CONFIG_EXT_INTER
3345 int is_compound,
3346#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003347 int16_t mode_context) {
Jingning Han1dc18072015-12-02 10:59:01 -08003348#if CONFIG_REF_MV
3349 int mode_cost = 0;
Yue Chen968bbc72016-01-19 16:45:45 -08003350#if CONFIG_EXT_INTER
3351 int16_t mode_ctx = is_compound ? mode_context :
3352 (mode_context & NEWMV_CTX_MASK);
3353#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003354 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
Yue Chen968bbc72016-01-19 16:45:45 -08003355#endif // CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003356 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
Jingning Han1dc18072015-12-02 10:59:01 -08003357
3358 assert(is_inter_mode(mode));
3359
Yue Chen1ac85872016-01-07 15:13:52 -08003360#if CONFIG_EXT_INTER
Yue Chen968bbc72016-01-19 16:45:45 -08003361 if (is_compound) {
3362 return cpi->inter_compound_mode_cost[mode_context]
3363 [INTER_COMPOUND_OFFSET(mode)];
3364 } else {
3365 if (mode == NEWMV || mode == NEWFROMNEARMV) {
Yue Chen1ac85872016-01-07 15:13:52 -08003366#else
Jingning Han1dc18072015-12-02 10:59:01 -08003367 if (mode == NEWMV) {
Yue Chen1ac85872016-01-07 15:13:52 -08003368#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08003369 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
Yue Chen1ac85872016-01-07 15:13:52 -08003370#if CONFIG_EXT_INTER
3371 if (!is_compound)
3372 mode_cost += cpi->new2mv_mode_cost[mode == NEWFROMNEARMV];
3373#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08003374 return mode_cost;
3375 } else {
3376 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
3377 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003378
3379 if (is_all_zero_mv)
3380 return mode_cost;
3381
Jingning Han1dc18072015-12-02 10:59:01 -08003382 if (mode == ZEROMV) {
3383 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
3384 return mode_cost;
3385 } else {
3386 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003387 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
Jingning Han387a10e2015-12-09 09:07:39 -08003388
3389 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET))
3390 mode_ctx = 6;
3391 if (mode_context & (1 << SKIP_NEARMV_OFFSET))
3392 mode_ctx = 7;
3393 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET))
3394 mode_ctx = 8;
3395
Jingning Han1dc18072015-12-02 10:59:01 -08003396 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
3397 return mode_cost;
3398 }
3399 }
Yue Chen968bbc72016-01-19 16:45:45 -08003400#if CONFIG_EXT_INTER
3401 }
3402#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08003403#else
Jingning Han3ee6db62015-08-05 19:00:31 -07003404 assert(is_inter_mode(mode));
Yue Chen968bbc72016-01-19 16:45:45 -08003405#if CONFIG_EXT_INTER
3406 if (is_inter_compound_mode(mode)) {
3407 return cpi->inter_compound_mode_cost[mode_context]
3408 [INTER_COMPOUND_OFFSET(mode)];
3409 } else {
3410#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003411 return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
Yue Chen968bbc72016-01-19 16:45:45 -08003412#if CONFIG_EXT_INTER
3413 }
3414#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08003415#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07003416}
3417
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003418static int set_and_cost_bmi_mvs(VP10_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd,
Jingning Han3ee6db62015-08-05 19:00:31 -07003419 int i,
3420 PREDICTION_MODE mode, int_mv this_mv[2],
3421 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
3422 int_mv seg_mvs[MAX_REF_FRAMES],
Yue Chen1ac85872016-01-07 15:13:52 -08003423#if CONFIG_EXT_INTER
3424 int_mv compound_seg_newmvs[2],
3425#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003426 int_mv *best_ref_mv[2], const int *mvjcost,
3427 int *mvcost[2]) {
3428 MODE_INFO *const mic = xd->mi[0];
3429 const MB_MODE_INFO *const mbmi = &mic->mbmi;
3430 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
3431 int thismvcost = 0;
3432 int idx, idy;
3433 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
3434 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
3435 const int is_compound = has_second_ref(mbmi);
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003436 int mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
Jingning Han3ee6db62015-08-05 19:00:31 -07003437
3438 switch (mode) {
3439 case NEWMV:
Yue Chen1ac85872016-01-07 15:13:52 -08003440#if CONFIG_EXT_INTER
3441 case NEWFROMNEARMV:
Yue Chen1ac85872016-01-07 15:13:52 -08003442#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003443 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08003444#if CONFIG_EXT_INTER
3445 if (!cpi->common.allow_high_precision_mv ||
3446 !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
3447 lower_mv_precision(&this_mv[0].as_mv, 0);
3448#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003449 thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
3450 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yue Chen968bbc72016-01-19 16:45:45 -08003451#if !CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003452 if (is_compound) {
3453 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
3454 thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
3455 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
3456 }
Yue Chen968bbc72016-01-19 16:45:45 -08003457#endif // !CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003458 break;
3459 case NEARMV:
3460 case NEARESTMV:
3461 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
3462 if (is_compound)
3463 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
3464 break;
3465 case ZEROMV:
3466 this_mv[0].as_int = 0;
3467 if (is_compound)
3468 this_mv[1].as_int = 0;
3469 break;
Yue Chen968bbc72016-01-19 16:45:45 -08003470#if CONFIG_EXT_INTER
3471 case NEW_NEWMV:
3472 if (compound_seg_newmvs[0].as_int == INVALID_MV ||
3473 compound_seg_newmvs[1].as_int == INVALID_MV) {
3474 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
3475 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
3476 } else {
3477 this_mv[0].as_int = compound_seg_newmvs[0].as_int;
3478 this_mv[1].as_int = compound_seg_newmvs[1].as_int;
3479 }
3480 if (!cpi->common.allow_high_precision_mv ||
3481 !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
3482 lower_mv_precision(&this_mv[0].as_mv, 0);
3483 if (!cpi->common.allow_high_precision_mv ||
3484 !vp10_use_mv_hp(&best_ref_mv[1]->as_mv))
3485 lower_mv_precision(&this_mv[1].as_mv, 0);
3486 thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv,
3487 &best_ref_mv[0]->as_mv,
3488 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
3489 thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv,
3490 &best_ref_mv[1]->as_mv,
3491 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
3492 break;
3493 case NEW_NEARMV:
3494 case NEW_NEARESTMV:
3495 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
3496 if (!cpi->common.allow_high_precision_mv ||
3497 !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
3498 lower_mv_precision(&this_mv[0].as_mv, 0);
3499 thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
3500 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
3501 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
3502 break;
3503 case NEAR_NEWMV:
3504 case NEAREST_NEWMV:
3505 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
3506 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
3507 if (!cpi->common.allow_high_precision_mv ||
3508 !vp10_use_mv_hp(&best_ref_mv[1]->as_mv))
3509 lower_mv_precision(&this_mv[1].as_mv, 0);
3510 thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
3511 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
3512 break;
3513 case NEAREST_NEARMV:
3514 case NEAR_NEARESTMV:
3515 case NEAREST_NEARESTMV:
3516 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
3517 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
3518 break;
3519 case ZERO_ZEROMV:
3520 this_mv[0].as_int = 0;
3521 this_mv[1].as_int = 0;
3522 break;
3523#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003524 default:
3525 break;
3526 }
3527
3528 mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
3529 if (is_compound)
3530 mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
3531
3532 mic->bmi[i].as_mode = mode;
3533
3534 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
3535 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
3536 memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
3537
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003538#if CONFIG_REF_MV
Yue Chen968bbc72016-01-19 16:45:45 -08003539#if CONFIG_EXT_INTER
3540 if (is_compound)
3541 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
3542 else
3543#endif // CONFIG_EXT_INTER
Jingning Han387a10e2015-12-09 09:07:39 -08003544 mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
3545 mbmi->ref_frame, mbmi->sb_type, i);
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003546#endif
Yue Chen1ac85872016-01-07 15:13:52 -08003547#if CONFIG_REF_MV && CONFIG_EXT_INTER
3548 return cost_mv_ref(cpi, mode, is_compound, mode_ctx) + thismvcost;
3549#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003550 return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
Yue Chen1ac85872016-01-07 15:13:52 -08003551#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003552}
3553
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003554static int64_t encode_inter_mb_segment(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07003555 MACROBLOCK *x,
3556 int64_t best_yrd,
3557 int i,
3558 int *labelyrate,
3559 int64_t *distortion, int64_t *sse,
3560 ENTROPY_CONTEXT *ta,
3561 ENTROPY_CONTEXT *tl,
Yaowu Xu7c514e22015-09-28 15:55:46 -07003562 int ir, int ic,
Jingning Han3ee6db62015-08-05 19:00:31 -07003563 int mi_row, int mi_col) {
3564 int k;
3565 MACROBLOCKD *xd = &x->e_mbd;
3566 struct macroblockd_plane *const pd = &xd->plane[0];
3567 struct macroblock_plane *const p = &x->plane[0];
3568 MODE_INFO *const mi = xd->mi[0];
3569 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
3570 const int width = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
3571 const int height = 4 * num_4x4_blocks_high_lookup[plane_bsize];
3572 int idx, idy;
Yaowu Xu7c514e22015-09-28 15:55:46 -07003573 void (*fwd_txm4x4)(const int16_t *input, tran_low_t *output, int stride);
Jingning Han3ee6db62015-08-05 19:00:31 -07003574
3575 const uint8_t *const src =
3576 &p->src.buf[vp10_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
3577 uint8_t *const dst = &pd->dst.buf[vp10_raster_block_offset(BLOCK_8X8, i,
3578 pd->dst.stride)];
3579 int64_t thisdistortion = 0, thissse = 0;
Yaowu Xu7c514e22015-09-28 15:55:46 -07003580 int thisrate = 0;
hui sub3cc3a02015-08-24 14:37:54 -07003581 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, i, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07003582 const scan_order *so = get_scan(TX_4X4, tx_type, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07003583
Yaowu Xu7c514e22015-09-28 15:55:46 -07003584 vp10_build_inter_predictor_sub8x8(xd, 0, i, ir, ic, mi_row, mi_col);
3585
Jingning Han3ee6db62015-08-05 19:00:31 -07003586#if CONFIG_VP9_HIGHBITDEPTH
3587 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04003588 fwd_txm4x4 = xd->lossless[mi->mbmi.segment_id] ? vp10_highbd_fwht4x4
3589 : vpx_highbd_fdct4x4;
Jingning Han3ee6db62015-08-05 19:00:31 -07003590 } else {
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04003591 fwd_txm4x4 = xd->lossless[mi->mbmi.segment_id] ? vp10_fwht4x4 : vpx_fdct4x4;
Jingning Han3ee6db62015-08-05 19:00:31 -07003592 }
3593#else
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04003594 fwd_txm4x4 = xd->lossless[mi->mbmi.segment_id] ? vp10_fwht4x4 : vpx_fdct4x4;
Jingning Han3ee6db62015-08-05 19:00:31 -07003595#endif // CONFIG_VP9_HIGHBITDEPTH
Jingning Han3ee6db62015-08-05 19:00:31 -07003596
3597#if CONFIG_VP9_HIGHBITDEPTH
3598 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3599 vpx_highbd_subtract_block(
3600 height, width, vp10_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
3601 8, src, p->src.stride, dst, pd->dst.stride, xd->bd);
3602 } else {
3603 vpx_subtract_block(
3604 height, width, vp10_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
3605 8, src, p->src.stride, dst, pd->dst.stride);
3606 }
3607#else
3608 vpx_subtract_block(height, width,
3609 vp10_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
3610 8, src, p->src.stride, dst, pd->dst.stride);
3611#endif // CONFIG_VP9_HIGHBITDEPTH
3612
3613 k = i;
3614 for (idy = 0; idy < height / 4; ++idy) {
3615 for (idx = 0; idx < width / 4; ++idx) {
3616 int64_t ssz, rd, rd1, rd2;
3617 tran_low_t* coeff;
Jingning Han2cdc1272015-10-09 09:57:42 -07003618#if CONFIG_VAR_TX
3619 int coeff_ctx;
3620#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07003621 k += (idy * 2 + idx);
Jingning Han2cdc1272015-10-09 09:57:42 -07003622#if CONFIG_VAR_TX
3623 coeff_ctx = combine_entropy_contexts(*(ta + (k & 1)),
3624 *(tl + (k >> 1)));
3625#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07003626 coeff = BLOCK_OFFSET(p->coeff, k);
Yaowu Xu7c514e22015-09-28 15:55:46 -07003627 fwd_txm4x4(vp10_raster_block_offset_int16(BLOCK_8X8, k, p->src_diff),
3628 coeff, 8);
Jingning Han3ee6db62015-08-05 19:00:31 -07003629 vp10_regular_quantize_b_4x4(x, 0, k, so->scan, so->iscan);
3630#if CONFIG_VP9_HIGHBITDEPTH
3631 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3632 thisdistortion += vp10_highbd_block_error(coeff,
3633 BLOCK_OFFSET(pd->dqcoeff, k),
3634 16, &ssz, xd->bd);
3635 } else {
3636 thisdistortion += vp10_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, k),
3637 16, &ssz);
3638 }
3639#else
3640 thisdistortion += vp10_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, k),
3641 16, &ssz);
3642#endif // CONFIG_VP9_HIGHBITDEPTH
3643 thissse += ssz;
Jingning Han2cdc1272015-10-09 09:57:42 -07003644#if CONFIG_VAR_TX
3645 thisrate += cost_coeffs(x, 0, k, coeff_ctx,
3646 TX_4X4,
Jingning Han3ee6db62015-08-05 19:00:31 -07003647 so->scan, so->neighbors,
3648 cpi->sf.use_fast_coef_costing);
Jingning Han2cdc1272015-10-09 09:57:42 -07003649 *(ta + (k & 1)) = !(p->eobs[k] == 0);
3650 *(tl + (k >> 1)) = !(p->eobs[k] == 0);
3651#else
3652 thisrate += cost_coeffs(x, 0, k, ta + (k & 1), tl + (k >> 1),
3653 TX_4X4,
3654 so->scan, so->neighbors,
3655 cpi->sf.use_fast_coef_costing);
3656#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07003657 rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion >> 2);
3658 rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse >> 2);
James Zern5e16d392015-08-17 18:19:22 -07003659 rd = VPXMIN(rd1, rd2);
Jingning Han3ee6db62015-08-05 19:00:31 -07003660 if (rd >= best_yrd)
3661 return INT64_MAX;
3662 }
3663 }
3664
3665 *distortion = thisdistortion >> 2;
3666 *labelyrate = thisrate;
3667 *sse = thissse >> 2;
3668
3669 return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
3670}
3671
3672typedef struct {
3673 int eobs;
3674 int brate;
3675 int byrate;
3676 int64_t bdist;
3677 int64_t bsse;
3678 int64_t brdcost;
3679 int_mv mvs[2];
Yue Chen1ac85872016-01-07 15:13:52 -08003680#if CONFIG_EXT_INTER
3681 int_mv ref_mv[2];
3682#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003683 ENTROPY_CONTEXT ta[2];
3684 ENTROPY_CONTEXT tl[2];
3685} SEG_RDSTAT;
3686
3687typedef struct {
3688 int_mv *ref_mv[2];
3689 int_mv mvp;
3690
3691 int64_t segment_rd;
3692 int r;
3693 int64_t d;
3694 int64_t sse;
3695 int segment_yrate;
3696 PREDICTION_MODE modes[4];
Yue Chen968bbc72016-01-19 16:45:45 -08003697#if CONFIG_EXT_INTER
3698 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
3699#else
Jingning Han3ee6db62015-08-05 19:00:31 -07003700 SEG_RDSTAT rdstat[4][INTER_MODES];
Yue Chen968bbc72016-01-19 16:45:45 -08003701#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003702 int mvthresh;
3703} BEST_SEG_INFO;
3704
3705static INLINE int mv_check_bounds(const MACROBLOCK *x, const MV *mv) {
3706 return (mv->row >> 3) < x->mv_row_min ||
3707 (mv->row >> 3) > x->mv_row_max ||
3708 (mv->col >> 3) < x->mv_col_min ||
3709 (mv->col >> 3) > x->mv_col_max;
3710}
3711
3712static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
3713 MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
3714 struct macroblock_plane *const p = &x->plane[0];
3715 struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
3716
3717 p->src.buf = &p->src.buf[vp10_raster_block_offset(BLOCK_8X8, i,
3718 p->src.stride)];
3719 assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
3720 pd->pre[0].buf = &pd->pre[0].buf[vp10_raster_block_offset(BLOCK_8X8, i,
3721 pd->pre[0].stride)];
3722 if (has_second_ref(mbmi))
3723 pd->pre[1].buf = &pd->pre[1].buf[vp10_raster_block_offset(BLOCK_8X8, i,
3724 pd->pre[1].stride)];
3725}
3726
3727static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
3728 struct buf_2d orig_pre[2]) {
3729 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
3730 x->plane[0].src = orig_src;
3731 x->e_mbd.plane[0].pre[0] = orig_pre[0];
3732 if (has_second_ref(mbmi))
3733 x->e_mbd.plane[0].pre[1] = orig_pre[1];
3734}
3735
Jingning Han3ee6db62015-08-05 19:00:31 -07003736// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
3737// TODO(aconverse): Find out if this is still productive then clean up or remove
3738static int check_best_zero_mv(
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003739 const VP10_COMP *cpi, const int16_t mode_context[MAX_REF_FRAMES],
Yue Chen968bbc72016-01-19 16:45:45 -08003740#if CONFIG_REF_MV && CONFIG_EXT_INTER
3741 const int16_t compound_mode_context[MAX_REF_FRAMES],
3742#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003743 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES], int this_mode,
Jingning Han387a10e2015-12-09 09:07:39 -08003744 const MV_REFERENCE_FRAME ref_frames[2],
3745 const BLOCK_SIZE bsize, int block) {
Jingning Han3ee6db62015-08-05 19:00:31 -07003746 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
3747 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
3748 (ref_frames[1] == NONE ||
3749 frame_mv[this_mode][ref_frames[1]].as_int == 0)) {
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003750#if CONFIG_REF_MV
Jingning Han387a10e2015-12-09 09:07:39 -08003751 int16_t rfc = vp10_mode_context_analyzer(mode_context,
3752 ref_frames, bsize, block);
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003753#else
3754 int16_t rfc = mode_context[ref_frames[0]];
3755#endif
Yue Chen1ac85872016-01-07 15:13:52 -08003756#if CONFIG_REF_MV && CONFIG_EXT_INTER
3757 int c1 = cost_mv_ref(cpi, NEARMV, ref_frames[1] > INTRA_FRAME, rfc);
3758 int c2 = cost_mv_ref(cpi, NEARESTMV, ref_frames[1] > INTRA_FRAME, rfc);
3759 int c3 = cost_mv_ref(cpi, ZEROMV, ref_frames[1] > INTRA_FRAME, rfc);
3760#else
Jingning Han3ee6db62015-08-05 19:00:31 -07003761 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
3762 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
3763 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
Yue Chen1ac85872016-01-07 15:13:52 -08003764#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003765
Jingning Han387a10e2015-12-09 09:07:39 -08003766#if !CONFIG_REF_MV
3767 (void)bsize;
3768 (void)block;
3769#endif
3770
Jingning Han3ee6db62015-08-05 19:00:31 -07003771 if (this_mode == NEARMV) {
3772 if (c1 > c3) return 0;
3773 } else if (this_mode == NEARESTMV) {
3774 if (c2 > c3) return 0;
3775 } else {
3776 assert(this_mode == ZEROMV);
3777 if (ref_frames[1] == NONE) {
3778 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
3779 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
3780 return 0;
3781 } else {
3782 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
3783 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
3784 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
3785 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
3786 return 0;
3787 }
3788 }
3789 }
Yue Chen968bbc72016-01-19 16:45:45 -08003790#if CONFIG_EXT_INTER
3791 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
3792 this_mode == NEAR_NEARESTMV || this_mode == ZERO_ZEROMV) &&
3793 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
3794 frame_mv[this_mode][ref_frames[1]].as_int == 0) {
3795#if CONFIG_REF_MV
3796 int16_t rfc = compound_mode_context[ref_frames[0]];
3797 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, 1, rfc);
3798 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, 1, rfc);
3799 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, 1, rfc);
3800 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, 1, rfc);
3801#else
3802 int16_t rfc = mode_context[ref_frames[0]];
3803 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
3804 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
3805 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
3806 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
3807#endif
3808
3809 if (this_mode == NEAREST_NEARMV) {
3810 if (c1 > c3) return 0;
3811 } else if (this_mode == NEAREST_NEARESTMV) {
3812 if (c2 > c3) return 0;
3813 } else if (this_mode == NEAR_NEARESTMV) {
3814 if (c4 > c3) return 0;
3815 } else {
3816 assert(this_mode == ZERO_ZEROMV);
3817 if (ref_frames[1] == NONE) {
3818 if ((c3 >= c2 &&
3819 frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0) ||
3820 (c3 >= c1 &&
3821 frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0) ||
3822 (c3 >= c4 &&
3823 frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0))
3824 return 0;
3825 } else {
3826 if ((c3 >= c2 &&
3827 frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
3828 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
3829 (c3 >= c1 &&
3830 frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
3831 frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
3832 (c3 >= c4 &&
3833 frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
3834 frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
3835 return 0;
3836 }
3837 }
3838 }
3839#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003840 return 1;
3841}
3842
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003843static void joint_motion_search(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003844 BLOCK_SIZE bsize,
3845 int_mv *frame_mv,
3846 int mi_row, int mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08003847#if CONFIG_EXT_INTER
3848 int_mv* ref_mv_sub8x8[2],
3849#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07003850 int_mv single_newmv[MAX_REF_FRAMES],
3851 int *rate_mv) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07003852 const VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07003853 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
3854 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
3855 MACROBLOCKD *xd = &x->e_mbd;
3856 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
3857 const int refs[2] = {mbmi->ref_frame[0],
3858 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]};
3859 int_mv ref_mv[2];
3860 int ite, ref;
Angie Chiang10ad97b2016-02-01 12:49:15 -08003861 const INTERP_FILTER interp_filter = mbmi->interp_filter;
Jingning Han3ee6db62015-08-05 19:00:31 -07003862 struct scale_factors sf;
3863
3864 // Do joint motion search in compound mode to get more accurate mv.
3865 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
3866 int last_besterr[2] = {INT_MAX, INT_MAX};
3867 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
3868 vp10_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
3869 vp10_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
3870 };
3871
3872 // Prediction buffer from second frame.
3873#if CONFIG_VP9_HIGHBITDEPTH
3874 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[64 * 64]);
3875 uint8_t *second_pred;
3876#else
3877 DECLARE_ALIGNED(16, uint8_t, second_pred[64 * 64]);
3878#endif // CONFIG_VP9_HIGHBITDEPTH
3879
3880 for (ref = 0; ref < 2; ++ref) {
Yue Chen1ac85872016-01-07 15:13:52 -08003881#if CONFIG_EXT_INTER
3882 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
3883 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
3884 else
3885#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003886 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
3887
3888 if (scaled_ref_frame[ref]) {
3889 int i;
3890 // Swap out the reference frame for a version that's been scaled to
3891 // match the resolution of the current frame, allowing the existing
3892 // motion search code to be used without additional modifications.
3893 for (i = 0; i < MAX_MB_PLANE; i++)
3894 backup_yv12[ref][i] = xd->plane[i].pre[ref];
3895 vp10_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
3896 NULL);
3897 }
3898
3899 frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
3900 }
3901
3902 // Since we have scaled the reference frames to match the size of the current
3903 // frame we must use a unit scaling factor during mode selection.
3904#if CONFIG_VP9_HIGHBITDEPTH
3905 vp10_setup_scale_factors_for_frame(&sf, cm->width, cm->height,
Debargha Mukherjee85514c42015-10-30 09:19:36 -07003906 cm->width, cm->height,
3907 cm->use_highbitdepth);
Jingning Han3ee6db62015-08-05 19:00:31 -07003908#else
3909 vp10_setup_scale_factors_for_frame(&sf, cm->width, cm->height,
Debargha Mukherjee85514c42015-10-30 09:19:36 -07003910 cm->width, cm->height);
Jingning Han3ee6db62015-08-05 19:00:31 -07003911#endif // CONFIG_VP9_HIGHBITDEPTH
3912
3913 // Allow joint search multiple times iteratively for each reference frame
3914 // and break out of the search loop if it couldn't find a better mv.
3915 for (ite = 0; ite < 4; ite++) {
3916 struct buf_2d ref_yv12[2];
3917 int bestsme = INT_MAX;
3918 int sadpb = x->sadperbit16;
3919 MV tmp_mv;
3920 int search_range = 3;
3921
3922 int tmp_col_min = x->mv_col_min;
3923 int tmp_col_max = x->mv_col_max;
3924 int tmp_row_min = x->mv_row_min;
3925 int tmp_row_max = x->mv_row_max;
3926 int id = ite % 2; // Even iterations search in the first reference frame,
3927 // odd iterations search in the second. The predictor
3928 // found for the 'other' reference frame is factored in.
3929
3930 // Initialized here because of compiler problem in Visual Studio.
3931 ref_yv12[0] = xd->plane[0].pre[0];
3932 ref_yv12[1] = xd->plane[0].pre[1];
3933
3934 // Get the prediction block from the 'other' reference frame.
3935#if CONFIG_VP9_HIGHBITDEPTH
3936 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3937 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
3938 vp10_highbd_build_inter_predictor(ref_yv12[!id].buf,
3939 ref_yv12[!id].stride,
3940 second_pred, pw,
3941 &frame_mv[refs[!id]].as_mv,
3942 &sf, pw, ph, 0,
Angie Chiang10ad97b2016-02-01 12:49:15 -08003943 interp_filter, MV_PRECISION_Q3,
Jingning Han3ee6db62015-08-05 19:00:31 -07003944 mi_col * MI_SIZE, mi_row * MI_SIZE,
3945 xd->bd);
3946 } else {
3947 second_pred = (uint8_t *)second_pred_alloc_16;
3948 vp10_build_inter_predictor(ref_yv12[!id].buf,
3949 ref_yv12[!id].stride,
3950 second_pred, pw,
3951 &frame_mv[refs[!id]].as_mv,
3952 &sf, pw, ph, 0,
Angie Chiang10ad97b2016-02-01 12:49:15 -08003953 interp_filter, MV_PRECISION_Q3,
Jingning Han3ee6db62015-08-05 19:00:31 -07003954 mi_col * MI_SIZE, mi_row * MI_SIZE);
3955 }
3956#else
3957 vp10_build_inter_predictor(ref_yv12[!id].buf,
3958 ref_yv12[!id].stride,
3959 second_pred, pw,
3960 &frame_mv[refs[!id]].as_mv,
3961 &sf, pw, ph, 0,
Angie Chiang10ad97b2016-02-01 12:49:15 -08003962 interp_filter, MV_PRECISION_Q3,
Jingning Han3ee6db62015-08-05 19:00:31 -07003963 mi_col * MI_SIZE, mi_row * MI_SIZE);
3964#endif // CONFIG_VP9_HIGHBITDEPTH
3965
3966 // Do compound motion search on the current reference frame.
3967 if (id)
3968 xd->plane[0].pre[0] = ref_yv12[id];
3969 vp10_set_mv_search_range(x, &ref_mv[id].as_mv);
3970
3971 // Use the mv result from the single mode as mv predictor.
3972 tmp_mv = frame_mv[refs[id]].as_mv;
3973
3974 tmp_mv.col >>= 3;
3975 tmp_mv.row >>= 3;
3976
3977 // Small-range full-pixel motion search.
3978 bestsme = vp10_refining_search_8p_c(x, &tmp_mv, sadpb,
3979 search_range,
3980 &cpi->fn_ptr[bsize],
3981 &ref_mv[id].as_mv, second_pred);
3982 if (bestsme < INT_MAX)
3983 bestsme = vp10_get_mvpred_av_var(x, &tmp_mv, &ref_mv[id].as_mv,
3984 second_pred, &cpi->fn_ptr[bsize], 1);
3985
3986 x->mv_col_min = tmp_col_min;
3987 x->mv_col_max = tmp_col_max;
3988 x->mv_row_min = tmp_row_min;
3989 x->mv_row_max = tmp_row_max;
3990
3991 if (bestsme < INT_MAX) {
3992 int dis; /* TODO: use dis in distortion calculation later. */
3993 unsigned int sse;
3994 bestsme = cpi->find_fractional_mv_step(
3995 x, &tmp_mv,
3996 &ref_mv[id].as_mv,
3997 cpi->common.allow_high_precision_mv,
3998 x->errorperbit,
3999 &cpi->fn_ptr[bsize],
4000 0, cpi->sf.mv.subpel_iters_per_step,
4001 NULL,
4002 x->nmvjointcost, x->mvcost,
4003 &dis, &sse, second_pred,
4004 pw, ph);
4005 }
4006
4007 // Restore the pointer to the first (possibly scaled) prediction buffer.
4008 if (id)
4009 xd->plane[0].pre[0] = ref_yv12[0];
4010
4011 if (bestsme < last_besterr[id]) {
4012 frame_mv[refs[id]].as_mv = tmp_mv;
4013 last_besterr[id] = bestsme;
4014 } else {
4015 break;
4016 }
4017 }
4018
4019 *rate_mv = 0;
4020
4021 for (ref = 0; ref < 2; ++ref) {
4022 if (scaled_ref_frame[ref]) {
4023 // Restore the prediction frame pointers to their unscaled versions.
4024 int i;
4025 for (i = 0; i < MAX_MB_PLANE; i++)
4026 xd->plane[i].pre[ref] = backup_yv12[ref][i];
4027 }
4028
Yue Chen1ac85872016-01-07 15:13:52 -08004029#if CONFIG_EXT_INTER
4030 if (bsize >= BLOCK_8X8)
4031#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004032 *rate_mv += vp10_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
4033 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
4034 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yue Chen1ac85872016-01-07 15:13:52 -08004035#if CONFIG_EXT_INTER
4036 else
4037 *rate_mv += vp10_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
4038 &ref_mv_sub8x8[ref]->as_mv,
4039 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
4040#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004041 }
4042}
4043
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004044static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07004045 int_mv *best_ref_mv,
4046 int_mv *second_best_ref_mv,
4047 int64_t best_rd, int *returntotrate,
4048 int *returnyrate,
4049 int64_t *returndistortion,
4050 int *skippable, int64_t *psse,
4051 int mvthresh,
Yue Chen1ac85872016-01-07 15:13:52 -08004052#if CONFIG_EXT_INTER
4053 int_mv seg_mvs[4][2][MAX_REF_FRAMES],
4054 int_mv compound_seg_newmvs[4][2],
4055#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004056 int_mv seg_mvs[4][MAX_REF_FRAMES],
Yue Chen1ac85872016-01-07 15:13:52 -08004057#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004058 BEST_SEG_INFO *bsi_buf, int filter_idx,
4059 int mi_row, int mi_col) {
4060 int i;
4061 BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
4062 MACROBLOCKD *xd = &x->e_mbd;
4063 MODE_INFO *mi = xd->mi[0];
4064 MB_MODE_INFO *mbmi = &mi->mbmi;
4065 int mode_idx;
4066 int k, br = 0, idx, idy;
4067 int64_t bd = 0, block_sse = 0;
4068 PREDICTION_MODE this_mode;
Yaowu Xufc7cbd12015-08-13 09:36:53 -07004069 VP10_COMMON *cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07004070 struct macroblock_plane *const p = &x->plane[0];
4071 struct macroblockd_plane *const pd = &xd->plane[0];
4072 const int label_count = 4;
4073 int64_t this_segment_rd = 0;
4074 int label_mv_thresh;
4075 int segmentyrate = 0;
4076 const BLOCK_SIZE bsize = mbmi->sb_type;
4077 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
4078 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
4079 ENTROPY_CONTEXT t_above[2], t_left[2];
4080 int subpelmv = 1, have_ref = 0;
4081 const int has_second_rf = has_second_ref(mbmi);
4082 const int inter_mode_mask = cpi->sf.inter_mode_mask[bsize];
4083 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4084
4085 vp10_zero(*bsi);
4086
4087 bsi->segment_rd = best_rd;
4088 bsi->ref_mv[0] = best_ref_mv;
4089 bsi->ref_mv[1] = second_best_ref_mv;
4090 bsi->mvp.as_int = best_ref_mv->as_int;
4091 bsi->mvthresh = mvthresh;
4092
4093 for (i = 0; i < 4; i++)
4094 bsi->modes[i] = ZEROMV;
4095
4096 memcpy(t_above, pd->above_context, sizeof(t_above));
4097 memcpy(t_left, pd->left_context, sizeof(t_left));
4098
4099 // 64 makes this threshold really big effectively
4100 // making it so that we very rarely check mvs on
4101 // segments. setting this to 1 would make mv thresh
4102 // roughly equal to what it is for macroblocks
4103 label_mv_thresh = 1 * bsi->mvthresh / label_count;
4104
4105 // Segmentation method overheads
4106 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
4107 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
4108 // TODO(jingning,rbultje): rewrite the rate-distortion optimization
4109 // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
4110 int_mv mode_mv[MB_MODE_COUNT][2];
4111 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
4112 PREDICTION_MODE mode_selected = ZEROMV;
4113 int64_t best_rd = INT64_MAX;
4114 const int i = idy * 2 + idx;
4115 int ref;
Yue Chen1ac85872016-01-07 15:13:52 -08004116#if CONFIG_EXT_INTER
4117 int mv_idx;
4118 int_mv ref_mvs_sub8x8[2][2];
4119#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004120
4121 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
4122 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
Yue Chen1ac85872016-01-07 15:13:52 -08004123#if CONFIG_EXT_INTER
4124 int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
4125 vp10_update_mv_context(cm, xd, mi, frame, mv_ref_list, i,
4126 mi_row, mi_col, NULL);
4127#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004128 frame_mv[ZEROMV][frame].as_int = 0;
4129 vp10_append_sub8x8_mvs_for_idx(cm, xd, i, ref, mi_row, mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08004130#if CONFIG_EXT_INTER
4131 mv_ref_list,
4132#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004133 &frame_mv[NEARESTMV][frame],
Jingning Han40cedd62015-11-25 13:42:59 -08004134 &frame_mv[NEARMV][frame]);
Yue Chen1ac85872016-01-07 15:13:52 -08004135#if CONFIG_EXT_INTER
4136 mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
4137 mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
4138 vp10_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
4139 &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
Yue Chen968bbc72016-01-19 16:45:45 -08004140
4141 if (has_second_rf) {
4142 frame_mv[ZERO_ZEROMV][frame].as_int = 0;
4143 frame_mv[NEAREST_NEARESTMV][frame].as_int =
4144 frame_mv[NEARESTMV][frame].as_int;
4145
4146 if (ref == 0) {
4147 frame_mv[NEAREST_NEARMV][frame].as_int =
4148 frame_mv[NEARESTMV][frame].as_int;
4149 frame_mv[NEAR_NEARESTMV][frame].as_int =
4150 frame_mv[NEARMV][frame].as_int;
4151 frame_mv[NEAREST_NEWMV][frame].as_int =
4152 frame_mv[NEARESTMV][frame].as_int;
4153 frame_mv[NEAR_NEWMV][frame].as_int =
4154 frame_mv[NEARMV][frame].as_int;
4155 } else if (ref == 1) {
4156 frame_mv[NEAREST_NEARMV][frame].as_int =
4157 frame_mv[NEARMV][frame].as_int;
4158 frame_mv[NEAR_NEARESTMV][frame].as_int =
4159 frame_mv[NEARESTMV][frame].as_int;
4160 frame_mv[NEW_NEARESTMV][frame].as_int =
4161 frame_mv[NEARESTMV][frame].as_int;
4162 frame_mv[NEW_NEARMV][frame].as_int =
4163 frame_mv[NEARMV][frame].as_int;
4164 }
4165 }
Yue Chen1ac85872016-01-07 15:13:52 -08004166#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004167 }
4168
4169 // search for the best motion vector on this segment
Yue Chen1ac85872016-01-07 15:13:52 -08004170#if CONFIG_EXT_INTER
Yue Chen968bbc72016-01-19 16:45:45 -08004171 for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
4172 this_mode <= (has_second_rf ? NEW_NEWMV : NEWFROMNEARMV);
4173 ++this_mode) {
Yue Chen1ac85872016-01-07 15:13:52 -08004174#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004175 for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
Yue Chen1ac85872016-01-07 15:13:52 -08004176#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004177 const struct buf_2d orig_src = x->plane[0].src;
4178 struct buf_2d orig_pre[2];
4179
4180 mode_idx = INTER_OFFSET(this_mode);
Yue Chen1ac85872016-01-07 15:13:52 -08004181#if CONFIG_EXT_INTER
4182 mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
Yue Chen968bbc72016-01-19 16:45:45 -08004183
Yue Chen1ac85872016-01-07 15:13:52 -08004184 for (ref = 0; ref < 1 + has_second_rf; ++ref)
4185 bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[mv_idx][ref].as_int;
4186#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004187 bsi->rdstat[i][mode_idx].brdcost = INT64_MAX;
4188 if (!(inter_mode_mask & (1 << this_mode)))
4189 continue;
4190
Yue Chen968bbc72016-01-19 16:45:45 -08004191 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
4192#if CONFIG_REF_MV && CONFIG_EXT_INTER
4193 mbmi_ext->compound_mode_context,
4194#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4195 frame_mv,
Jingning Han387a10e2015-12-09 09:07:39 -08004196 this_mode, mbmi->ref_frame, bsize, i))
Jingning Han3ee6db62015-08-05 19:00:31 -07004197 continue;
4198
4199 memcpy(orig_pre, pd->pre, sizeof(orig_pre));
4200 memcpy(bsi->rdstat[i][mode_idx].ta, t_above,
4201 sizeof(bsi->rdstat[i][mode_idx].ta));
4202 memcpy(bsi->rdstat[i][mode_idx].tl, t_left,
4203 sizeof(bsi->rdstat[i][mode_idx].tl));
4204
4205 // motion search for newmv (single predictor case only)
Yue Chen1ac85872016-01-07 15:13:52 -08004206 if (!has_second_rf &&
4207#if CONFIG_EXT_INTER
4208 have_newmv_in_inter_mode(this_mode) &&
4209 seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV
4210#else
4211 this_mode == NEWMV &&
4212 seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV
4213#endif // CONFIG_EXT_INTER
4214 ) {
4215#if CONFIG_EXT_INTER
4216 MV *const new_mv = &mode_mv[this_mode][0].as_mv;
4217#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004218 MV *const new_mv = &mode_mv[NEWMV][0].as_mv;
Yue Chen1ac85872016-01-07 15:13:52 -08004219#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004220 int step_param = 0;
paulwilkins4e692bb2015-12-08 15:48:24 +00004221 int bestsme = INT_MAX;
Jingning Han3ee6db62015-08-05 19:00:31 -07004222 int sadpb = x->sadperbit4;
4223 MV mvp_full;
4224 int max_mv;
4225 int cost_list[5];
4226
4227 /* Is the best so far sufficiently good that we cant justify doing
4228 * and new motion search. */
4229 if (best_rd < label_mv_thresh)
4230 break;
4231
4232 if (cpi->oxcf.mode != BEST) {
Yue Chen1ac85872016-01-07 15:13:52 -08004233#if CONFIG_EXT_INTER
4234 bsi->mvp.as_int = bsi->ref_mv[0]->as_int;
4235#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004236 // use previous block's result as next block's MV predictor.
4237 if (i > 0) {
4238 bsi->mvp.as_int = mi->bmi[i - 1].as_mv[0].as_int;
4239 if (i == 2)
4240 bsi->mvp.as_int = mi->bmi[i - 2].as_mv[0].as_int;
4241 }
Yue Chen1ac85872016-01-07 15:13:52 -08004242#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004243 }
4244 if (i == 0)
4245 max_mv = x->max_mv_context[mbmi->ref_frame[0]];
4246 else
James Zern5e16d392015-08-17 18:19:22 -07004247 max_mv =
4248 VPXMAX(abs(bsi->mvp.as_mv.row), abs(bsi->mvp.as_mv.col)) >> 3;
Jingning Han3ee6db62015-08-05 19:00:31 -07004249
4250 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
4251 // Take wtd average of the step_params based on the last frame's
4252 // max mv magnitude and the best ref mvs of the current block for
4253 // the given reference.
4254 step_param = (vp10_init_search_range(max_mv) +
4255 cpi->mv_step_param) / 2;
4256 } else {
4257 step_param = cpi->mv_step_param;
4258 }
4259
4260 mvp_full.row = bsi->mvp.as_mv.row >> 3;
4261 mvp_full.col = bsi->mvp.as_mv.col >> 3;
4262
4263 if (cpi->sf.adaptive_motion_search) {
4264 mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
4265 mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
James Zern5e16d392015-08-17 18:19:22 -07004266 step_param = VPXMAX(step_param, 8);
Jingning Han3ee6db62015-08-05 19:00:31 -07004267 }
4268
4269 // adjust src pointer for this block
4270 mi_buf_shift(x, i);
4271
4272 vp10_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
4273
4274 bestsme = vp10_full_pixel_search(
4275 cpi, x, bsize, &mvp_full, step_param, sadpb,
4276 cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
4277 &bsi->ref_mv[0]->as_mv, new_mv,
4278 INT_MAX, 1);
4279
Jingning Han3ee6db62015-08-05 19:00:31 -07004280 if (bestsme < INT_MAX) {
4281 int distortion;
4282 cpi->find_fractional_mv_step(
4283 x,
4284 new_mv,
4285 &bsi->ref_mv[0]->as_mv,
4286 cm->allow_high_precision_mv,
4287 x->errorperbit, &cpi->fn_ptr[bsize],
4288 cpi->sf.mv.subpel_force_stop,
4289 cpi->sf.mv.subpel_iters_per_step,
4290 cond_cost_list(cpi, cost_list),
4291 x->nmvjointcost, x->mvcost,
4292 &distortion,
4293 &x->pred_sse[mbmi->ref_frame[0]],
4294 NULL, 0, 0);
4295
4296 // save motion search result for use in compound prediction
Yue Chen1ac85872016-01-07 15:13:52 -08004297#if CONFIG_EXT_INTER
4298 seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_mv = *new_mv;
4299#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004300 seg_mvs[i][mbmi->ref_frame[0]].as_mv = *new_mv;
Yue Chen1ac85872016-01-07 15:13:52 -08004301#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004302 }
4303
4304 if (cpi->sf.adaptive_motion_search)
4305 x->pred_mv[mbmi->ref_frame[0]] = *new_mv;
4306
4307 // restore src pointers
4308 mi_buf_restore(x, orig_src, orig_pre);
4309 }
4310
4311 if (has_second_rf) {
Yue Chen1ac85872016-01-07 15:13:52 -08004312#if CONFIG_EXT_INTER
4313 if (seg_mvs[i][mv_idx][mbmi->ref_frame[1]].as_int == INVALID_MV ||
4314 seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
4315#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004316 if (seg_mvs[i][mbmi->ref_frame[1]].as_int == INVALID_MV ||
4317 seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yue Chen1ac85872016-01-07 15:13:52 -08004318#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004319 continue;
4320 }
4321
Yue Chen968bbc72016-01-19 16:45:45 -08004322 if (has_second_rf &&
4323#if CONFIG_EXT_INTER
4324 this_mode == NEW_NEWMV &&
4325#else
4326 this_mode == NEWMV &&
4327#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004328 mbmi->interp_filter == EIGHTTAP) {
4329 // adjust src pointers
4330 mi_buf_shift(x, i);
4331 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
4332 int rate_mv;
4333 joint_motion_search(cpi, x, bsize, frame_mv[this_mode],
Yue Chen1ac85872016-01-07 15:13:52 -08004334 mi_row, mi_col,
4335#if CONFIG_EXT_INTER
4336 bsi->ref_mv,
4337 seg_mvs[i][mv_idx],
4338#else
4339 seg_mvs[i],
4340#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004341 &rate_mv);
Yue Chen1ac85872016-01-07 15:13:52 -08004342#if CONFIG_EXT_INTER
4343 compound_seg_newmvs[i][0].as_int =
4344 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
4345 compound_seg_newmvs[i][1].as_int =
4346 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
4347#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004348 seg_mvs[i][mbmi->ref_frame[0]].as_int =
4349 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
4350 seg_mvs[i][mbmi->ref_frame[1]].as_int =
4351 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08004352#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004353 }
4354 // restore src pointers
4355 mi_buf_restore(x, orig_src, orig_pre);
4356 }
4357
4358 bsi->rdstat[i][mode_idx].brate =
4359 set_and_cost_bmi_mvs(cpi, x, xd, i, this_mode, mode_mv[this_mode],
Yue Chen1ac85872016-01-07 15:13:52 -08004360 frame_mv,
4361#if CONFIG_EXT_INTER
4362 seg_mvs[i][mv_idx],
4363 compound_seg_newmvs[i],
4364#else
4365 seg_mvs[i],
4366#endif // CONFIG_EXT_INTER
4367 bsi->ref_mv,
Jingning Han3ee6db62015-08-05 19:00:31 -07004368 x->nmvjointcost, x->mvcost);
4369
4370 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
4371 bsi->rdstat[i][mode_idx].mvs[ref].as_int =
4372 mode_mv[this_mode][ref].as_int;
4373 if (num_4x4_blocks_wide > 1)
4374 bsi->rdstat[i + 1][mode_idx].mvs[ref].as_int =
4375 mode_mv[this_mode][ref].as_int;
4376 if (num_4x4_blocks_high > 1)
4377 bsi->rdstat[i + 2][mode_idx].mvs[ref].as_int =
4378 mode_mv[this_mode][ref].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08004379#if CONFIG_EXT_INTER
4380 bsi->rdstat[i][mode_idx].ref_mv[ref].as_int =
4381 bsi->ref_mv[ref]->as_int;
4382 if (num_4x4_blocks_wide > 1)
4383 bsi->rdstat[i + 1][mode_idx].ref_mv[ref].as_int =
4384 bsi->ref_mv[ref]->as_int;
4385 if (num_4x4_blocks_high > 1)
4386 bsi->rdstat[i + 2][mode_idx].ref_mv[ref].as_int =
4387 bsi->ref_mv[ref]->as_int;
4388#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004389 }
4390
4391 // Trap vectors that reach beyond the UMV borders
4392 if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
4393 (has_second_rf &&
4394 mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
4395 continue;
4396
4397 if (filter_idx > 0) {
4398 BEST_SEG_INFO *ref_bsi = bsi_buf;
4399 subpelmv = 0;
4400 have_ref = 1;
4401
4402 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
4403 subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
Yue Chen1ac85872016-01-07 15:13:52 -08004404#if CONFIG_EXT_INTER
4405 if (have_newmv_in_inter_mode(this_mode))
4406 have_ref &= (
4407 (mode_mv[this_mode][ref].as_int ==
4408 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int) &&
4409 (bsi->ref_mv[ref]->as_int ==
4410 ref_bsi->rdstat[i][mode_idx].ref_mv[ref].as_int));
4411 else
4412#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004413 have_ref &= mode_mv[this_mode][ref].as_int ==
4414 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
4415 }
4416
4417 if (filter_idx > 1 && !subpelmv && !have_ref) {
4418 ref_bsi = bsi_buf + 1;
4419 have_ref = 1;
4420 for (ref = 0; ref < 1 + has_second_rf; ++ref)
Yue Chen1ac85872016-01-07 15:13:52 -08004421#if CONFIG_EXT_INTER
4422 if (have_newmv_in_inter_mode(this_mode))
4423 have_ref &= (
4424 (mode_mv[this_mode][ref].as_int ==
4425 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int) &&
4426 (bsi->ref_mv[ref]->as_int ==
4427 ref_bsi->rdstat[i][mode_idx].ref_mv[ref].as_int));
4428 else
4429#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004430 have_ref &= mode_mv[this_mode][ref].as_int ==
4431 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
4432 }
4433
4434 if (!subpelmv && have_ref &&
4435 ref_bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) {
4436 memcpy(&bsi->rdstat[i][mode_idx], &ref_bsi->rdstat[i][mode_idx],
4437 sizeof(SEG_RDSTAT));
4438 if (num_4x4_blocks_wide > 1)
4439 bsi->rdstat[i + 1][mode_idx].eobs =
4440 ref_bsi->rdstat[i + 1][mode_idx].eobs;
4441 if (num_4x4_blocks_high > 1)
4442 bsi->rdstat[i + 2][mode_idx].eobs =
4443 ref_bsi->rdstat[i + 2][mode_idx].eobs;
4444
4445 if (bsi->rdstat[i][mode_idx].brdcost < best_rd) {
4446 mode_selected = this_mode;
4447 best_rd = bsi->rdstat[i][mode_idx].brdcost;
4448 }
4449 continue;
4450 }
4451 }
4452
4453 bsi->rdstat[i][mode_idx].brdcost =
4454 encode_inter_mb_segment(cpi, x,
4455 bsi->segment_rd - this_segment_rd, i,
4456 &bsi->rdstat[i][mode_idx].byrate,
4457 &bsi->rdstat[i][mode_idx].bdist,
4458 &bsi->rdstat[i][mode_idx].bsse,
4459 bsi->rdstat[i][mode_idx].ta,
4460 bsi->rdstat[i][mode_idx].tl,
Yaowu Xu7c514e22015-09-28 15:55:46 -07004461 idy, idx,
Jingning Han3ee6db62015-08-05 19:00:31 -07004462 mi_row, mi_col);
4463 if (bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) {
4464 bsi->rdstat[i][mode_idx].brdcost += RDCOST(x->rdmult, x->rddiv,
4465 bsi->rdstat[i][mode_idx].brate, 0);
4466 bsi->rdstat[i][mode_idx].brate += bsi->rdstat[i][mode_idx].byrate;
4467 bsi->rdstat[i][mode_idx].eobs = p->eobs[i];
4468 if (num_4x4_blocks_wide > 1)
4469 bsi->rdstat[i + 1][mode_idx].eobs = p->eobs[i + 1];
4470 if (num_4x4_blocks_high > 1)
4471 bsi->rdstat[i + 2][mode_idx].eobs = p->eobs[i + 2];
4472 }
4473
4474 if (bsi->rdstat[i][mode_idx].brdcost < best_rd) {
4475 mode_selected = this_mode;
4476 best_rd = bsi->rdstat[i][mode_idx].brdcost;
4477 }
4478 } /*for each 4x4 mode*/
4479
4480 if (best_rd == INT64_MAX) {
4481 int iy, midx;
4482 for (iy = i + 1; iy < 4; ++iy)
Yue Chen968bbc72016-01-19 16:45:45 -08004483#if CONFIG_EXT_INTER
4484 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
4485#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004486 for (midx = 0; midx < INTER_MODES; ++midx)
Yue Chen968bbc72016-01-19 16:45:45 -08004487#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004488 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
4489 bsi->segment_rd = INT64_MAX;
4490 return INT64_MAX;
4491 }
4492
4493 mode_idx = INTER_OFFSET(mode_selected);
4494 memcpy(t_above, bsi->rdstat[i][mode_idx].ta, sizeof(t_above));
4495 memcpy(t_left, bsi->rdstat[i][mode_idx].tl, sizeof(t_left));
4496
Yue Chen1ac85872016-01-07 15:13:52 -08004497#if CONFIG_EXT_INTER
4498 mv_idx = (mode_selected == NEWFROMNEARMV) ? 1 : 0;
4499 bsi->ref_mv[0]->as_int = bsi->rdstat[i][mode_idx].ref_mv[0].as_int;
4500 if (has_second_rf)
4501 bsi->ref_mv[1]->as_int = bsi->rdstat[i][mode_idx].ref_mv[1].as_int;
4502#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004503 set_and_cost_bmi_mvs(cpi, x, xd, i, mode_selected, mode_mv[mode_selected],
Yue Chen1ac85872016-01-07 15:13:52 -08004504 frame_mv,
4505#if CONFIG_EXT_INTER
4506 seg_mvs[i][mv_idx],
4507 compound_seg_newmvs[i],
4508#else
4509 seg_mvs[i],
4510#endif // CONFIG_EXT_INTER
4511 bsi->ref_mv, x->nmvjointcost, x->mvcost);
Jingning Han3ee6db62015-08-05 19:00:31 -07004512
4513 br += bsi->rdstat[i][mode_idx].brate;
4514 bd += bsi->rdstat[i][mode_idx].bdist;
4515 block_sse += bsi->rdstat[i][mode_idx].bsse;
4516 segmentyrate += bsi->rdstat[i][mode_idx].byrate;
4517 this_segment_rd += bsi->rdstat[i][mode_idx].brdcost;
4518
4519 if (this_segment_rd > bsi->segment_rd) {
4520 int iy, midx;
4521 for (iy = i + 1; iy < 4; ++iy)
Yue Chen968bbc72016-01-19 16:45:45 -08004522#if CONFIG_EXT_INTER
4523 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
4524#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004525 for (midx = 0; midx < INTER_MODES; ++midx)
Yue Chen968bbc72016-01-19 16:45:45 -08004526#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004527 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
4528 bsi->segment_rd = INT64_MAX;
4529 return INT64_MAX;
4530 }
4531 }
4532 } /* for each label */
4533
4534 bsi->r = br;
4535 bsi->d = bd;
4536 bsi->segment_yrate = segmentyrate;
4537 bsi->segment_rd = this_segment_rd;
4538 bsi->sse = block_sse;
4539
4540 // update the coding decisions
4541 for (k = 0; k < 4; ++k)
4542 bsi->modes[k] = mi->bmi[k].as_mode;
4543
4544 if (bsi->segment_rd > best_rd)
4545 return INT64_MAX;
4546 /* set it to the best */
4547 for (i = 0; i < 4; i++) {
4548 mode_idx = INTER_OFFSET(bsi->modes[i]);
4549 mi->bmi[i].as_mv[0].as_int = bsi->rdstat[i][mode_idx].mvs[0].as_int;
4550 if (has_second_ref(mbmi))
4551 mi->bmi[i].as_mv[1].as_int = bsi->rdstat[i][mode_idx].mvs[1].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08004552#if CONFIG_EXT_INTER
4553 mi->bmi[i].ref_mv[0].as_int = bsi->rdstat[i][mode_idx].ref_mv[0].as_int;
4554 if (has_second_rf)
4555 mi->bmi[i].ref_mv[1].as_int = bsi->rdstat[i][mode_idx].ref_mv[1].as_int;
4556#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004557 x->plane[0].eobs[i] = bsi->rdstat[i][mode_idx].eobs;
4558 mi->bmi[i].as_mode = bsi->modes[i];
4559 }
4560
4561 /*
4562 * used to set mbmi->mv.as_int
4563 */
4564 *returntotrate = bsi->r;
4565 *returndistortion = bsi->d;
4566 *returnyrate = bsi->segment_yrate;
4567 *skippable = vp10_is_skippable_in_plane(x, BLOCK_8X8, 0);
4568 *psse = bsi->sse;
4569 mbmi->mode = bsi->modes[3];
4570
4571 return bsi->segment_rd;
4572}
4573
Yaowu Xufc7cbd12015-08-13 09:36:53 -07004574static void estimate_ref_frame_costs(const VP10_COMMON *cm,
Jingning Han3ee6db62015-08-05 19:00:31 -07004575 const MACROBLOCKD *xd,
4576 int segment_id,
4577 unsigned int *ref_costs_single,
4578 unsigned int *ref_costs_comp,
4579 vpx_prob *comp_mode_p) {
4580 int seg_ref_active = segfeature_active(&cm->seg, segment_id,
4581 SEG_LVL_REF_FRAME);
4582 if (seg_ref_active) {
4583 memset(ref_costs_single, 0, MAX_REF_FRAMES * sizeof(*ref_costs_single));
4584 memset(ref_costs_comp, 0, MAX_REF_FRAMES * sizeof(*ref_costs_comp));
4585 *comp_mode_p = 128;
4586 } else {
4587 vpx_prob intra_inter_p = vp10_get_intra_inter_prob(cm, xd);
4588 vpx_prob comp_inter_p = 128;
4589
4590 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
4591 comp_inter_p = vp10_get_reference_mode_prob(cm, xd);
4592 *comp_mode_p = comp_inter_p;
4593 } else {
4594 *comp_mode_p = 128;
4595 }
4596
4597 ref_costs_single[INTRA_FRAME] = vp10_cost_bit(intra_inter_p, 0);
4598
4599 if (cm->reference_mode != COMPOUND_REFERENCE) {
4600 vpx_prob ref_single_p1 = vp10_get_pred_prob_single_ref_p1(cm, xd);
4601 vpx_prob ref_single_p2 = vp10_get_pred_prob_single_ref_p2(cm, xd);
Zoe Liu3ec16012015-11-12 02:12:17 -08004602#if CONFIG_EXT_REFS
4603 vpx_prob ref_single_p3 = vp10_get_pred_prob_single_ref_p3(cm, xd);
4604 vpx_prob ref_single_p4 = vp10_get_pred_prob_single_ref_p4(cm, xd);
4605 vpx_prob ref_single_p5 = vp10_get_pred_prob_single_ref_p5(cm, xd);
4606#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07004607 unsigned int base_cost = vp10_cost_bit(intra_inter_p, 1);
4608
Zoe Liu3ec16012015-11-12 02:12:17 -08004609 ref_costs_single[LAST_FRAME] =
4610#if CONFIG_EXT_REFS
4611 ref_costs_single[LAST2_FRAME] =
4612 ref_costs_single[LAST3_FRAME] =
4613 ref_costs_single[LAST4_FRAME] =
4614#endif // CONFIG_EXT_REFS
4615 ref_costs_single[GOLDEN_FRAME] =
Jingning Han3ee6db62015-08-05 19:00:31 -07004616 ref_costs_single[ALTREF_FRAME] = base_cost;
Zoe Liu3ec16012015-11-12 02:12:17 -08004617
4618#if CONFIG_EXT_REFS
4619 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p1, 0);
4620 ref_costs_single[LAST2_FRAME] += vp10_cost_bit(ref_single_p1, 0);
4621 ref_costs_single[LAST3_FRAME] += vp10_cost_bit(ref_single_p1, 0);
4622 ref_costs_single[LAST4_FRAME] += vp10_cost_bit(ref_single_p1, 0);
4623 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p1, 1);
4624 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p1, 1);
4625
4626 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p3, 0);
4627 ref_costs_single[LAST2_FRAME] += vp10_cost_bit(ref_single_p3, 0);
4628 ref_costs_single[LAST3_FRAME] += vp10_cost_bit(ref_single_p3, 1);
4629 ref_costs_single[LAST4_FRAME] += vp10_cost_bit(ref_single_p3, 1);
4630 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p2, 0);
4631 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p2, 1);
4632
4633 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p4, 0);
4634 ref_costs_single[LAST2_FRAME] += vp10_cost_bit(ref_single_p4, 1);
4635 ref_costs_single[LAST3_FRAME] += vp10_cost_bit(ref_single_p5, 0);
4636 ref_costs_single[LAST4_FRAME] += vp10_cost_bit(ref_single_p5, 1);
4637#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004638 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p1, 0);
4639 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p1, 1);
4640 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p1, 1);
4641 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p2, 0);
4642 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p2, 1);
Zoe Liu3ec16012015-11-12 02:12:17 -08004643#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07004644 } else {
4645 ref_costs_single[LAST_FRAME] = 512;
Zoe Liu3ec16012015-11-12 02:12:17 -08004646#if CONFIG_EXT_REFS
4647 ref_costs_single[LAST2_FRAME] = 512;
4648 ref_costs_single[LAST3_FRAME] = 512;
4649 ref_costs_single[LAST4_FRAME] = 512;
4650#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07004651 ref_costs_single[GOLDEN_FRAME] = 512;
4652 ref_costs_single[ALTREF_FRAME] = 512;
4653 }
Zoe Liu3ec16012015-11-12 02:12:17 -08004654
Jingning Han3ee6db62015-08-05 19:00:31 -07004655 if (cm->reference_mode != SINGLE_REFERENCE) {
4656 vpx_prob ref_comp_p = vp10_get_pred_prob_comp_ref_p(cm, xd);
Zoe Liu3ec16012015-11-12 02:12:17 -08004657#if CONFIG_EXT_REFS
4658 vpx_prob ref_comp_p1 = vp10_get_pred_prob_comp_ref_p1(cm, xd);
4659 vpx_prob ref_comp_p2 = vp10_get_pred_prob_comp_ref_p2(cm, xd);
4660 vpx_prob ref_comp_p3 = vp10_get_pred_prob_comp_ref_p3(cm, xd);
4661#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07004662 unsigned int base_cost = vp10_cost_bit(intra_inter_p, 1);
4663
Zoe Liu3ec16012015-11-12 02:12:17 -08004664 ref_costs_comp[LAST_FRAME] =
4665#if CONFIG_EXT_REFS
4666 ref_costs_comp[LAST2_FRAME] =
4667 ref_costs_comp[LAST3_FRAME] =
4668 ref_costs_comp[LAST4_FRAME] =
4669#endif // CONFIG_EXT_REFS
4670 ref_costs_comp[GOLDEN_FRAME] = base_cost;
4671
4672#if CONFIG_EXT_REFS
4673 ref_costs_comp[LAST_FRAME] += vp10_cost_bit(ref_comp_p, 0);
4674 ref_costs_comp[LAST2_FRAME] += vp10_cost_bit(ref_comp_p, 0);
4675 ref_costs_comp[LAST3_FRAME] += vp10_cost_bit(ref_comp_p, 1);
4676 ref_costs_comp[LAST4_FRAME] += vp10_cost_bit(ref_comp_p, 1);
4677 ref_costs_comp[GOLDEN_FRAME] += vp10_cost_bit(ref_comp_p, 1);
4678
4679 ref_costs_comp[LAST_FRAME] += vp10_cost_bit(ref_comp_p1, 1);
4680 ref_costs_comp[LAST2_FRAME] += vp10_cost_bit(ref_comp_p1, 0);
4681 ref_costs_comp[LAST3_FRAME] += vp10_cost_bit(ref_comp_p2, 0);
4682 ref_costs_comp[LAST4_FRAME] += vp10_cost_bit(ref_comp_p2, 0);
4683 ref_costs_comp[GOLDEN_FRAME] += vp10_cost_bit(ref_comp_p2, 1);
4684
4685 ref_costs_comp[LAST3_FRAME] += vp10_cost_bit(ref_comp_p3, 1);
4686 ref_costs_comp[LAST4_FRAME] += vp10_cost_bit(ref_comp_p3, 0);
4687#else
4688 ref_costs_comp[LAST_FRAME] += vp10_cost_bit(ref_comp_p, 0);
4689 ref_costs_comp[GOLDEN_FRAME] += vp10_cost_bit(ref_comp_p, 1);
4690#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07004691 } else {
4692 ref_costs_comp[LAST_FRAME] = 512;
Zoe Liu3ec16012015-11-12 02:12:17 -08004693#if CONFIG_EXT_REFS
4694 ref_costs_comp[LAST2_FRAME] = 512;
4695 ref_costs_comp[LAST3_FRAME] = 512;
4696 ref_costs_comp[LAST4_FRAME] = 512;
4697#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07004698 ref_costs_comp[GOLDEN_FRAME] = 512;
4699 }
4700 }
4701}
4702
4703static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
4704 int mode_index,
4705 int64_t comp_pred_diff[REFERENCE_MODES],
4706 int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS],
4707 int skippable) {
4708 MACROBLOCKD *const xd = &x->e_mbd;
4709
4710 // Take a snapshot of the coding context so it can be
4711 // restored if we decide to encode this way
4712 ctx->skip = x->skip;
4713 ctx->skippable = skippable;
4714 ctx->best_mode_index = mode_index;
4715 ctx->mic = *xd->mi[0];
4716 ctx->mbmi_ext = *x->mbmi_ext;
4717 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
4718 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
4719 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
4720
4721 memcpy(ctx->best_filter_diff, best_filter_diff,
4722 sizeof(*best_filter_diff) * SWITCHABLE_FILTER_CONTEXTS);
4723}
4724
Zoe Liu3ec16012015-11-12 02:12:17 -08004725static void setup_buffer_inter(
4726 VP10_COMP *cpi, MACROBLOCK *x,
4727 MV_REFERENCE_FRAME ref_frame,
4728 BLOCK_SIZE block_size,
4729 int mi_row, int mi_col,
4730 int_mv frame_nearest_mv[MAX_REF_FRAMES],
4731 int_mv frame_near_mv[MAX_REF_FRAMES],
4732 struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE]) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07004733 const VP10_COMMON *cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07004734 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
4735 MACROBLOCKD *const xd = &x->e_mbd;
4736 MODE_INFO *const mi = xd->mi[0];
4737 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
4738 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
4739 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4740
4741 assert(yv12 != NULL);
4742
4743 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
4744 // use the UV scaling factors.
4745 vp10_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
4746
4747 // Gets an initial list of candidate vectors from neighbours and orders them
Jingning Hane5c57c52015-11-23 15:05:18 -08004748 vp10_find_mv_refs(cm, xd, mi, ref_frame,
4749#if CONFIG_REF_MV
4750 &mbmi_ext->ref_mv_count[ref_frame],
4751 mbmi_ext->ref_mv_stack[ref_frame],
Yue Chen968bbc72016-01-19 16:45:45 -08004752#if CONFIG_EXT_INTER
4753 mbmi_ext->compound_mode_context,
4754#endif // CONFIG_EXT_INTER
Jingning Hane5c57c52015-11-23 15:05:18 -08004755#endif
4756 candidates, mi_row, mi_col,
4757 NULL, NULL, mbmi_ext->mode_context);
Jingning Han3ee6db62015-08-05 19:00:31 -07004758
4759 // Candidate refinement carried out at encoder and decoder
Ronald S. Bultje5b4805d2015-10-02 11:51:54 -04004760 vp10_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
4761 &frame_nearest_mv[ref_frame],
4762 &frame_near_mv[ref_frame]);
Jingning Han3ee6db62015-08-05 19:00:31 -07004763
4764 // Further refinement that is encode side only to test the top few candidates
4765 // in full and choose the best as the centre point for subsequent searches.
4766 // The current implementation doesn't support scaling.
4767 if (!vp10_is_scaled(sf) && block_size >= BLOCK_8X8)
4768 vp10_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride,
4769 ref_frame, block_size);
4770}
4771
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004772static void single_motion_search(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07004773 BLOCK_SIZE bsize,
4774 int mi_row, int mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08004775#if CONFIG_EXT_INTER
4776 int ref_idx,
4777 int mv_idx,
4778#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004779 int_mv *tmp_mv, int *rate_mv) {
4780 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xufc7cbd12015-08-13 09:36:53 -07004781 const VP10_COMMON *cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07004782 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4783 struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0, 0}};
4784 int bestsme = INT_MAX;
4785 int step_param;
4786 int sadpb = x->sadperbit16;
4787 MV mvp_full;
Yue Chen1ac85872016-01-07 15:13:52 -08004788#if CONFIG_EXT_INTER
4789 int ref = mbmi->ref_frame[ref_idx];
4790 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
4791#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004792 int ref = mbmi->ref_frame[0];
4793 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
Yue Chen1ac85872016-01-07 15:13:52 -08004794#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004795
4796 int tmp_col_min = x->mv_col_min;
4797 int tmp_col_max = x->mv_col_max;
4798 int tmp_row_min = x->mv_row_min;
4799 int tmp_row_max = x->mv_row_max;
4800 int cost_list[5];
4801
4802 const YV12_BUFFER_CONFIG *scaled_ref_frame = vp10_get_scaled_ref_frame(cpi,
4803 ref);
4804
4805 MV pred_mv[3];
4806 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
4807 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
4808 pred_mv[2] = x->pred_mv[ref];
4809
4810 if (scaled_ref_frame) {
4811 int i;
4812 // Swap out the reference frame for a version that's been scaled to
4813 // match the resolution of the current frame, allowing the existing
4814 // motion search code to be used without additional modifications.
4815 for (i = 0; i < MAX_MB_PLANE; i++)
4816 backup_yv12[i] = xd->plane[i].pre[0];
4817
4818 vp10_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
4819 }
4820
4821 vp10_set_mv_search_range(x, &ref_mv);
4822
4823 // Work out the size of the first step in the mv step search.
James Zern5e16d392015-08-17 18:19:22 -07004824 // 0 here is maximum length first step. 1 is VPXMAX >> 1 etc.
Jingning Han3ee6db62015-08-05 19:00:31 -07004825 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
4826 // Take wtd average of the step_params based on the last frame's
4827 // max mv magnitude and that based on the best ref mvs of the current
4828 // block for the given reference.
4829 step_param = (vp10_init_search_range(x->max_mv_context[ref]) +
4830 cpi->mv_step_param) / 2;
4831 } else {
4832 step_param = cpi->mv_step_param;
4833 }
4834
4835 if (cpi->sf.adaptive_motion_search && bsize < BLOCK_64X64) {
James Zern5e16d392015-08-17 18:19:22 -07004836 int boffset =
4837 2 * (b_width_log2_lookup[BLOCK_64X64] -
4838 VPXMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
4839 step_param = VPXMAX(step_param, boffset);
Jingning Han3ee6db62015-08-05 19:00:31 -07004840 }
4841
4842 if (cpi->sf.adaptive_motion_search) {
4843 int bwl = b_width_log2_lookup[bsize];
4844 int bhl = b_height_log2_lookup[bsize];
4845 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
4846
4847 if (tlevel < 5)
4848 step_param += 2;
4849
4850 // prev_mv_sad is not setup for dynamically scaled frames.
4851 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
4852 int i;
4853 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
4854 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
4855 x->pred_mv[ref].row = 0;
4856 x->pred_mv[ref].col = 0;
4857 tmp_mv->as_int = INVALID_MV;
4858
4859 if (scaled_ref_frame) {
4860 int i;
4861 for (i = 0; i < MAX_MB_PLANE; ++i)
4862 xd->plane[i].pre[0] = backup_yv12[i];
4863 }
4864 return;
4865 }
4866 }
4867 }
4868 }
4869
4870 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
4871
4872 mvp_full.col >>= 3;
4873 mvp_full.row >>= 3;
4874
4875 bestsme = vp10_full_pixel_search(cpi, x, bsize, &mvp_full, step_param, sadpb,
4876 cond_cost_list(cpi, cost_list),
4877 &ref_mv, &tmp_mv->as_mv, INT_MAX, 1);
4878
4879 x->mv_col_min = tmp_col_min;
4880 x->mv_col_max = tmp_col_max;
4881 x->mv_row_min = tmp_row_min;
4882 x->mv_row_max = tmp_row_max;
4883
4884 if (bestsme < INT_MAX) {
4885 int dis; /* TODO: use dis in distortion calculation later. */
4886 cpi->find_fractional_mv_step(x, &tmp_mv->as_mv, &ref_mv,
4887 cm->allow_high_precision_mv,
4888 x->errorperbit,
4889 &cpi->fn_ptr[bsize],
4890 cpi->sf.mv.subpel_force_stop,
4891 cpi->sf.mv.subpel_iters_per_step,
4892 cond_cost_list(cpi, cost_list),
4893 x->nmvjointcost, x->mvcost,
4894 &dis, &x->pred_sse[ref], NULL, 0, 0);
4895 }
4896 *rate_mv = vp10_mv_bit_cost(&tmp_mv->as_mv, &ref_mv,
4897 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
4898
4899 if (cpi->sf.adaptive_motion_search)
4900 x->pred_mv[ref] = tmp_mv->as_mv;
4901
4902 if (scaled_ref_frame) {
4903 int i;
4904 for (i = 0; i < MAX_MB_PLANE; i++)
4905 xd->plane[i].pre[0] = backup_yv12[i];
4906 }
4907}
4908
Jingning Han3ee6db62015-08-05 19:00:31 -07004909static INLINE void restore_dst_buf(MACROBLOCKD *xd,
4910 uint8_t *orig_dst[MAX_MB_PLANE],
4911 int orig_dst_stride[MAX_MB_PLANE]) {
4912 int i;
4913 for (i = 0; i < MAX_MB_PLANE; i++) {
4914 xd->plane[i].dst.buf = orig_dst[i];
4915 xd->plane[i].dst.stride = orig_dst_stride[i];
4916 }
4917}
4918
4919// In some situations we want to discount tha pparent cost of a new motion
4920// vector. Where there is a subtle motion field and especially where there is
4921// low spatial complexity then it can be hard to cover the cost of a new motion
4922// vector in a single block, even if that motion vector reduces distortion.
4923// However, once established that vector may be usable through the nearest and
4924// near mv modes to reduce distortion in subsequent blocks and also improve
4925// visual quality.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004926static int discount_newmv_test(const VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07004927 int this_mode,
4928 int_mv this_mv,
4929 int_mv (*mode_mv)[MAX_REF_FRAMES],
4930 int ref_frame) {
4931 return (!cpi->rc.is_src_frame_alt_ref &&
4932 (this_mode == NEWMV) &&
4933 (this_mv.as_int != 0) &&
4934 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
4935 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
4936 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
4937 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
4938}
4939
Ronald S. Bultje5b4805d2015-10-02 11:51:54 -04004940#define LEFT_TOP_MARGIN ((VP9_ENC_BORDER_IN_PIXELS - VP9_INTERP_EXTEND) << 3)
4941#define RIGHT_BOTTOM_MARGIN ((VP9_ENC_BORDER_IN_PIXELS -\
4942 VP9_INTERP_EXTEND) << 3)
4943
4944// TODO(jingning): this mv clamping function should be block size dependent.
4945static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
4946 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
4947 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
4948 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
4949 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
4950}
Angie Chiangc0035cc2016-02-10 14:20:56 -08004951static INTERP_FILTER predict_interp_filter(const VP10_COMP *cpi,
4952 const MACROBLOCK *x,
4953 const BLOCK_SIZE bsize,
4954 const int mi_row,
4955 const int mi_col,
4956 INTERP_FILTER
4957 (*single_filter)[MAX_REF_FRAMES]
4958 ) {
Jingning Han3ee6db62015-08-05 19:00:31 -07004959 INTERP_FILTER best_filter = SWITCHABLE;
Angie Chiangc0035cc2016-02-10 14:20:56 -08004960 const VP10_COMMON *cm = &cpi->common;
4961 const MACROBLOCKD *xd = &x->e_mbd;
Jingning Han3ee6db62015-08-05 19:00:31 -07004962 int bsl = mi_width_log2_lookup[bsize];
4963 int pred_filter_search = cpi->sf.cb_pred_filter_search ?
4964 (((mi_row + mi_col) >> bsl) +
Yue Chend1cad9c2016-01-27 14:18:53 -08004965 get_chessboard_index(cm->current_video_frame)) & 0x1 : 0;
Angie Chiangc0035cc2016-02-10 14:20:56 -08004966 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4967 const int is_comp_pred = has_second_ref(mbmi);
4968 const int this_mode = mbmi->mode;
4969 int refs[2] = { mbmi->ref_frame[0],
Yue Chend1cad9c2016-01-27 14:18:53 -08004970 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Jingning Han3ee6db62015-08-05 19:00:31 -07004971 if (pred_filter_search) {
4972 INTERP_FILTER af = SWITCHABLE, lf = SWITCHABLE;
4973 if (xd->up_available)
4974 af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
4975 if (xd->left_available)
4976 lf = xd->mi[-1]->mbmi.interp_filter;
4977
Yue Chen1ac85872016-01-07 15:13:52 -08004978#if CONFIG_EXT_INTER
Yue Chen968bbc72016-01-19 16:45:45 -08004979 if ((this_mode != NEWMV && this_mode != NEWFROMNEARMV &&
4980 this_mode != NEW_NEWMV) || (af == lf))
Yue Chen1ac85872016-01-07 15:13:52 -08004981#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004982 if ((this_mode != NEWMV) || (af == lf))
Yue Chen1ac85872016-01-07 15:13:52 -08004983#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004984 best_filter = af;
4985 }
Jingning Han3ee6db62015-08-05 19:00:31 -07004986 if (is_comp_pred) {
Jingning Han3ee6db62015-08-05 19:00:31 -07004987 if (cpi->sf.adaptive_mode_search) {
Yue Chen968bbc72016-01-19 16:45:45 -08004988#if CONFIG_EXT_INTER
4989 switch (this_mode) {
4990 case NEAREST_NEARESTMV:
4991 if (single_filter[NEARESTMV][refs[0]] ==
4992 single_filter[NEARESTMV][refs[1]])
4993 best_filter = single_filter[NEARESTMV][refs[0]];
4994 break;
4995 case NEAREST_NEARMV:
4996 if (single_filter[NEARESTMV][refs[0]] ==
4997 single_filter[NEARMV][refs[1]])
4998 best_filter = single_filter[NEARESTMV][refs[0]];
4999 break;
5000 case NEAR_NEARESTMV:
5001 if (single_filter[NEARMV][refs[0]] ==
5002 single_filter[NEARESTMV][refs[1]])
5003 best_filter = single_filter[NEARMV][refs[0]];
5004 break;
5005 case ZERO_ZEROMV:
5006 if (single_filter[ZEROMV][refs[0]] ==
5007 single_filter[ZEROMV][refs[1]])
5008 best_filter = single_filter[ZEROMV][refs[0]];
5009 break;
5010 case NEW_NEWMV:
5011 if (single_filter[NEWMV][refs[0]] ==
5012 single_filter[NEWMV][refs[1]])
5013 best_filter = single_filter[NEWMV][refs[0]];
5014 break;
5015 case NEAREST_NEWMV:
5016 if (single_filter[NEARESTMV][refs[0]] ==
5017 single_filter[NEWMV][refs[1]])
5018 best_filter = single_filter[NEARESTMV][refs[0]];
5019 break;
5020 case NEAR_NEWMV:
5021 if (single_filter[NEARMV][refs[0]] ==
5022 single_filter[NEWMV][refs[1]])
5023 best_filter = single_filter[NEARMV][refs[0]];
5024 break;
5025 case NEW_NEARESTMV:
5026 if (single_filter[NEWMV][refs[0]] ==
5027 single_filter[NEARESTMV][refs[1]])
5028 best_filter = single_filter[NEWMV][refs[0]];
5029 break;
5030 case NEW_NEARMV:
5031 if (single_filter[NEWMV][refs[0]] ==
5032 single_filter[NEARMV][refs[1]])
5033 best_filter = single_filter[NEWMV][refs[0]];
5034 break;
5035 default:
5036 if (single_filter[this_mode][refs[0]] ==
5037 single_filter[this_mode][refs[1]])
5038 best_filter = single_filter[this_mode][refs[0]];
5039 break;
5040 }
5041#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005042 if (single_filter[this_mode][refs[0]] ==
5043 single_filter[this_mode][refs[1]])
5044 best_filter = single_filter[this_mode][refs[0]];
Yue Chen968bbc72016-01-19 16:45:45 -08005045#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005046 }
5047 }
Angie Chiangc0035cc2016-02-10 14:20:56 -08005048 if (cm->interp_filter != BILINEAR) {
5049 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
5050 best_filter = EIGHTTAP;
5051 }
5052#if CONFIG_EXT_INTERP
5053 else if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE) {
5054 best_filter = EIGHTTAP;
5055 }
5056#endif
5057 }
5058 return best_filter;
5059}
5060
5061static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
5062 BLOCK_SIZE bsize,
5063 int *rate2, int64_t *distortion,
5064 int *skippable,
5065 int *rate_y, int *rate_uv,
5066 int *disable_skip,
5067 int_mv (*mode_mv)[MAX_REF_FRAMES],
5068 int mi_row, int mi_col,
Yue Chend1cad9c2016-01-27 14:18:53 -08005069#if CONFIG_OBMC
5070 uint8_t *dst_buf1[3],
5071 int dst_stride1[3],
5072 uint8_t *dst_buf2[3],
5073 int dst_stride2[3],
5074#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005075#if CONFIG_EXT_INTER
5076 int_mv single_newmvs[2][MAX_REF_FRAMES],
5077#else
5078 int_mv single_newmv[MAX_REF_FRAMES],
5079#endif // CONFIG_EXT_INTER
5080 INTERP_FILTER (*single_filter)[MAX_REF_FRAMES],
5081 int (*single_skippable)[MAX_REF_FRAMES],
5082 int64_t *psse,
5083 const int64_t ref_best_rd,
5084 int64_t *mask_filter,
5085 int64_t filter_cache[]) {
5086 VP10_COMMON *cm = &cpi->common;
5087 MACROBLOCKD *xd = &x->e_mbd;
5088 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5089 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
5090 const int is_comp_pred = has_second_ref(mbmi);
5091 const int this_mode = mbmi->mode;
5092 int_mv *frame_mv = mode_mv[this_mode];
5093 int i;
5094 int refs[2] = { mbmi->ref_frame[0],
5095 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
5096 int_mv cur_mv[2];
5097#if CONFIG_EXT_INTER
5098 int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
5099 int_mv single_newmv[MAX_REF_FRAMES];
5100#if CONFIG_REF_MV
5101 uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
5102#endif
5103#endif // CONFIG_EXT_INTER
5104#if CONFIG_VP9_HIGHBITDEPTH
5105 DECLARE_ALIGNED(16, uint16_t, tmp_buf16[MAX_MB_PLANE * 64 * 64]);
5106 uint8_t *tmp_buf;
5107#else
5108 DECLARE_ALIGNED(16, uint8_t, tmp_buf[MAX_MB_PLANE * 64 * 64]);
5109#endif // CONFIG_VP9_HIGHBITDEPTH
Yue Chend1cad9c2016-01-27 14:18:53 -08005110#if CONFIG_OBMC
Yue Chen907f88c2016-02-16 12:22:11 -08005111 int allow_obmc = is_obmc_allowed(mbmi);
5112 int best_obmc_flag = 0;
Yue Chend1cad9c2016-01-27 14:18:53 -08005113#if CONFIG_VP9_HIGHBITDEPTH
5114 DECLARE_ALIGNED(16, uint16_t, tmp_buf1_16[MAX_MB_PLANE * 64 * 64]);
5115 uint8_t *tmp_buf1;
5116 uint8_t *obmc_tmp_buf[3];
5117#else
5118 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * 64 * 64]);
5119 uint8_t *obmc_tmp_buf[3] = {tmp_buf1, tmp_buf1 + 4096, tmp_buf1 + 8192};
5120#endif // CONFIG_VP9_HIGHBITDEPTH
5121 int obmc_tmp_stride[3] = {64, 64, 64};
Yue Chend1cad9c2016-01-27 14:18:53 -08005122 uint8_t tmp_skip_txfm[MAX_MB_PLANE << 2] = {0};
5123 int64_t tmp_bsse[MAX_MB_PLANE << 2] = {0};
5124 int64_t rdobmc;
5125 int skip_txfm_sb_obmc = 0;
5126 int64_t skip_sse_sb_obmc = INT64_MAX;
Yue Chend1cad9c2016-01-27 14:18:53 -08005127#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005128 int pred_exists = 0;
5129 int intpel_mv;
5130 int64_t rd, tmp_rd, best_rd = INT64_MAX;
5131 int best_needs_copy = 0;
5132 uint8_t *orig_dst[MAX_MB_PLANE];
5133 int orig_dst_stride[MAX_MB_PLANE];
5134 int rs = 0;
5135 INTERP_FILTER best_filter = SWITCHABLE;
5136 uint8_t skip_txfm[MAX_MB_PLANE << 2] = {0};
5137 int64_t bsse[MAX_MB_PLANE << 2] = {0};
5138
5139 int skip_txfm_sb = 0;
5140 int64_t skip_sse_sb = INT64_MAX;
5141 int64_t distortion_y = 0, distortion_uv = 0;
5142 int16_t mode_ctx = mbmi_ext->mode_context[refs[0]];
5143
Yue Chend1cad9c2016-01-27 14:18:53 -08005144#if CONFIG_OBMC
5145 tmp_rd = 0;
5146#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005147#if CONFIG_REF_MV
5148#if CONFIG_EXT_INTER
5149 if (is_comp_pred)
5150 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
5151 else
5152#endif // CONFIG_EXT_INTER
5153 mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
5154 mbmi->ref_frame, bsize, -1);
5155#endif
5156
5157#if CONFIG_VP9_HIGHBITDEPTH
5158 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5159 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf16);
Yue Chend1cad9c2016-01-27 14:18:53 -08005160#if CONFIG_OBMC
5161 tmp_buf1 = CONVERT_TO_BYTEPTR(tmp_buf1_16);
5162#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005163 } else {
5164 tmp_buf = (uint8_t *)tmp_buf16;
Yue Chend1cad9c2016-01-27 14:18:53 -08005165#if CONFIG_OBMC
5166 tmp_buf1 = (uint8_t *)tmp_buf1_16;
5167#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005168 }
Yue Chend1cad9c2016-01-27 14:18:53 -08005169#if CONFIG_OBMC
5170 obmc_tmp_buf[0] = tmp_buf1;
5171 obmc_tmp_buf[1] = tmp_buf1 + 4096;
5172 obmc_tmp_buf[2] = tmp_buf1 + 8192;
5173#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005174#endif // CONFIG_VP9_HIGHBITDEPTH
5175
5176 if (is_comp_pred) {
5177 if (frame_mv[refs[0]].as_int == INVALID_MV ||
5178 frame_mv[refs[1]].as_int == INVALID_MV)
5179 return INT64_MAX;
5180 }
Jingning Han3ee6db62015-08-05 19:00:31 -07005181
Yue Chen1ac85872016-01-07 15:13:52 -08005182#if CONFIG_EXT_INTER
5183 if (have_newmv_in_inter_mode(this_mode)) {
5184#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005185 if (this_mode == NEWMV) {
Yue Chen1ac85872016-01-07 15:13:52 -08005186#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005187 int rate_mv;
5188 if (is_comp_pred) {
Yue Chen1ac85872016-01-07 15:13:52 -08005189#if CONFIG_EXT_INTER
5190 for (i = 0; i < 2; ++i) {
5191 single_newmv[refs[i]].as_int =
Yue Chen968bbc72016-01-19 16:45:45 -08005192 single_newmvs[mv_idx][refs[i]].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08005193 }
Yue Chen968bbc72016-01-19 16:45:45 -08005194
5195 if (this_mode == NEW_NEWMV) {
5196 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
5197 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
5198
5199 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
5200 joint_motion_search(cpi, x, bsize, frame_mv,
5201 mi_row, mi_col, NULL, single_newmv, &rate_mv);
5202 } else {
5203 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
5204 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
5205 x->nmvjointcost, x->mvcost,
5206 MV_COST_WEIGHT);
5207 rate_mv += vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
5208 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
5209 x->nmvjointcost, x->mvcost,
5210 MV_COST_WEIGHT);
5211 }
5212 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
5213 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
5214 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
5215 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
5216 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5217 } else {
5218 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
5219 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
5220 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
5221 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5222 }
5223#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005224 // Initialize mv using single prediction mode result.
5225 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
5226 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
5227
5228 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
5229 joint_motion_search(cpi, x, bsize, frame_mv,
Yue Chen1ac85872016-01-07 15:13:52 -08005230 mi_row, mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08005231 single_newmv, &rate_mv);
Jingning Han3ee6db62015-08-05 19:00:31 -07005232 } else {
5233 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
5234 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
5235 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5236 rate_mv += vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
5237 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
5238 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5239 }
Yue Chen968bbc72016-01-19 16:45:45 -08005240#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005241 *rate2 += rate_mv;
5242 } else {
5243 int_mv tmp_mv;
5244 single_motion_search(cpi, x, bsize, mi_row, mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08005245#if CONFIG_EXT_INTER
5246 0, mv_idx,
5247#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005248 &tmp_mv, &rate_mv);
5249 if (tmp_mv.as_int == INVALID_MV)
5250 return INT64_MAX;
5251
5252 frame_mv[refs[0]].as_int =
5253 xd->mi[0]->bmi[0].as_mv[0].as_int = tmp_mv.as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08005254#if CONFIG_EXT_INTER
5255 single_newmvs[mv_idx][refs[0]].as_int = tmp_mv.as_int;
5256#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005257 single_newmv[refs[0]].as_int = tmp_mv.as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08005258#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005259
5260 // Estimate the rate implications of a new mv but discount this
5261 // under certain circumstances where we want to help initiate a weak
5262 // motion field, where the distortion gain for a single block may not
5263 // be enough to overcome the cost of a new mv.
5264 if (discount_newmv_test(cpi, this_mode, tmp_mv, mode_mv, refs[0])) {
James Zern5e16d392015-08-17 18:19:22 -07005265 *rate2 += VPXMAX((rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07005266 } else {
5267 *rate2 += rate_mv;
5268 }
5269 }
5270 }
5271
5272 for (i = 0; i < is_comp_pred + 1; ++i) {
5273 cur_mv[i] = frame_mv[refs[i]];
5274 // Clip "next_nearest" so that it does not extend to far out of image
Yue Chen1ac85872016-01-07 15:13:52 -08005275#if CONFIG_EXT_INTER
5276 if (this_mode != NEWMV && this_mode != NEWFROMNEARMV)
5277#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005278 if (this_mode != NEWMV)
Yue Chen1ac85872016-01-07 15:13:52 -08005279#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005280 clamp_mv2(&cur_mv[i].as_mv, xd);
5281
5282 if (mv_check_bounds(x, &cur_mv[i].as_mv))
5283 return INT64_MAX;
5284 mbmi->mv[i].as_int = cur_mv[i].as_int;
5285 }
5286
Jingning Han33cc1bd2016-01-12 15:06:59 -08005287#if CONFIG_REF_MV
Yue Chen968bbc72016-01-19 16:45:45 -08005288#if CONFIG_EXT_INTER
5289 if (this_mode == NEAREST_NEARESTMV) {
5290#else
Jingning Han33cc1bd2016-01-12 15:06:59 -08005291 if (this_mode == NEARESTMV && is_comp_pred) {
5292 uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
Yue Chen968bbc72016-01-19 16:45:45 -08005293#endif // CONFIG_EXT_INTER
Jingning Han3944cfb2016-01-13 09:03:15 -08005294 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
Jingning Han33cc1bd2016-01-12 15:06:59 -08005295 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
5296 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
5297
5298 for (i = 0; i < 2; ++i) {
5299 lower_mv_precision(&cur_mv[i].as_mv, cm->allow_high_precision_mv);
5300 clamp_mv2(&cur_mv[i].as_mv, xd);
5301 if (mv_check_bounds(x, &cur_mv[i].as_mv))
5302 return INT64_MAX;
5303 mbmi->mv[i].as_int = cur_mv[i].as_int;
5304 }
5305 }
5306 }
5307
Yue Chen968bbc72016-01-19 16:45:45 -08005308#if CONFIG_EXT_INTER
5309 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
5310 if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
5311 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
5312
5313 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
5314 clamp_mv2(&cur_mv[0].as_mv, xd);
5315 if (mv_check_bounds(x, &cur_mv[0].as_mv))
5316 return INT64_MAX;
5317 mbmi->mv[0].as_int = cur_mv[0].as_int;
5318 }
5319
5320 if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
5321 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
5322
5323 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
5324 clamp_mv2(&cur_mv[1].as_mv, xd);
5325 if (mv_check_bounds(x, &cur_mv[1].as_mv))
5326 return INT64_MAX;
5327 mbmi->mv[1].as_int = cur_mv[1].as_int;
5328 }
5329 }
5330
5331 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
5332 if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV) {
5333 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][1].this_mv;
5334
5335 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
5336 clamp_mv2(&cur_mv[0].as_mv, xd);
5337 if (mv_check_bounds(x, &cur_mv[0].as_mv))
5338 return INT64_MAX;
5339 mbmi->mv[0].as_int = cur_mv[0].as_int;
5340 }
5341
5342 if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV) {
5343 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][1].comp_mv;
5344
5345 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
5346 clamp_mv2(&cur_mv[1].as_mv, xd);
5347 if (mv_check_bounds(x, &cur_mv[1].as_mv))
5348 return INT64_MAX;
5349 mbmi->mv[1].as_int = cur_mv[1].as_int;
5350 }
5351 }
5352#else
Jingning Han33cc1bd2016-01-12 15:06:59 -08005353 if (this_mode == NEARMV && is_comp_pred) {
5354 uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
5355 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
Yue Chend1cad9c2016-01-27 14:18:53 -08005356 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][1].this_mv;
5357 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][1].comp_mv;
Jingning Han33cc1bd2016-01-12 15:06:59 -08005358
5359 for (i = 0; i < 2; ++i) {
5360 lower_mv_precision(&cur_mv[i].as_mv, cm->allow_high_precision_mv);
5361 clamp_mv2(&cur_mv[i].as_mv, xd);
5362 if (mv_check_bounds(x, &cur_mv[i].as_mv))
5363 return INT64_MAX;
5364 mbmi->mv[i].as_int = cur_mv[i].as_int;
5365 }
5366 }
5367 }
Yue Chen968bbc72016-01-19 16:45:45 -08005368#endif // CONFIG_EXT_INTER
Jingning Han33cc1bd2016-01-12 15:06:59 -08005369#endif
5370
Jingning Han3ee6db62015-08-05 19:00:31 -07005371 // do first prediction into the destination buffer. Do the next
5372 // prediction into a temporary buffer. Then keep track of which one
5373 // of these currently holds the best predictor, and use the other
5374 // one for future predictions. In the end, copy from tmp_buf to
5375 // dst if necessary.
5376 for (i = 0; i < MAX_MB_PLANE; i++) {
5377 orig_dst[i] = xd->plane[i].dst.buf;
5378 orig_dst_stride[i] = xd->plane[i].dst.stride;
5379 }
5380
5381 // We don't include the cost of the second reference here, because there
5382 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
5383 // words if you present them in that order, the second one is always known
5384 // if the first is known.
5385 //
5386 // Under some circumstances we discount the cost of new mv mode to encourage
5387 // initiation of a motion field.
5388 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]],
5389 mode_mv, refs[0])) {
Yue Chen1ac85872016-01-07 15:13:52 -08005390#if CONFIG_REF_MV && CONFIG_EXT_INTER
5391 *rate2 += VPXMIN(cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx),
5392 cost_mv_ref(cpi, NEARESTMV, is_comp_pred, mode_ctx));
5393#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08005394 *rate2 += VPXMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
5395 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
Yue Chen1ac85872016-01-07 15:13:52 -08005396#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005397 } else {
Yue Chen1ac85872016-01-07 15:13:52 -08005398#if CONFIG_REF_MV && CONFIG_EXT_INTER
5399 *rate2 += cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx);
5400#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08005401 *rate2 += cost_mv_ref(cpi, this_mode, mode_ctx);
Yue Chen1ac85872016-01-07 15:13:52 -08005402#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005403 }
5404
5405 if (RDCOST(x->rdmult, x->rddiv, *rate2, 0) > ref_best_rd &&
Yue Chen968bbc72016-01-19 16:45:45 -08005406#if CONFIG_EXT_INTER
5407 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV)
5408#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005409 mbmi->mode != NEARESTMV)
Yue Chen968bbc72016-01-19 16:45:45 -08005410#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005411 return INT64_MAX;
5412
5413 pred_exists = 0;
5414 // Are all MVs integer pel for Y and UV
5415 intpel_mv = !mv_has_subpel(&mbmi->mv[0].as_mv);
5416 if (is_comp_pred)
5417 intpel_mv &= !mv_has_subpel(&mbmi->mv[1].as_mv);
5418
5419 // Search for best switchable filter by checking the variance of
5420 // pred error irrespective of whether the filter will be used
5421 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
5422 filter_cache[i] = INT64_MAX;
5423
Angie Chiangc0035cc2016-02-10 14:20:56 -08005424 best_filter = predict_interp_filter(cpi, x, bsize, mi_row, mi_col,
5425 single_filter);
5426 if (cm->interp_filter != BILINEAR && best_filter == SWITCHABLE) {
5427 int newbest;
5428 int tmp_rate_sum = 0;
5429 int64_t tmp_dist_sum = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07005430
Angie Chiangc0035cc2016-02-10 14:20:56 -08005431 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
5432 int j;
5433 int64_t rs_rd;
5434 int tmp_skip_sb = 0;
5435 int64_t tmp_skip_sse = INT64_MAX;
Yue Chend1cad9c2016-01-27 14:18:53 -08005436#if CONFIG_OBMC
5437 int obmc_flag = 0;
5438 int tmp_skip_sb_obmc = 0;
5439 int64_t tmp_skip_sse_obmc = INT64_MAX;
5440#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07005441
Angie Chiangc0035cc2016-02-10 14:20:56 -08005442 mbmi->interp_filter = i;
5443 rs = vp10_get_switchable_rate(cpi, xd);
5444 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07005445
Angie Chiangc0035cc2016-02-10 14:20:56 -08005446 if (i > 0 && intpel_mv && IsInterpolatingFilter(i)) {
5447 rd = RDCOST(x->rdmult, x->rddiv, tmp_rate_sum, tmp_dist_sum);
5448 filter_cache[i] = rd;
5449 filter_cache[SWITCHABLE_FILTERS] =
5450 VPXMIN(filter_cache[SWITCHABLE_FILTERS], rd + rs_rd);
5451 if (cm->interp_filter == SWITCHABLE)
5452 rd += rs_rd;
Yue Chend1cad9c2016-01-27 14:18:53 -08005453#if CONFIG_OBMC
5454 if (allow_obmc) {
5455 obmc_flag = best_obmc_flag;
5456 rd += RDCOST(x->rdmult, x->rddiv,
5457 cpi->obmc_cost[bsize][obmc_flag], 0);
5458 }
5459#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005460 *mask_filter = VPXMAX(*mask_filter, rd);
5461 } else {
5462 int rate_sum = 0;
5463 int64_t dist_sum = 0;
Yue Chend1cad9c2016-01-27 14:18:53 -08005464#if CONFIG_OBMC
5465 int rate_sum_obmc = 0;
5466 int64_t dist_sum_obmc = 0;
5467#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005468 if (i > 0 && cpi->sf.adaptive_interp_filter_search &&
5469 (cpi->sf.interp_filter_search_mask & (1 << i))) {
5470 rate_sum = INT_MAX;
5471 dist_sum = INT64_MAX;
5472 continue;
Jingning Han3ee6db62015-08-05 19:00:31 -07005473 }
5474
Angie Chiangc0035cc2016-02-10 14:20:56 -08005475 if ((cm->interp_filter == SWITCHABLE &&
5476 (!i || best_needs_copy)) ||
Jingning Han3ee6db62015-08-05 19:00:31 -07005477 (cm->interp_filter != SWITCHABLE &&
Angie Chiangc0035cc2016-02-10 14:20:56 -08005478 (cm->interp_filter == mbmi->interp_filter ||
5479 (i == 0 && intpel_mv && IsInterpolatingFilter(i))))) {
5480 restore_dst_buf(xd, orig_dst, orig_dst_stride);
5481 } else {
5482 for (j = 0; j < MAX_MB_PLANE; j++) {
5483 xd->plane[j].dst.buf = tmp_buf + j * 64 * 64;
5484 xd->plane[j].dst.stride = 64;
5485 }
5486 }
5487 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
5488 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
5489 &tmp_skip_sb, &tmp_skip_sse);
Jingning Han3ee6db62015-08-05 19:00:31 -07005490
Angie Chiangc0035cc2016-02-10 14:20:56 -08005491 rd = RDCOST(x->rdmult, x->rddiv, rate_sum, dist_sum);
Yue Chend1cad9c2016-01-27 14:18:53 -08005492#if CONFIG_OBMC
5493 if (allow_obmc) {
5494 rd += RDCOST(x->rdmult, x->rddiv, cpi->obmc_cost[bsize][0], 0);
5495 memcpy(tmp_skip_txfm, x->skip_txfm, sizeof(tmp_skip_txfm));
5496 memcpy(tmp_bsse, x->bsse, sizeof(tmp_bsse));
5497
5498 vp10_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, 1,
5499 obmc_tmp_buf, obmc_tmp_stride,
5500 dst_buf1, dst_stride1,
5501 dst_buf2, dst_stride2);
5502 for (j = 0; j < MAX_MB_PLANE; ++j) {
5503 xd->plane[j].dst.buf = obmc_tmp_buf[j];
5504 xd->plane[j].dst.stride = obmc_tmp_stride[j];
5505 }
5506 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum_obmc, &dist_sum_obmc,
5507 &tmp_skip_sb_obmc, &tmp_skip_sse_obmc);
5508 rdobmc = RDCOST(x->rdmult, x->rddiv,
5509 rate_sum_obmc + cpi->obmc_cost[bsize][1],
5510 dist_sum_obmc);
5511
5512 if ((double)rdobmc <= 0.99 * (double)rd) {
5513 obmc_flag = 1;
5514 rd = rdobmc;
5515 rate_sum = rate_sum_obmc;
5516 dist_sum = dist_sum_obmc;
5517 tmp_skip_sb = tmp_skip_sb_obmc;
5518 tmp_skip_sse = tmp_skip_sse_obmc;
5519 } else {
5520 obmc_flag = 0;
5521 memcpy(x->skip_txfm, tmp_skip_txfm, sizeof(tmp_skip_txfm));
5522 memcpy(x->bsse, tmp_bsse, sizeof(tmp_bsse));
5523 }
5524 }
5525#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005526 filter_cache[i] = rd;
5527 filter_cache[SWITCHABLE_FILTERS] =
5528 VPXMIN(filter_cache[SWITCHABLE_FILTERS], rd + rs_rd);
5529 if (cm->interp_filter == SWITCHABLE)
5530 rd += rs_rd;
5531 *mask_filter = VPXMAX(*mask_filter, rd);
5532
5533 if (i == 0 && intpel_mv && IsInterpolatingFilter(i)) {
5534 tmp_rate_sum = rate_sum;
5535 tmp_dist_sum = dist_sum;
Jingning Han3ee6db62015-08-05 19:00:31 -07005536 }
5537 }
Angie Chiangc0035cc2016-02-10 14:20:56 -08005538
5539 if (i == 0 && cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
5540 if (rd / 2 > ref_best_rd) {
5541 restore_dst_buf(xd, orig_dst, orig_dst_stride);
5542 return INT64_MAX;
5543 }
5544 }
5545 newbest = i == 0 || rd < best_rd;
5546
5547 if (newbest) {
5548 best_rd = rd;
5549 best_filter = mbmi->interp_filter;
Yue Chend1cad9c2016-01-27 14:18:53 -08005550#if CONFIG_OBMC
5551 if (allow_obmc)
5552 best_obmc_flag = obmc_flag;
5553#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005554 if (cm->interp_filter == SWITCHABLE && i &&
5555 !(intpel_mv && IsInterpolatingFilter(i)))
5556 best_needs_copy = !best_needs_copy;
5557 }
5558
5559 if ((cm->interp_filter == SWITCHABLE && newbest) ||
5560 (cm->interp_filter != SWITCHABLE &&
5561 cm->interp_filter == mbmi->interp_filter)) {
5562 pred_exists = 1;
5563 tmp_rd = best_rd;
5564
5565 skip_txfm_sb = tmp_skip_sb;
5566 skip_sse_sb = tmp_skip_sse;
5567 memcpy(skip_txfm, x->skip_txfm, sizeof(skip_txfm));
5568 memcpy(bsse, x->bsse, sizeof(bsse));
5569 }
Jingning Han3ee6db62015-08-05 19:00:31 -07005570 }
Angie Chiangc0035cc2016-02-10 14:20:56 -08005571 restore_dst_buf(xd, orig_dst, orig_dst_stride);
Jingning Han3ee6db62015-08-05 19:00:31 -07005572 }
Debargha Mukherjee85514c42015-10-30 09:19:36 -07005573
Jingning Han3ee6db62015-08-05 19:00:31 -07005574 // Set the appropriate filter
5575 mbmi->interp_filter = cm->interp_filter != SWITCHABLE ?
5576 cm->interp_filter : best_filter;
5577 rs = cm->interp_filter == SWITCHABLE ? vp10_get_switchable_rate(cpi, xd) : 0;
Yue Chend1cad9c2016-01-27 14:18:53 -08005578#if CONFIG_OBMC
5579 if (allow_obmc)
5580 mbmi->obmc = best_obmc_flag;
5581 else
5582 mbmi->obmc = 0;
5583#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07005584
Yue Chend1cad9c2016-01-27 14:18:53 -08005585#if CONFIG_OBMC
5586 if (pred_exists && !mbmi->obmc) {
5587#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005588 if (pred_exists) {
Yue Chend1cad9c2016-01-27 14:18:53 -08005589#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07005590 if (best_needs_copy) {
5591 // again temporarily set the buffers to local memory to prevent a memcpy
5592 for (i = 0; i < MAX_MB_PLANE; i++) {
5593 xd->plane[i].dst.buf = tmp_buf + i * 64 * 64;
5594 xd->plane[i].dst.stride = 64;
5595 }
5596 }
5597 rd = tmp_rd + RDCOST(x->rdmult, x->rddiv, rs, 0);
Yue Chend1cad9c2016-01-27 14:18:53 -08005598#if CONFIG_OBMC
5599 if (allow_obmc)
5600 rd += RDCOST(x->rdmult, x->rddiv,
5601 cpi->obmc_cost[bsize][mbmi->obmc], 0);
5602#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07005603 } else {
5604 int tmp_rate;
5605 int64_t tmp_dist;
Yue Chend1cad9c2016-01-27 14:18:53 -08005606#if CONFIG_OBMC
5607 int tmp_rate_obmc;
5608 int64_t tmp_dist_obmc;
Yue Chen907f88c2016-02-16 12:22:11 -08005609 restore_dst_buf(xd, orig_dst, orig_dst_stride);
Yue Chend1cad9c2016-01-27 14:18:53 -08005610#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07005611 // Handles the special case when a filter that is not in the
5612 // switchable list (ex. bilinear) is indicated at the frame level, or
5613 // skip condition holds.
5614 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yue Chend1cad9c2016-01-27 14:18:53 -08005615#if CONFIG_OBMC
5616 if (mbmi->obmc) {
Yue Chen907f88c2016-02-16 12:22:11 -08005617 vp10_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, 0,
5618 NULL, NULL,
Yue Chend1cad9c2016-01-27 14:18:53 -08005619 dst_buf1, dst_stride1,
5620 dst_buf2, dst_stride2);
Yue Chend1cad9c2016-01-27 14:18:53 -08005621 model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist,
5622 &skip_txfm_sb, &skip_sse_sb);
5623 rd = RDCOST(x->rdmult, x->rddiv,
Yue Chen907f88c2016-02-16 12:22:11 -08005624 rs + tmp_rate + cpi->obmc_cost[bsize][1], tmp_dist);
Yue Chend1cad9c2016-01-27 14:18:53 -08005625 } else {
5626#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07005627 model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist,
5628 &skip_txfm_sb, &skip_sse_sb);
5629 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
Yue Chend1cad9c2016-01-27 14:18:53 -08005630#if CONFIG_OBMC
5631 if (allow_obmc) {
5632 rd += RDCOST(x->rdmult, x->rddiv, cpi->obmc_cost[bsize][0], 0);
5633 memcpy(tmp_skip_txfm, x->skip_txfm, sizeof(tmp_skip_txfm));
5634 memcpy(tmp_bsse, x->bsse, sizeof(tmp_bsse));
5635
5636 vp10_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, 1,
5637 obmc_tmp_buf, obmc_tmp_stride,
5638 dst_buf1, dst_stride1,
5639 dst_buf2, dst_stride2);
5640 for (i = 0; i < MAX_MB_PLANE; ++i) {
5641 xd->plane[i].dst.buf = obmc_tmp_buf[i];
5642 xd->plane[i].dst.stride = obmc_tmp_stride[i];
5643 }
5644 model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate_obmc, &tmp_dist_obmc,
5645 &skip_txfm_sb_obmc, &skip_sse_sb_obmc);
5646 rdobmc = RDCOST(x->rdmult, x->rddiv,
5647 rs + tmp_rate_obmc + cpi->obmc_cost[bsize][1],
5648 tmp_dist_obmc);
5649 if ((double)rdobmc <= 0.99 * (double)rd) {
5650 mbmi->obmc = 1;
5651 rd = rdobmc;
5652 skip_txfm_sb = skip_txfm_sb_obmc;
5653 skip_sse_sb = skip_sse_sb_obmc;
5654 } else {
5655 mbmi->obmc = 0;
5656 memcpy(x->skip_txfm, tmp_skip_txfm, sizeof(tmp_skip_txfm));
5657 memcpy(x->bsse, tmp_bsse, sizeof(tmp_bsse));
5658 restore_dst_buf(xd, orig_dst, orig_dst_stride);
5659 }
5660 } else {
5661 mbmi->obmc = 0;
5662 }
5663 }
5664#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07005665 memcpy(skip_txfm, x->skip_txfm, sizeof(skip_txfm));
5666 memcpy(bsse, x->bsse, sizeof(bsse));
5667 }
5668
5669 if (!is_comp_pred)
5670 single_filter[this_mode][refs[0]] = mbmi->interp_filter;
5671
5672 if (cpi->sf.adaptive_mode_search)
5673 if (is_comp_pred)
Yue Chen968bbc72016-01-19 16:45:45 -08005674#if CONFIG_EXT_INTER
5675 switch (this_mode) {
5676 case NEAREST_NEARESTMV:
5677 if (single_skippable[NEARESTMV][refs[0]] &&
5678 single_skippable[NEARESTMV][refs[1]])
5679 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5680 break;
5681 case ZERO_ZEROMV:
5682 if (single_skippable[ZEROMV][refs[0]] &&
5683 single_skippable[ZEROMV][refs[1]])
5684 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5685 break;
5686 case NEW_NEWMV:
5687 if (single_skippable[NEWMV][refs[0]] &&
5688 single_skippable[NEWMV][refs[1]])
5689 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5690 break;
5691 case NEAREST_NEWMV:
5692 if (single_skippable[NEARESTMV][refs[0]] &&
5693 single_skippable[NEWMV][refs[1]])
5694 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5695 break;
5696 case NEAR_NEWMV:
5697 if (single_skippable[NEARMV][refs[0]] &&
5698 single_skippable[NEWMV][refs[1]])
5699 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5700 break;
5701 case NEW_NEARESTMV:
5702 if (single_skippable[NEWMV][refs[0]] &&
5703 single_skippable[NEARESTMV][refs[1]])
5704 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5705 break;
5706 case NEW_NEARMV:
5707 if (single_skippable[NEWMV][refs[0]] &&
5708 single_skippable[NEARMV][refs[1]])
5709 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5710 break;
5711 case NEAREST_NEARMV:
5712 if (single_skippable[NEARESTMV][refs[0]] &&
5713 single_skippable[NEARMV][refs[1]])
5714 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5715 break;
5716 case NEAR_NEARESTMV:
5717 if (single_skippable[NEARMV][refs[0]] &&
5718 single_skippable[NEARESTMV][refs[1]])
5719 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5720 break;
5721 default:
5722 if (single_skippable[this_mode][refs[0]] &&
5723 single_skippable[this_mode][refs[1]])
5724 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
5725 break;
5726 }
5727#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005728 if (single_skippable[this_mode][refs[0]] &&
5729 single_skippable[this_mode][refs[1]])
5730 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
Yue Chen968bbc72016-01-19 16:45:45 -08005731#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005732
5733 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
5734 // if current pred_error modeled rd is substantially more than the best
5735 // so far, do not bother doing full rd
5736 if (rd / 2 > ref_best_rd) {
5737 restore_dst_buf(xd, orig_dst, orig_dst_stride);
5738 return INT64_MAX;
5739 }
5740 }
5741
5742 if (cm->interp_filter == SWITCHABLE)
5743 *rate2 += rs;
Yue Chend1cad9c2016-01-27 14:18:53 -08005744#if CONFIG_OBMC
5745 if (allow_obmc)
5746 *rate2 += cpi->obmc_cost[bsize][mbmi->obmc];
5747#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07005748
5749 memcpy(x->skip_txfm, skip_txfm, sizeof(skip_txfm));
5750 memcpy(x->bsse, bsse, sizeof(bsse));
5751
5752 if (!skip_txfm_sb) {
5753 int skippable_y, skippable_uv;
5754 int64_t sseuv = INT64_MAX;
5755 int64_t rdcosty = INT64_MAX;
5756
5757 // Y cost and distortion
5758 vp10_subtract_plane(x, bsize, 0);
Jingning Han2cdc1272015-10-09 09:57:42 -07005759#if CONFIG_VAR_TX
Jingning Hanf0dee772015-10-26 12:32:30 -07005760 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
Jingning Han4b594d32015-11-02 12:05:47 -08005761 select_tx_type_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
5762 bsize, ref_best_rd);
Jingning Han2cdc1272015-10-09 09:57:42 -07005763 } else {
Jingning Han0f34e352015-11-15 20:52:51 -08005764 int idx, idy;
Jingning Han2cdc1272015-10-09 09:57:42 -07005765 super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
5766 bsize, ref_best_rd);
Jingning Han0f34e352015-11-15 20:52:51 -08005767 for (idy = 0; idy < xd->n8_h; ++idy)
5768 for (idx = 0; idx < xd->n8_w; ++idx)
5769 mbmi->inter_tx_size[idy * 8 + idx] = mbmi->tx_size;
Jingning Han2cdc1272015-10-09 09:57:42 -07005770 }
5771#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005772 super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
5773 bsize, ref_best_rd);
Debargha Mukherjee9a8a6a12016-01-22 14:52:38 -08005774#endif // CONFIG_VAR_TX
Jingning Han704985e2015-10-08 12:05:03 -07005775
Jingning Han3ee6db62015-08-05 19:00:31 -07005776 if (*rate_y == INT_MAX) {
5777 *rate2 = INT_MAX;
5778 *distortion = INT64_MAX;
5779 restore_dst_buf(xd, orig_dst, orig_dst_stride);
5780 return INT64_MAX;
5781 }
5782
5783 *rate2 += *rate_y;
5784 *distortion += distortion_y;
5785
5786 rdcosty = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
James Zern5e16d392015-08-17 18:19:22 -07005787 rdcosty = VPXMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, *psse));
Jingning Han3ee6db62015-08-05 19:00:31 -07005788
Jingning Hana8dad552015-10-08 16:46:10 -07005789#if CONFIG_VAR_TX
5790 if (!inter_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv,
5791 &sseuv, bsize, ref_best_rd - rdcosty)) {
5792#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005793 if (!super_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv,
5794 &sseuv, bsize, ref_best_rd - rdcosty)) {
Debargha Mukherjee9a8a6a12016-01-22 14:52:38 -08005795#endif // CONFIG_VAR_TX
Jingning Han3ee6db62015-08-05 19:00:31 -07005796 *rate2 = INT_MAX;
5797 *distortion = INT64_MAX;
5798 restore_dst_buf(xd, orig_dst, orig_dst_stride);
5799 return INT64_MAX;
5800 }
5801
5802 *psse += sseuv;
5803 *rate2 += *rate_uv;
5804 *distortion += distortion_uv;
5805 *skippable = skippable_y && skippable_uv;
5806 } else {
5807 x->skip = 1;
5808 *disable_skip = 1;
5809
5810 // The cost of skip bit needs to be added.
5811 *rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
5812
5813 *distortion = skip_sse_sb;
5814 }
5815
5816 if (!is_comp_pred)
5817 single_skippable[this_mode][refs[0]] = *skippable;
5818
5819 restore_dst_buf(xd, orig_dst, orig_dst_stride);
5820 return 0; // The rate-distortion cost will be re-calculated by caller.
5821}
5822
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005823void vp10_rd_pick_intra_mode_sb(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07005824 RD_COST *rd_cost, BLOCK_SIZE bsize,
5825 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07005826 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07005827 MACROBLOCKD *const xd = &x->e_mbd;
5828 struct macroblockd_plane *const pd = xd->plane;
5829 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
5830 int y_skip = 0, uv_skip = 0;
5831 int64_t dist_y = 0, dist_uv = 0;
5832 TX_SIZE max_uv_tx_size;
Jingning Han3ee6db62015-08-05 19:00:31 -07005833 ctx->skip = 0;
5834 xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
5835 xd->mi[0]->mbmi.ref_frame[1] = NONE;
5836
5837 if (bsize >= BLOCK_8X8) {
5838 if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly,
5839 &dist_y, &y_skip, bsize,
5840 best_rd) >= best_rd) {
5841 rd_cost->rate = INT_MAX;
5842 return;
5843 }
5844 } else {
5845 y_skip = 0;
5846 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
5847 &dist_y, best_rd) >= best_rd) {
5848 rd_cost->rate = INT_MAX;
5849 return;
5850 }
5851 }
5852 max_uv_tx_size = get_uv_tx_size_impl(xd->mi[0]->mbmi.tx_size, bsize,
5853 pd[1].subsampling_x,
5854 pd[1].subsampling_y);
5855 rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv, &rate_uv_tokenonly,
James Zern5e16d392015-08-17 18:19:22 -07005856 &dist_uv, &uv_skip, VPXMAX(BLOCK_8X8, bsize),
Jingning Han3ee6db62015-08-05 19:00:31 -07005857 max_uv_tx_size);
5858
5859 if (y_skip && uv_skip) {
5860 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
5861 vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
5862 rd_cost->dist = dist_y + dist_uv;
5863 } else {
5864 rd_cost->rate = rate_y + rate_uv +
5865 vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
5866 rd_cost->dist = dist_y + dist_uv;
5867 }
5868
5869 ctx->mic = *xd->mi[0];
5870 ctx->mbmi_ext = *x->mbmi_ext;
5871 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
5872}
5873
5874// This function is designed to apply a bias or adjustment to an rd value based
5875// on the relative variance of the source and reconstruction.
5876#define LOW_VAR_THRESH 16
5877#define VLOW_ADJ_MAX 25
5878#define VHIGH_ADJ_MAX 8
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005879static void rd_variance_adjustment(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07005880 MACROBLOCK *x,
5881 BLOCK_SIZE bsize,
5882 int64_t *this_rd,
5883 MV_REFERENCE_FRAME ref_frame,
5884 unsigned int source_variance) {
5885 MACROBLOCKD *const xd = &x->e_mbd;
5886 unsigned int recon_variance;
5887 unsigned int absvar_diff = 0;
5888 int64_t var_error = 0;
5889 int64_t var_factor = 0;
5890
5891 if (*this_rd == INT64_MAX)
5892 return;
5893
5894#if CONFIG_VP9_HIGHBITDEPTH
5895 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5896 recon_variance =
5897 vp10_high_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize, xd->bd);
5898 } else {
5899 recon_variance =
5900 vp10_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
5901 }
5902#else
5903 recon_variance =
5904 vp10_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
5905#endif // CONFIG_VP9_HIGHBITDEPTH
5906
5907 if ((source_variance + recon_variance) > LOW_VAR_THRESH) {
5908 absvar_diff = (source_variance > recon_variance)
5909 ? (source_variance - recon_variance)
5910 : (recon_variance - source_variance);
5911
Alex Converseb1fcd172015-11-19 14:53:51 -08005912 var_error = ((int64_t)200 * source_variance * recon_variance) /
5913 (((int64_t)source_variance * source_variance) +
5914 ((int64_t)recon_variance * recon_variance));
Jingning Han3ee6db62015-08-05 19:00:31 -07005915 var_error = 100 - var_error;
5916 }
5917
5918 // Source variance above a threshold and ref frame is intra.
5919 // This case is targeted mainly at discouraging intra modes that give rise
5920 // to a predictor with a low spatial complexity compared to the source.
5921 if ((source_variance > LOW_VAR_THRESH) && (ref_frame == INTRA_FRAME) &&
5922 (source_variance > recon_variance)) {
James Zern5e16d392015-08-17 18:19:22 -07005923 var_factor = VPXMIN(absvar_diff, VPXMIN(VLOW_ADJ_MAX, var_error));
Jingning Han3ee6db62015-08-05 19:00:31 -07005924 // A second possible case of interest is where the source variance
5925 // is very low and we wish to discourage false texture or motion trails.
5926 } else if ((source_variance < (LOW_VAR_THRESH >> 1)) &&
5927 (recon_variance > source_variance)) {
James Zern5e16d392015-08-17 18:19:22 -07005928 var_factor = VPXMIN(absvar_diff, VPXMIN(VHIGH_ADJ_MAX, var_error));
Jingning Han3ee6db62015-08-05 19:00:31 -07005929 }
5930 *this_rd += (*this_rd * var_factor) / 100;
5931}
5932
5933
5934// Do we have an internal image edge (e.g. formatting bars).
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005935int vp10_internal_image_edge(VP10_COMP *cpi) {
Jingning Han3ee6db62015-08-05 19:00:31 -07005936 return (cpi->oxcf.pass == 2) &&
5937 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
5938 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
5939}
5940
5941// Checks to see if a super block is on a horizontal image edge.
5942// In most cases this is the "real" edge unless there are formatting
5943// bars embedded in the stream.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005944int vp10_active_h_edge(VP10_COMP *cpi, int mi_row, int mi_step) {
Jingning Han3ee6db62015-08-05 19:00:31 -07005945 int top_edge = 0;
5946 int bottom_edge = cpi->common.mi_rows;
5947 int is_active_h_edge = 0;
5948
5949 // For two pass account for any formatting bars detected.
5950 if (cpi->oxcf.pass == 2) {
5951 TWO_PASS *twopass = &cpi->twopass;
5952
5953 // The inactive region is specified in MBs not mi units.
5954 // The image edge is in the following MB row.
5955 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
5956
5957 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
James Zern5e16d392015-08-17 18:19:22 -07005958 bottom_edge = VPXMAX(top_edge, bottom_edge);
Jingning Han3ee6db62015-08-05 19:00:31 -07005959 }
5960
5961 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
5962 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
5963 is_active_h_edge = 1;
5964 }
5965 return is_active_h_edge;
5966}
5967
5968// Checks to see if a super block is on a vertical image edge.
5969// In most cases this is the "real" edge unless there are formatting
5970// bars embedded in the stream.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005971int vp10_active_v_edge(VP10_COMP *cpi, int mi_col, int mi_step) {
Jingning Han3ee6db62015-08-05 19:00:31 -07005972 int left_edge = 0;
5973 int right_edge = cpi->common.mi_cols;
5974 int is_active_v_edge = 0;
5975
5976 // For two pass account for any formatting bars detected.
5977 if (cpi->oxcf.pass == 2) {
5978 TWO_PASS *twopass = &cpi->twopass;
5979
5980 // The inactive region is specified in MBs not mi units.
5981 // The image edge is in the following MB row.
5982 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
5983
5984 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
James Zern5e16d392015-08-17 18:19:22 -07005985 right_edge = VPXMAX(left_edge, right_edge);
Jingning Han3ee6db62015-08-05 19:00:31 -07005986 }
5987
5988 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
5989 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
5990 is_active_v_edge = 1;
5991 }
5992 return is_active_v_edge;
5993}
5994
5995// Checks to see if a super block is at the edge of the active image.
5996// In most cases this is the "real" edge unless there are formatting
5997// bars embedded in the stream.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005998int vp10_active_edge_sb(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07005999 int mi_row, int mi_col) {
6000 return vp10_active_h_edge(cpi, mi_row, MI_BLOCK_SIZE) ||
6001 vp10_active_v_edge(cpi, mi_col, MI_BLOCK_SIZE);
6002}
6003
Yaowu Xu26a9afc2015-08-13 09:42:27 -07006004void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
Jingning Han4fa8e732015-09-10 12:24:06 -07006005 TileDataEnc *tile_data,
6006 MACROBLOCK *x,
6007 int mi_row, int mi_col,
Debargha Mukherjee3787b172015-11-19 16:51:16 -08006008 RD_COST *rd_cost,
6009#if CONFIG_SUPERTX
6010 int *returnrate_nocoef,
6011#endif // CONFIG_SUPERTX
6012 BLOCK_SIZE bsize,
Jingning Han4fa8e732015-09-10 12:24:06 -07006013 PICK_MODE_CONTEXT *ctx,
6014 int64_t best_rd_so_far) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07006015 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07006016 RD_OPT *const rd_opt = &cpi->rd;
6017 SPEED_FEATURES *const sf = &cpi->sf;
6018 MACROBLOCKD *const xd = &x->e_mbd;
6019 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6020 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6021 const struct segmentation *const seg = &cm->seg;
6022 PREDICTION_MODE this_mode;
6023 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
6024 unsigned char segment_id = mbmi->segment_id;
6025 int comp_pred, i, k;
6026 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
Zoe Liu3ec16012015-11-12 02:12:17 -08006027 struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE];
Yue Chen1ac85872016-01-07 15:13:52 -08006028#if CONFIG_EXT_INTER
6029 int_mv single_newmvs[2][MAX_REF_FRAMES] = { { { 0 } }, { { 0 } } };
6030#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006031 int_mv single_newmv[MAX_REF_FRAMES] = { { 0 } };
Yue Chen1ac85872016-01-07 15:13:52 -08006032#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006033 INTERP_FILTER single_inter_filter[MB_MODE_COUNT][MAX_REF_FRAMES];
6034 int single_skippable[MB_MODE_COUNT][MAX_REF_FRAMES];
Zoe Liu3ec16012015-11-12 02:12:17 -08006035 static const int flag_list[REFS_PER_FRAME + 1] = {
6036 0,
6037 VP9_LAST_FLAG,
6038#if CONFIG_EXT_REFS
6039 VP9_LAST2_FLAG,
6040 VP9_LAST3_FLAG,
6041 VP9_LAST4_FLAG,
6042#endif // CONFIG_EXT_REFS
6043 VP9_GOLD_FLAG,
6044 VP9_ALT_FLAG
6045 };
Jingning Han3ee6db62015-08-05 19:00:31 -07006046 int64_t best_rd = best_rd_so_far;
6047 int64_t best_pred_diff[REFERENCE_MODES];
6048 int64_t best_pred_rd[REFERENCE_MODES];
6049 int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
6050 int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
6051 MB_MODE_INFO best_mbmode;
Jingning Han67cf8902016-01-15 09:05:51 -08006052#if CONFIG_REF_MV
Jingning Han28e03932016-01-20 17:40:47 -08006053 uint8_t best_ref_mv_idx[MODE_CTX_REF_FRAMES] = { 0 };
Jingning Han67cf8902016-01-15 09:05:51 -08006054#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07006055 int best_mode_skippable = 0;
6056 int midx, best_mode_index = -1;
6057 unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
6058 vpx_prob comp_mode_p;
6059 int64_t best_intra_rd = INT64_MAX;
6060 unsigned int best_pred_sse = UINT_MAX;
6061 PREDICTION_MODE best_intra_mode = DC_PRED;
6062 int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES];
6063 int64_t dist_uv[TX_SIZES];
6064 int skip_uv[TX_SIZES];
6065 PREDICTION_MODE mode_uv[TX_SIZES];
hui sube3559b2015-10-07 09:29:02 -07006066#if CONFIG_EXT_INTRA
6067 EXT_INTRA_MODE_INFO ext_intra_mode_info_uv[TX_SIZES];
hui su4aa50c12015-11-10 12:09:59 -08006068 int8_t uv_angle_delta[TX_SIZES];
hui sud7c8bc72015-11-12 19:18:32 -08006069 int is_directional_mode, angle_stats_ready = 0;
hui su4aa50c12015-11-10 12:09:59 -08006070 int rate_overhead, rate_dummy;
hui sud7c8bc72015-11-12 19:18:32 -08006071 uint8_t directional_mode_skip_mask[INTRA_MODES];
hui sube3559b2015-10-07 09:29:02 -07006072#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07006073 const int intra_cost_penalty = vp10_get_intra_cost_penalty(
6074 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
hui su1559afd2015-12-30 10:27:19 -08006075 const int * const intra_mode_cost =
6076 cpi->mbmode_cost[size_group_lookup[bsize]];
Jingning Han3ee6db62015-08-05 19:00:31 -07006077 int best_skip2 = 0;
6078 uint8_t ref_frame_skip_mask[2] = { 0 };
Yue Chen1ac85872016-01-07 15:13:52 -08006079#if CONFIG_EXT_INTER
6080 uint32_t mode_skip_mask[MAX_REF_FRAMES] = { 0 };
6081#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006082 uint16_t mode_skip_mask[MAX_REF_FRAMES] = { 0 };
Yue Chen1ac85872016-01-07 15:13:52 -08006083#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006084 int mode_skip_start = sf->mode_skip_start + 1;
6085 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
6086 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
6087 int64_t mode_threshold[MAX_MODES];
6088 int *mode_map = tile_data->mode_map[bsize];
6089 const int mode_search_skip_flags = sf->mode_search_skip_flags;
6090 int64_t mask_filter = 0;
6091 int64_t filter_cache[SWITCHABLE_FILTER_CONTEXTS];
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08006092 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
6093 const vpx_prob *tx_probs = get_tx_probs2(max_tx_size, xd, &cm->fc->tx_probs);
Yue Chend1cad9c2016-01-27 14:18:53 -08006094#if CONFIG_OBMC
6095#if CONFIG_VP9_HIGHBITDEPTH
6096 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * 64 * 64]);
6097 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * 64 * 64]);
6098#else
6099 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * 64 * 64]);
6100 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * 64 * 64]);
6101#endif // CONFIG_VP9_HIGHBITDEPTH
6102 uint8_t *dst_buf1[3], *dst_buf2[3];
6103 int dst_stride1[3] = {64, 64, 64};
6104 int dst_stride2[3] = {64, 64, 64};
6105
6106#if CONFIG_VP9_HIGHBITDEPTH
6107 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6108 int len = sizeof(uint16_t);
6109 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
6110 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + 4096 * len);
6111 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 8192 * len);
6112 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
6113 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + 4096 * len);
6114 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 8192 * len);
6115 } else {
6116#endif // CONFIG_VP9_HIGHBITDEPTH
6117 dst_buf1[0] = tmp_buf1;
6118 dst_buf1[1] = tmp_buf1 + 4096;
6119 dst_buf1[2] = tmp_buf1 + 8192;
6120 dst_buf2[0] = tmp_buf2;
6121 dst_buf2[1] = tmp_buf2 + 4096;
6122 dst_buf2[2] = tmp_buf2 + 8192;
6123#if CONFIG_VP9_HIGHBITDEPTH
6124 }
6125#endif // CONFIG_VP9_HIGHBITDEPTH
6126#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006127
6128 vp10_zero(best_mbmode);
6129
hui sud7c8bc72015-11-12 19:18:32 -08006130#if CONFIG_EXT_INTRA
6131 memset(directional_mode_skip_mask, 0,
6132 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
6133#endif // CONFIG_EXT_INTRA
6134
Jingning Han3ee6db62015-08-05 19:00:31 -07006135 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
6136 filter_cache[i] = INT64_MAX;
6137
6138 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
6139 &comp_mode_p);
6140
6141 for (i = 0; i < REFERENCE_MODES; ++i)
6142 best_pred_rd[i] = INT64_MAX;
6143 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
6144 best_filter_rd[i] = INT64_MAX;
6145 for (i = 0; i < TX_SIZES; i++)
6146 rate_uv_intra[i] = INT_MAX;
6147 for (i = 0; i < MAX_REF_FRAMES; ++i)
6148 x->pred_sse[i] = INT_MAX;
6149 for (i = 0; i < MB_MODE_COUNT; ++i) {
6150 for (k = 0; k < MAX_REF_FRAMES; ++k) {
6151 single_inter_filter[i][k] = SWITCHABLE;
6152 single_skippable[i][k] = 0;
6153 }
6154 }
6155
6156 rd_cost->rate = INT_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08006157#if CONFIG_SUPERTX
6158 *returnrate_nocoef = INT_MAX;
6159#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07006160
6161 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
6162 x->pred_mv_sad[ref_frame] = INT_MAX;
Jingning Han387a10e2015-12-09 09:07:39 -08006163 x->mbmi_ext->mode_context[ref_frame] = 0;
Yue Chen968bbc72016-01-19 16:45:45 -08006164#if CONFIG_REF_MV && CONFIG_EXT_INTER
6165 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
6166#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006167 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
6168 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
6169 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
6170 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
6171 }
6172 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
6173 frame_mv[ZEROMV][ref_frame].as_int = 0;
Yue Chen1ac85872016-01-07 15:13:52 -08006174#if CONFIG_EXT_INTER
6175 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
Yue Chen968bbc72016-01-19 16:45:45 -08006176 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
6177 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
Yue Chen1ac85872016-01-07 15:13:52 -08006178#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006179 }
6180
Jingning Han33cc1bd2016-01-12 15:06:59 -08006181#if CONFIG_REF_MV
6182 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
6183 MODE_INFO *const mi = xd->mi[0];
6184 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
6185 x->mbmi_ext->mode_context[ref_frame] = 0;
6186 vp10_find_mv_refs(cm, xd, mi, ref_frame,
6187#if CONFIG_REF_MV
6188 &mbmi_ext->ref_mv_count[ref_frame],
6189 mbmi_ext->ref_mv_stack[ref_frame],
Yue Chen968bbc72016-01-19 16:45:45 -08006190#if CONFIG_EXT_INTER
6191 mbmi_ext->compound_mode_context,
6192#endif // CONFIG_EXT_INTER
Jingning Han33cc1bd2016-01-12 15:06:59 -08006193#endif
6194 candidates, mi_row, mi_col,
6195 NULL, NULL, mbmi_ext->mode_context);
6196 }
6197#endif
6198
Yue Chend1cad9c2016-01-27 14:18:53 -08006199#if CONFIG_OBMC
6200 vp10_build_prediction_by_above_preds(cpi, xd, mi_row, mi_col, dst_buf1,
6201 dst_stride1);
6202 vp10_build_prediction_by_left_preds(cpi, xd, mi_row, mi_col, dst_buf2,
6203 dst_stride2);
6204 vp10_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
6205#endif // CONFIG_OBMC
6206
Jingning Han3ee6db62015-08-05 19:00:31 -07006207 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
6208 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
6209 // Skip checking missing references in both single and compound reference
6210 // modes. Note that a mode will be skipped iff both reference frames
6211 // are masked out.
6212 ref_frame_skip_mask[0] |= (1 << ref_frame);
6213 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
Jingning Han1eb760e2015-09-10 12:56:41 -07006214 } else {
Jingning Han3ee6db62015-08-05 19:00:31 -07006215 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
6216 // Skip fixed mv modes for poor references
6217 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
6218 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
6219 break;
6220 }
6221 }
6222 }
6223 // If the segment reference frame feature is enabled....
6224 // then do nothing if the current ref frame is not allowed..
6225 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
6226 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
6227 ref_frame_skip_mask[0] |= (1 << ref_frame);
6228 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
6229 }
6230 }
6231
6232 // Disable this drop out case if the ref frame
6233 // segment level feature is enabled for this segment. This is to
6234 // prevent the possibility that we end up unable to pick any mode.
6235 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
6236 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
6237 // unless ARNR filtering is enabled in which case we want
6238 // an unfiltered alternative. We allow near/nearest as well
6239 // because they may result in zero-zero MVs but be cheaper.
6240 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Zoe Liu3ec16012015-11-12 02:12:17 -08006241 ref_frame_skip_mask[0] =
6242 (1 << LAST_FRAME) |
6243#if CONFIG_EXT_REFS
6244 (1 << LAST2_FRAME) |
6245 (1 << LAST3_FRAME) |
6246 (1 << LAST4_FRAME) |
6247#endif // CONFIG_EXT_REFS
6248 (1 << GOLDEN_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07006249 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
6250 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
6251 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != 0)
6252 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
6253 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != 0)
6254 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
Yue Chen968bbc72016-01-19 16:45:45 -08006255#if CONFIG_EXT_INTER
6256 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != 0)
6257 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
6258 if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != 0)
6259 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
6260 if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != 0)
6261 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
6262#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006263 }
6264 }
6265
6266 if (cpi->rc.is_src_frame_alt_ref) {
6267 if (sf->alt_ref_search_fp) {
6268 mode_skip_mask[ALTREF_FRAME] = 0;
6269 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
6270 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
6271 }
6272 }
6273
6274 if (sf->alt_ref_search_fp)
6275 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
6276 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
6277 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
6278
6279 if (sf->adaptive_mode_search) {
6280 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
6281 cpi->rc.frames_since_golden >= 3)
6282 if (x->pred_mv_sad[GOLDEN_FRAME] > (x->pred_mv_sad[LAST_FRAME] << 1))
6283 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
6284 }
6285
6286 if (bsize > sf->max_intra_bsize) {
6287 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
6288 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
6289 }
6290
6291 mode_skip_mask[INTRA_FRAME] |=
6292 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
6293
6294 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i)
6295 mode_threshold[i] = 0;
6296 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
6297 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
6298
6299 midx = sf->schedule_mode_search ? mode_skip_start : 0;
6300 while (midx > 4) {
6301 uint8_t end_pos = 0;
6302 for (i = 5; i < midx; ++i) {
6303 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
6304 uint8_t tmp = mode_map[i];
6305 mode_map[i] = mode_map[i - 1];
6306 mode_map[i - 1] = tmp;
6307 end_pos = i;
6308 }
6309 }
6310 midx = end_pos;
6311 }
6312
hui suc93e5cc2015-12-07 18:18:57 -08006313 mbmi->palette_mode_info.palette_size[0] = 0;
6314 mbmi->palette_mode_info.palette_size[1] = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07006315 for (midx = 0; midx < MAX_MODES; ++midx) {
6316 int mode_index = mode_map[midx];
6317 int mode_excluded = 0;
6318 int64_t this_rd = INT64_MAX;
6319 int disable_skip = 0;
6320 int compmode_cost = 0;
6321 int rate2 = 0, rate_y = 0, rate_uv = 0;
6322 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
6323 int skippable = 0;
6324 int this_skip2 = 0;
6325 int64_t total_sse = INT64_MAX;
6326 int early_term = 0;
Jingning Han28e03932016-01-20 17:40:47 -08006327#if CONFIG_REF_MV
6328 uint8_t ref_frame_type;
6329#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07006330
6331 this_mode = vp10_mode_order[mode_index].mode;
6332 ref_frame = vp10_mode_order[mode_index].ref_frame[0];
6333 second_ref_frame = vp10_mode_order[mode_index].ref_frame[1];
6334
Yue Chen968bbc72016-01-19 16:45:45 -08006335#if CONFIG_EXT_INTER
6336 if (this_mode == NEAREST_NEARESTMV) {
6337 frame_mv[NEAREST_NEARESTMV][ref_frame].as_int =
6338 frame_mv[NEARESTMV][ref_frame].as_int;
6339 frame_mv[NEAREST_NEARESTMV][second_ref_frame].as_int =
6340 frame_mv[NEARESTMV][second_ref_frame].as_int;
6341 } else if (this_mode == NEAREST_NEARMV) {
6342 frame_mv[NEAREST_NEARMV][ref_frame].as_int =
6343 frame_mv[NEARESTMV][ref_frame].as_int;
6344 frame_mv[NEAREST_NEARMV][second_ref_frame].as_int =
6345 frame_mv[NEARMV][second_ref_frame].as_int;
6346 } else if (this_mode == NEAR_NEARESTMV) {
6347 frame_mv[NEAR_NEARESTMV][ref_frame].as_int =
6348 frame_mv[NEARMV][ref_frame].as_int;
6349 frame_mv[NEAR_NEARESTMV][second_ref_frame].as_int =
6350 frame_mv[NEARESTMV][second_ref_frame].as_int;
6351 } else if (this_mode == NEAREST_NEWMV) {
6352 frame_mv[NEAREST_NEWMV][ref_frame].as_int =
6353 frame_mv[NEARESTMV][ref_frame].as_int;
6354 frame_mv[NEAREST_NEWMV][second_ref_frame].as_int =
6355 frame_mv[NEWMV][second_ref_frame].as_int;
6356 } else if (this_mode == NEW_NEARESTMV) {
6357 frame_mv[NEW_NEARESTMV][ref_frame].as_int =
6358 frame_mv[NEWMV][ref_frame].as_int;
6359 frame_mv[NEW_NEARESTMV][second_ref_frame].as_int =
6360 frame_mv[NEARESTMV][second_ref_frame].as_int;
6361 } else if (this_mode == NEAR_NEWMV) {
6362 frame_mv[NEAR_NEWMV][ref_frame].as_int =
6363 frame_mv[NEARMV][ref_frame].as_int;
6364 frame_mv[NEAR_NEWMV][second_ref_frame].as_int =
6365 frame_mv[NEWMV][second_ref_frame].as_int;
6366 } else if (this_mode == NEW_NEARMV) {
6367 frame_mv[NEW_NEARMV][ref_frame].as_int =
6368 frame_mv[NEWMV][ref_frame].as_int;
6369 frame_mv[NEW_NEARMV][second_ref_frame].as_int =
6370 frame_mv[NEARMV][second_ref_frame].as_int;
6371 } else if (this_mode == NEW_NEWMV) {
6372 frame_mv[NEW_NEWMV][ref_frame].as_int =
6373 frame_mv[NEWMV][ref_frame].as_int;
6374 frame_mv[NEW_NEWMV][second_ref_frame].as_int =
6375 frame_mv[NEWMV][second_ref_frame].as_int;
6376 }
6377#endif // CONFIG_EXT_INTER
6378
Jingning Han3ee6db62015-08-05 19:00:31 -07006379 // Look at the reference frame of the best mode so far and set the
6380 // skip mask to look at a subset of the remaining modes.
6381 if (midx == mode_skip_start && best_mode_index >= 0) {
6382 switch (best_mbmode.ref_frame[0]) {
6383 case INTRA_FRAME:
6384 break;
6385 case LAST_FRAME:
6386 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
6387 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
6388 break;
Zoe Liu3ec16012015-11-12 02:12:17 -08006389#if CONFIG_EXT_REFS
6390 case LAST2_FRAME:
6391 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
6392 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
6393 break;
6394 case LAST3_FRAME:
6395 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
6396 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
6397 break;
6398 case LAST4_FRAME:
6399 ref_frame_skip_mask[0] |= LAST4_FRAME_MODE_MASK;
6400 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
6401 break;
6402#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07006403 case GOLDEN_FRAME:
6404 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
6405 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
6406 break;
6407 case ALTREF_FRAME:
6408 ref_frame_skip_mask[0] |= ALT_REF_MODE_MASK;
6409 break;
6410 case NONE:
6411 case MAX_REF_FRAMES:
6412 assert(0 && "Invalid Reference frame");
6413 break;
6414 }
6415 }
6416
6417 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
James Zern5e16d392015-08-17 18:19:22 -07006418 (ref_frame_skip_mask[1] & (1 << VPXMAX(0, second_ref_frame))))
Jingning Han3ee6db62015-08-05 19:00:31 -07006419 continue;
6420
6421 if (mode_skip_mask[ref_frame] & (1 << this_mode))
6422 continue;
6423
6424 // Test best rd so far against threshold for trying this mode.
6425 if (best_mode_skippable && sf->schedule_mode_search)
6426 mode_threshold[mode_index] <<= 1;
6427
6428 if (best_rd < mode_threshold[mode_index])
6429 continue;
6430
Jingning Han3ee6db62015-08-05 19:00:31 -07006431 comp_pred = second_ref_frame > INTRA_FRAME;
6432 if (comp_pred) {
6433 if (!cpi->allow_comp_inter_inter)
6434 continue;
6435
6436 // Skip compound inter modes if ARF is not available.
6437 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
6438 continue;
6439
6440 // Do not allow compound prediction if the segment level reference frame
6441 // feature is in use as in this case there can only be one reference.
6442 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
6443 continue;
6444
6445 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
6446 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
6447 continue;
6448
6449 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
6450 } else {
6451 if (ref_frame != INTRA_FRAME)
6452 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
6453 }
6454
6455 if (ref_frame == INTRA_FRAME) {
6456 if (sf->adaptive_mode_search)
6457 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
6458 continue;
6459
6460 if (this_mode != DC_PRED) {
6461 // Disable intra modes other than DC_PRED for blocks with low variance
6462 // Threshold for intra skipping based on source variance
6463 // TODO(debargha): Specialize the threshold for super block sizes
6464 const unsigned int skip_intra_var_thresh = 64;
6465 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
6466 x->source_variance < skip_intra_var_thresh)
6467 continue;
6468 // Only search the oblique modes if the best so far is
6469 // one of the neighboring directional modes
6470 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
6471 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
6472 if (best_mode_index >= 0 &&
6473 best_mbmode.ref_frame[0] > INTRA_FRAME)
6474 continue;
6475 }
6476 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
6477 if (conditional_skipintra(this_mode, best_intra_mode))
6478 continue;
6479 }
6480 }
6481 } else {
6482 const MV_REFERENCE_FRAME ref_frames[2] = {ref_frame, second_ref_frame};
Yue Chen968bbc72016-01-19 16:45:45 -08006483 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
6484#if CONFIG_REF_MV && CONFIG_EXT_INTER
6485 mbmi_ext->compound_mode_context,
6486#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
6487 frame_mv,
Jingning Han387a10e2015-12-09 09:07:39 -08006488 this_mode, ref_frames, bsize, -1))
Jingning Han3ee6db62015-08-05 19:00:31 -07006489 continue;
6490 }
6491
6492 mbmi->mode = this_mode;
6493 mbmi->uv_mode = DC_PRED;
6494 mbmi->ref_frame[0] = ref_frame;
6495 mbmi->ref_frame[1] = second_ref_frame;
hui sube3559b2015-10-07 09:29:02 -07006496#if CONFIG_EXT_INTRA
6497 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
6498 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
6499#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07006500 // Evaluate all sub-pel filters irrespective of whether we can use
6501 // them for this frame.
6502 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP
6503 : cm->interp_filter;
6504 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chend1cad9c2016-01-27 14:18:53 -08006505#if CONFIG_OBMC
6506 mbmi->obmc = 0;
6507#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006508
6509 x->skip = 0;
6510 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
6511
6512 // Select prediction reference frames.
6513 for (i = 0; i < MAX_MB_PLANE; i++) {
6514 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
6515 if (comp_pred)
6516 xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
6517 }
6518
6519 if (ref_frame == INTRA_FRAME) {
6520 TX_SIZE uv_tx;
6521 struct macroblockd_plane *const pd = &xd->plane[1];
6522 memset(x->skip_txfm, 0, sizeof(x->skip_txfm));
hui su4aa50c12015-11-10 12:09:59 -08006523
hui sube3559b2015-10-07 09:29:02 -07006524#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08006525 is_directional_mode = (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED);
6526 if (is_directional_mode) {
hui sud7c8bc72015-11-12 19:18:32 -08006527 if (!angle_stats_ready) {
6528 const int src_stride = x->plane[0].src.stride;
6529 const uint8_t *src = x->plane[0].src.buf;
6530 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
6531 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
6532 double hist[DIRECTIONAL_MODES];
6533 PREDICTION_MODE mode;
6534
6535#if CONFIG_VP9_HIGHBITDEPTH
6536 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
6537 highbd_angle_estimation(src, src_stride, rows, cols, hist);
6538 else
6539#endif
6540 angle_estimation(src, src_stride, rows, cols, hist);
6541 for (mode = 0; mode < INTRA_MODES; ++mode) {
6542 if (mode != DC_PRED && mode != TM_PRED) {
6543 int index = get_angle_index((double)mode_to_angle_map[mode]);
6544 double score, weight = 1.0;
6545 score = hist[index];
6546 if (index > 0) {
6547 score += hist[index - 1] * 0.5;
6548 weight += 0.5;
6549 }
6550 if (index < DIRECTIONAL_MODES - 1) {
6551 score += hist[index + 1] * 0.5;
6552 weight += 0.5;
6553 }
6554 score /= weight;
6555 if (score < ANGLE_SKIP_THRESH)
6556 directional_mode_skip_mask[mode] = 1;
6557 }
6558 }
6559 angle_stats_ready = 1;
6560 }
6561 if (directional_mode_skip_mask[mbmi->mode])
6562 continue;
hui su4aa50c12015-11-10 12:09:59 -08006563 rate_overhead = write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0) +
hui su1559afd2015-12-30 10:27:19 -08006564 intra_mode_cost[mbmi->mode];
hui su4aa50c12015-11-10 12:09:59 -08006565 rate_y = INT_MAX;
6566 this_rd =
6567 rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
6568 &skippable, bsize, rate_overhead, best_rd);
6569 } else {
6570 mbmi->angle_delta[0] = 0;
6571 super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
6572 NULL, bsize, best_rd);
6573 }
6574
hui sube3559b2015-10-07 09:29:02 -07006575 // TODO(huisu): ext-intra is turned off in lossless mode for now to
6576 // avoid a unit test failure
hui su4aa50c12015-11-10 12:09:59 -08006577 if (mbmi->mode == DC_PRED && !xd->lossless[mbmi->segment_id] &&
6578 ALLOW_FILTER_INTRA_MODES) {
hui sube3559b2015-10-07 09:29:02 -07006579 MB_MODE_INFO mbmi_copy = *mbmi;
hui sube3559b2015-10-07 09:29:02 -07006580
6581 if (rate_y != INT_MAX) {
hui su1559afd2015-12-30 10:27:19 -08006582 int this_rate = rate_y + intra_mode_cost[mbmi->mode] +
hui sube3559b2015-10-07 09:29:02 -07006583 vp10_cost_bit(cm->fc->ext_intra_probs[0], 0);
6584 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, distortion_y);
6585 } else {
6586 this_rd = best_rd;
6587 }
6588
6589 if (!rd_pick_ext_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
6590 &skippable, bsize,
hui su1559afd2015-12-30 10:27:19 -08006591 intra_mode_cost[mbmi->mode], &this_rd))
hui sube3559b2015-10-07 09:29:02 -07006592 *mbmi = mbmi_copy;
6593 }
hui su4aa50c12015-11-10 12:09:59 -08006594#else
6595 super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
6596 NULL, bsize, best_rd);
hui sube3559b2015-10-07 09:29:02 -07006597#endif // CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08006598
Jingning Han3ee6db62015-08-05 19:00:31 -07006599 if (rate_y == INT_MAX)
6600 continue;
Jingning Han3ee6db62015-08-05 19:00:31 -07006601 uv_tx = get_uv_tx_size_impl(mbmi->tx_size, bsize, pd->subsampling_x,
6602 pd->subsampling_y);
6603 if (rate_uv_intra[uv_tx] == INT_MAX) {
6604 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx,
6605 &rate_uv_intra[uv_tx], &rate_uv_tokenonly[uv_tx],
6606 &dist_uv[uv_tx], &skip_uv[uv_tx], &mode_uv[uv_tx]);
hui sube3559b2015-10-07 09:29:02 -07006607#if CONFIG_EXT_INTRA
6608 ext_intra_mode_info_uv[uv_tx] = mbmi->ext_intra_mode_info;
hui su4aa50c12015-11-10 12:09:59 -08006609 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui sube3559b2015-10-07 09:29:02 -07006610#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07006611 }
6612
6613 rate_uv = rate_uv_tokenonly[uv_tx];
6614 distortion_uv = dist_uv[uv_tx];
6615 skippable = skippable && skip_uv[uv_tx];
6616 mbmi->uv_mode = mode_uv[uv_tx];
hui sube3559b2015-10-07 09:29:02 -07006617#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08006618 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui sube3559b2015-10-07 09:29:02 -07006619 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
6620 ext_intra_mode_info_uv[uv_tx].use_ext_intra_mode[1];
6621 if (ext_intra_mode_info_uv[uv_tx].use_ext_intra_mode[1]) {
6622 mbmi->ext_intra_mode_info.ext_intra_mode[1] =
6623 ext_intra_mode_info_uv[uv_tx].ext_intra_mode[1];
hui sube3559b2015-10-07 09:29:02 -07006624 }
6625#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07006626
hui su1559afd2015-12-30 10:27:19 -08006627 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv_intra[uv_tx];
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08006628
6629 if (!xd->lossless[mbmi->segment_id]) {
6630 // super_block_yrd above includes the cost of the tx_size in the
6631 // tokenonly rate, but for intra blocks, tx_size is always coded
6632 // (prediction granularity), so we account for it in the full rate,
6633 // not the tokenonly rate.
6634 rate_y -= vp10_cost_tx_size(mbmi->tx_size, max_tx_size, tx_probs);
6635 }
hui sube3559b2015-10-07 09:29:02 -07006636#if CONFIG_EXT_INTRA
hui su3b1c7662016-01-12 16:38:58 -08006637 if (is_directional_mode) {
6638 int p_angle;
6639 const int intra_filter_ctx = vp10_get_pred_context_intra_interp(xd);
hui su4aa50c12015-11-10 12:09:59 -08006640 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
6641 MAX_ANGLE_DELTAS +
6642 mbmi->angle_delta[0]);
hui su3b1c7662016-01-12 16:38:58 -08006643 p_angle = mode_to_angle_map[mbmi->mode] +
6644 mbmi->angle_delta[0] * ANGLE_STEP;
6645 if (pick_intra_filter(p_angle))
6646 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
6647 }
hui su4aa50c12015-11-10 12:09:59 -08006648
6649 if (mbmi->mode == DC_PRED && ALLOW_FILTER_INTRA_MODES) {
hui sube3559b2015-10-07 09:29:02 -07006650 rate2 += vp10_cost_bit(cm->fc->ext_intra_probs[0],
6651 mbmi->ext_intra_mode_info.use_ext_intra_mode[0]);
6652 if (mbmi->ext_intra_mode_info.use_ext_intra_mode[0]) {
6653 EXT_INTRA_MODE ext_intra_mode =
6654 mbmi->ext_intra_mode_info.ext_intra_mode[0];
hui su4aa50c12015-11-10 12:09:59 -08006655 rate2 += write_uniform_cost(FILTER_INTRA_MODES, ext_intra_mode);
hui sube3559b2015-10-07 09:29:02 -07006656 }
6657 }
6658#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07006659 if (this_mode != DC_PRED && this_mode != TM_PRED)
6660 rate2 += intra_cost_penalty;
6661 distortion2 = distortion_y + distortion_uv;
6662 } else {
Jingning Han28e03932016-01-20 17:40:47 -08006663#if CONFIG_REF_MV
6664 mbmi->ref_mv_idx = 0;
6665 ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
6666#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07006667 this_rd = handle_inter_mode(cpi, x, bsize,
6668 &rate2, &distortion2, &skippable,
6669 &rate_y, &rate_uv,
6670 &disable_skip, frame_mv,
6671 mi_row, mi_col,
Yue Chend1cad9c2016-01-27 14:18:53 -08006672#if CONFIG_OBMC
6673 dst_buf1, dst_stride1,
6674 dst_buf2, dst_stride2,
6675#endif // CONFIG_OBMC
Yue Chen1ac85872016-01-07 15:13:52 -08006676#if CONFIG_EXT_INTER
6677 single_newmvs,
6678#else
6679 single_newmv,
6680#endif // CONFIG_EXT_INTER
6681 single_inter_filter,
Jingning Han3ee6db62015-08-05 19:00:31 -07006682 single_skippable, &total_sse, best_rd,
6683 &mask_filter, filter_cache);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07006684
Jingning Han67cf8902016-01-15 09:05:51 -08006685#if CONFIG_REF_MV
Jingning Han4fb8b212016-01-19 16:36:25 -08006686 // TODO(jingning): This needs some refactoring to improve code quality
6687 // and reduce redundant steps.
Jingning Han28e03932016-01-20 17:40:47 -08006688 if (mbmi->mode == NEARMV &&
6689 mbmi_ext->ref_mv_count[ref_frame_type] > 2) {
Jingning Han67cf8902016-01-15 09:05:51 -08006690 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
6691 int_mv cur_mv = mbmi_ext->ref_mv_stack[ref_frame][2].this_mv;
6692 MB_MODE_INFO backup_mbmi = *mbmi;
6693
Jingning Han4fb8b212016-01-19 16:36:25 -08006694 int64_t tmp_ref_rd = this_rd;
6695 int ref_idx;
Jingning Han28e03932016-01-20 17:40:47 -08006696 int ref_set = VPXMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 2);
6697
Jingning Han49589872016-01-21 18:07:31 -08006698 uint8_t drl0_ctx =
Jingning Hana39e83d2016-02-11 16:38:13 -08006699 vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 1);
Jingning Han49589872016-01-21 18:07:31 -08006700 rate2 += cpi->drl_mode_cost0[drl0_ctx][0];
Jingning Han67cf8902016-01-15 09:05:51 -08006701
Jingning Han590265e2016-01-15 11:33:40 -08006702 if (this_rd < INT64_MAX) {
6703 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
6704 RDCOST(x->rdmult, x->rddiv, 0, total_sse))
6705 tmp_ref_rd = RDCOST(x->rdmult, x->rddiv,
6706 rate2 + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0),
6707 distortion2);
6708 else
6709 tmp_ref_rd = RDCOST(x->rdmult, x->rddiv,
6710 rate2 + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1) -
6711 rate_y - rate_uv,
6712 total_sse);
6713 }
6714
Jingning Han4fb8b212016-01-19 16:36:25 -08006715 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
6716 int64_t tmp_alt_rd = INT64_MAX;
6717 int tmp_rate = 0, tmp_rate_y = 0, tmp_rate_uv = 0;
6718 int tmp_skip = 1;
6719 int64_t tmp_dist = 0, tmp_sse = 0;
Jingning Han590265e2016-01-15 11:33:40 -08006720
Jingning Han4fb8b212016-01-19 16:36:25 -08006721 cur_mv = mbmi_ext->ref_mv_stack[ref_frame][2 + ref_idx].this_mv;
6722 lower_mv_precision(&cur_mv.as_mv, cm->allow_high_precision_mv);
6723 clamp_mv2(&cur_mv.as_mv, xd);
6724
6725 if (!mv_check_bounds(x, &cur_mv.as_mv)) {
6726 int64_t dummy_filter_cache[SWITCHABLE_FILTER_CONTEXTS];
6727 INTERP_FILTER dummy_single_inter_filter[MB_MODE_COUNT]
6728 [MAX_REF_FRAMES];
6729 int dummy_single_skippable[MB_MODE_COUNT][MAX_REF_FRAMES];
6730 int dummy_disable_skip = 0;
6731 int64_t dummy_mask_filter = 0;
6732#if CONFIG_EXT_INTER
6733 int_mv dummy_single_newmvs[2][MAX_REF_FRAMES] =
6734 { { { 0 } }, { { 0 } } };
6735#else
6736 int_mv dummy_single_newmv[MAX_REF_FRAMES] = { { 0 } };
6737#endif
6738
6739
Jingning Han28e03932016-01-20 17:40:47 -08006740 mbmi->ref_mv_idx = 1 + ref_idx;
6741
Jingning Han4fb8b212016-01-19 16:36:25 -08006742 frame_mv[NEARMV][ref_frame] = cur_mv;
6743 tmp_alt_rd = handle_inter_mode(cpi, x, bsize,
6744 &tmp_rate, &tmp_dist, &tmp_skip,
6745 &tmp_rate_y, &tmp_rate_uv,
6746 &dummy_disable_skip, frame_mv,
6747 mi_row, mi_col,
Yue Chend1cad9c2016-01-27 14:18:53 -08006748#if CONFIG_OBMC
6749 dst_buf1, dst_stride1,
6750 dst_buf2, dst_stride2,
6751#endif // CONFIG_OBMC
Jingning Han4fb8b212016-01-19 16:36:25 -08006752#if CONFIG_EXT_INTER
6753 dummy_single_newmvs,
6754#else
6755 dummy_single_newmv,
6756#endif
6757 dummy_single_inter_filter,
6758 dummy_single_skippable,
6759 &tmp_sse, best_rd,
6760 &dummy_mask_filter,
6761 dummy_filter_cache);
6762 }
6763
Jingning Han49589872016-01-21 18:07:31 -08006764 tmp_rate += cpi->drl_mode_cost0[drl0_ctx][1];
6765
6766 if (mbmi_ext->ref_mv_count[ref_frame_type] > 3) {
6767 uint8_t drl1_ctx =
Jingning Hana39e83d2016-02-11 16:38:13 -08006768 vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 2);
Jingning Han49589872016-01-21 18:07:31 -08006769 tmp_rate += cpi->drl_mode_cost1[drl1_ctx][ref_idx];
6770 }
Jingning Han4fb8b212016-01-19 16:36:25 -08006771
6772 if (tmp_alt_rd < INT64_MAX) {
6773 if (RDCOST(x->rdmult, x->rddiv,
6774 tmp_rate_y + tmp_rate_uv, tmp_dist) <
6775 RDCOST(x->rdmult, x->rddiv, 0, tmp_sse))
6776 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv,
6777 tmp_rate + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0),
6778 tmp_dist);
6779 else
6780 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv,
6781 tmp_rate + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1) -
6782 tmp_rate_y - tmp_rate_uv,
6783 tmp_sse);
6784 }
6785
6786 if (tmp_ref_rd > tmp_alt_rd) {
6787 rate2 = tmp_rate;
6788 distortion2 = tmp_dist;
6789 skippable = tmp_skip;
6790 rate_y = tmp_rate_y;
6791 rate_uv = tmp_rate_uv;
6792 total_sse = tmp_sse;
6793 this_rd = tmp_alt_rd;
Jingning Han4fb8b212016-01-19 16:36:25 -08006794 // Indicator of the effective nearmv reference motion vector.
Jingning Han28e03932016-01-20 17:40:47 -08006795 best_ref_mv_idx[ref_frame_type] = 1 + ref_idx;
Jingning Han4fb8b212016-01-19 16:36:25 -08006796 tmp_ref_rd = tmp_alt_rd;
6797 backup_mbmi = *mbmi;
6798 } else {
6799 *mbmi = backup_mbmi;
6800 }
Jingning Han67cf8902016-01-15 09:05:51 -08006801 }
6802
6803 frame_mv[NEARMV][ref_frame] = backup_mv;
Jingning Han67cf8902016-01-15 09:05:51 -08006804 }
6805#endif
6806
Jingning Han3ee6db62015-08-05 19:00:31 -07006807 if (this_rd == INT64_MAX)
6808 continue;
6809
6810 compmode_cost = vp10_cost_bit(comp_mode_p, comp_pred);
6811
6812 if (cm->reference_mode == REFERENCE_MODE_SELECT)
6813 rate2 += compmode_cost;
6814 }
6815
6816 // Estimate the reference frame signaling cost and add it
6817 // to the rolling cost variable.
6818 if (comp_pred) {
6819 rate2 += ref_costs_comp[ref_frame];
6820 } else {
6821 rate2 += ref_costs_single[ref_frame];
6822 }
6823
6824 if (!disable_skip) {
6825 if (skippable) {
6826 // Back out the coefficient coding costs
6827 rate2 -= (rate_y + rate_uv);
Debargha Mukherjee3787b172015-11-19 16:51:16 -08006828 rate_y = 0;
6829 rate_uv = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07006830 // Cost the skip mb case
6831 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07006832
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04006833 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Jingning Han3ee6db62015-08-05 19:00:31 -07006834 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
6835 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
6836 // Add in the cost of the no skip flag.
6837 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
6838 } else {
6839 // FIXME(rbultje) make this work for splitmv also
6840 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
6841 distortion2 = total_sse;
6842 assert(total_sse >= 0);
6843 rate2 -= (rate_y + rate_uv);
6844 this_skip2 = 1;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08006845 rate_y = 0;
6846 rate_uv = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07006847 }
6848 } else {
6849 // Add in the cost of the no skip flag.
6850 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
6851 }
6852
6853 // Calculate the final RD estimate for this mode.
6854 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
6855 }
6856
6857 // Apply an adjustment to the rd value based on the similarity of the
6858 // source variance and reconstructed variance.
6859 rd_variance_adjustment(cpi, x, bsize, &this_rd,
6860 ref_frame, x->source_variance);
6861
6862 if (ref_frame == INTRA_FRAME) {
6863 // Keep record of best intra rd
6864 if (this_rd < best_intra_rd) {
6865 best_intra_rd = this_rd;
6866 best_intra_mode = mbmi->mode;
6867 }
6868 }
6869
6870 if (!disable_skip && ref_frame == INTRA_FRAME) {
6871 for (i = 0; i < REFERENCE_MODES; ++i)
James Zern5e16d392015-08-17 18:19:22 -07006872 best_pred_rd[i] = VPXMIN(best_pred_rd[i], this_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07006873 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
James Zern5e16d392015-08-17 18:19:22 -07006874 best_filter_rd[i] = VPXMIN(best_filter_rd[i], this_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07006875 }
6876
6877 // Did this mode help.. i.e. is it the new best mode
6878 if (this_rd < best_rd || x->skip) {
6879 int max_plane = MAX_MB_PLANE;
6880 if (!mode_excluded) {
6881 // Note index of best mode so far
6882 best_mode_index = mode_index;
6883
6884 if (ref_frame == INTRA_FRAME) {
6885 /* required for left and above block mv */
6886 mbmi->mv[0].as_int = 0;
6887 max_plane = 1;
6888 } else {
6889 best_pred_sse = x->pred_sse[ref_frame];
6890 }
6891
6892 rd_cost->rate = rate2;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08006893#if CONFIG_SUPERTX
6894 *returnrate_nocoef = rate2 - rate_y - rate_uv;
6895 if (!disable_skip) {
6896 *returnrate_nocoef -= vp10_cost_bit(vp10_get_skip_prob(cm, xd),
6897 skippable || this_skip2);
6898 }
6899 *returnrate_nocoef -= vp10_cost_bit(vp10_get_intra_inter_prob(cm, xd),
6900 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chend1cad9c2016-01-27 14:18:53 -08006901#if CONFIG_OBMC
6902 if (is_inter_block(mbmi) && is_obmc_allowed(mbmi))
6903 *returnrate_nocoef -= cpi->obmc_cost[bsize][mbmi->obmc];
6904#endif // CONFIG_OBMC
Debargha Mukherjee3787b172015-11-19 16:51:16 -08006905#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07006906 rd_cost->dist = distortion2;
6907 rd_cost->rdcost = this_rd;
6908 best_rd = this_rd;
6909 best_mbmode = *mbmi;
6910 best_skip2 = this_skip2;
6911 best_mode_skippable = skippable;
6912
6913 if (!x->select_tx_size)
6914 swap_block_ptr(x, ctx, 1, 0, 0, max_plane);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07006915
6916#if CONFIG_VAR_TX
6917 for (i = 0; i < MAX_MB_PLANE; ++i)
6918 memcpy(ctx->blk_skip[i], x->blk_skip[i],
6919 sizeof(uint8_t) * ctx->num_4x4_blk);
6920#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006921 memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
hui su088b05f2015-08-12 10:41:51 -07006922 sizeof(ctx->zcoeff_blk[0]) * ctx->num_4x4_blk);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07006923#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07006924
6925 // TODO(debargha): enhance this test with a better distortion prediction
6926 // based on qp, activity mask and history
6927 if ((mode_search_skip_flags & FLAG_EARLY_TERMINATE) &&
6928 (mode_index > MIN_EARLY_TERM_INDEX)) {
6929 int qstep = xd->plane[0].dequant[1];
6930 // TODO(debargha): Enhance this by specializing for each mode_index
6931 int scale = 4;
6932#if CONFIG_VP9_HIGHBITDEPTH
6933 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6934 qstep >>= (xd->bd - 8);
6935 }
6936#endif // CONFIG_VP9_HIGHBITDEPTH
6937 if (x->source_variance < UINT_MAX) {
6938 const int var_adjust = (x->source_variance < 16);
6939 scale -= var_adjust;
6940 }
6941 if (ref_frame > INTRA_FRAME &&
6942 distortion2 * scale < qstep * qstep) {
6943 early_term = 1;
6944 }
6945 }
6946 }
6947 }
6948
6949 /* keep record of best compound/single-only prediction */
6950 if (!disable_skip && ref_frame != INTRA_FRAME) {
6951 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
6952
6953 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
6954 single_rate = rate2 - compmode_cost;
6955 hybrid_rate = rate2;
6956 } else {
6957 single_rate = rate2;
6958 hybrid_rate = rate2 + compmode_cost;
6959 }
6960
6961 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
6962 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
6963
6964 if (!comp_pred) {
6965 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
6966 best_pred_rd[SINGLE_REFERENCE] = single_rd;
6967 } else {
6968 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
6969 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
6970 }
6971 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
6972 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
6973
6974 /* keep record of best filter type */
6975 if (!mode_excluded && cm->interp_filter != BILINEAR) {
6976 int64_t ref = filter_cache[cm->interp_filter == SWITCHABLE ?
6977 SWITCHABLE_FILTERS : cm->interp_filter];
6978
6979 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
6980 int64_t adj_rd;
6981 if (ref == INT64_MAX)
6982 adj_rd = 0;
6983 else if (filter_cache[i] == INT64_MAX)
6984 // when early termination is triggered, the encoder does not have
6985 // access to the rate-distortion cost. it only knows that the cost
6986 // should be above the maximum valid value. hence it takes the known
6987 // maximum plus an arbitrary constant as the rate-distortion cost.
6988 adj_rd = mask_filter - ref + 10;
6989 else
6990 adj_rd = filter_cache[i] - ref;
6991
6992 adj_rd += this_rd;
James Zern5e16d392015-08-17 18:19:22 -07006993 best_filter_rd[i] = VPXMIN(best_filter_rd[i], adj_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07006994 }
6995 }
6996 }
6997
6998 if (early_term)
6999 break;
7000
7001 if (x->skip && !comp_pred)
7002 break;
7003 }
7004
7005 // The inter modes' rate costs are not calculated precisely in some cases.
7006 // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
7007 // ZEROMV. Here, checks are added for those cases, and the mode decisions
7008 // are corrected.
Yue Chen1ac85872016-01-07 15:13:52 -08007009 if (best_mbmode.mode == NEWMV
7010#if CONFIG_EXT_INTER
7011 || best_mbmode.mode == NEWFROMNEARMV
Yue Chen968bbc72016-01-19 16:45:45 -08007012 || best_mbmode.mode == NEW_NEWMV
Yue Chen1ac85872016-01-07 15:13:52 -08007013#endif // CONFIG_EXT_INTER
7014 ) {
Jingning Han3ee6db62015-08-05 19:00:31 -07007015 const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0],
7016 best_mbmode.ref_frame[1]};
7017 int comp_pred_mode = refs[1] > INTRA_FRAME;
Jingning Han33cc1bd2016-01-12 15:06:59 -08007018#if CONFIG_REF_MV
7019 if (!comp_pred_mode) {
Jingning Han4fb8b212016-01-19 16:36:25 -08007020 if (best_ref_mv_idx[best_mbmode.ref_frame[0]] > 0 &&
Jingning Han67cf8902016-01-15 09:05:51 -08007021 best_mbmode.ref_frame[1] == NONE) {
Jingning Han4fb8b212016-01-19 16:36:25 -08007022 int idx = best_ref_mv_idx[best_mbmode.ref_frame[0]] + 1;
Jingning Han67cf8902016-01-15 09:05:51 -08007023 int_mv cur_mv =
Jingning Han4fb8b212016-01-19 16:36:25 -08007024 mbmi_ext->ref_mv_stack[best_mbmode.ref_frame[0]][idx].this_mv;
Jingning Han67cf8902016-01-15 09:05:51 -08007025 lower_mv_precision(&cur_mv.as_mv, cm->allow_high_precision_mv);
7026 frame_mv[NEARMV][refs[0]] = cur_mv;
7027 }
7028
Jingning Han33cc1bd2016-01-12 15:06:59 -08007029 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
7030 best_mbmode.mode = NEARESTMV;
7031 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
7032 best_mbmode.mode = NEARMV;
7033 else if (best_mbmode.mv[0].as_int == 0)
7034 best_mbmode.mode = ZEROMV;
7035 } else {
7036 uint8_t rf_type = vp10_ref_frame_type(best_mbmode.ref_frame);
Jingning Han3944cfb2016-01-13 09:03:15 -08007037 int i;
7038 const int allow_hp = cm->allow_high_precision_mv;
7039 int_mv nearestmv[2] = { frame_mv[NEARESTMV][refs[0]],
7040 frame_mv[NEARESTMV][refs[1]] };
Jingning Han3ee6db62015-08-05 19:00:31 -07007041
Jingning Han3944cfb2016-01-13 09:03:15 -08007042 int_mv nearmv[2] = { frame_mv[NEARMV][refs[0]],
7043 frame_mv[NEARMV][refs[1]] };
7044
7045 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
Jingning Han33cc1bd2016-01-12 15:06:59 -08007046 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
7047 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
Jingning Han3944cfb2016-01-13 09:03:15 -08007048 }
7049
7050 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
Jingning Han28e03932016-01-20 17:40:47 -08007051 int ref_mv_idx = best_ref_mv_idx[rf_type] + 1;
7052 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][ref_mv_idx].this_mv;
7053 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][ref_mv_idx].comp_mv;
Jingning Han33cc1bd2016-01-12 15:06:59 -08007054 }
Jingning Han3944cfb2016-01-13 09:03:15 -08007055
7056 for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
7057 lower_mv_precision(&nearestmv[i].as_mv, allow_hp);
7058 lower_mv_precision(&nearmv[i].as_mv, allow_hp);
7059 }
7060
7061 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
7062 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
Yue Chen968bbc72016-01-19 16:45:45 -08007063#if CONFIG_EXT_INTER
7064 best_mbmode.mode = NEAREST_NEARESTMV;
7065 else if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
7066 nearmv[1].as_int == best_mbmode.mv[1].as_int)
7067 best_mbmode.mode = NEAREST_NEARMV;
7068 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
7069 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
7070 best_mbmode.mode = NEAR_NEARESTMV;
7071 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
7072 best_mbmode.mode = ZERO_ZEROMV;
7073#else
Jingning Han3944cfb2016-01-13 09:03:15 -08007074 best_mbmode.mode = NEARESTMV;
7075 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
7076 nearmv[1].as_int == best_mbmode.mv[1].as_int)
7077 best_mbmode.mode = NEARMV;
7078 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
7079 best_mbmode.mode = ZEROMV;
Yue Chen968bbc72016-01-19 16:45:45 -08007080#endif // CONFIG_EXT_INTER
Jingning Han33cc1bd2016-01-12 15:06:59 -08007081 }
7082#else
Yue Chen968bbc72016-01-19 16:45:45 -08007083#if CONFIG_EXT_INTER
7084 if (!comp_pred_mode) {
7085#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007086 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
7087 ((comp_pred_mode && frame_mv[NEARESTMV][refs[1]].as_int ==
7088 best_mbmode.mv[1].as_int) || !comp_pred_mode))
7089 best_mbmode.mode = NEARESTMV;
7090 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
7091 ((comp_pred_mode && frame_mv[NEARMV][refs[1]].as_int ==
7092 best_mbmode.mv[1].as_int) || !comp_pred_mode))
7093 best_mbmode.mode = NEARMV;
7094 else if (best_mbmode.mv[0].as_int == 0 &&
7095 ((comp_pred_mode && best_mbmode.mv[1].as_int == 0) || !comp_pred_mode))
7096 best_mbmode.mode = ZEROMV;
Yue Chen968bbc72016-01-19 16:45:45 -08007097#if CONFIG_EXT_INTER
7098 } else {
7099 const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0],
7100 best_mbmode.ref_frame[1]};
7101
7102 if (frame_mv[NEAREST_NEARESTMV][refs[0]].as_int ==
7103 best_mbmode.mv[0].as_int &&
7104 frame_mv[NEAREST_NEARESTMV][refs[1]].as_int ==
7105 best_mbmode.mv[1].as_int)
7106 best_mbmode.mode = NEAREST_NEARESTMV;
7107 else if (frame_mv[NEAREST_NEARMV][refs[0]].as_int ==
7108 best_mbmode.mv[0].as_int &&
7109 frame_mv[NEAREST_NEARMV][refs[1]].as_int ==
7110 best_mbmode.mv[1].as_int)
7111 best_mbmode.mode = NEAREST_NEARMV;
7112 else if (frame_mv[NEAR_NEARESTMV][refs[0]].as_int ==
7113 best_mbmode.mv[0].as_int &&
7114 frame_mv[NEAR_NEARESTMV][refs[1]].as_int ==
7115 best_mbmode.mv[1].as_int)
7116 best_mbmode.mode = NEAR_NEARESTMV;
7117 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
7118 best_mbmode.mode = ZERO_ZEROMV;
7119 }
7120#endif // CONFIG_EXT_INTER
Jingning Han33cc1bd2016-01-12 15:06:59 -08007121#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07007122 }
7123
Jingning Hanaa5d53e2015-12-07 15:54:59 -08007124#if CONFIG_REF_MV
7125 if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
7126 best_mbmode.mv[0].as_int == 0 &&
Yue Chen968bbc72016-01-19 16:45:45 -08007127#if CONFIG_EXT_INTER
7128 best_mbmode.ref_frame[1] == NONE) {
7129#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08007130 (best_mbmode.ref_frame[1] == NONE || best_mbmode.mv[1].as_int == 0)) {
Yue Chen968bbc72016-01-19 16:45:45 -08007131#endif // CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08007132 int16_t mode_ctx = mbmi_ext->mode_context[best_mbmode.ref_frame[0]];
Yue Chen968bbc72016-01-19 16:45:45 -08007133#if !CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08007134 if (best_mbmode.ref_frame[1] > NONE)
7135 mode_ctx &= (mbmi_ext->mode_context[best_mbmode.ref_frame[1]] | 0x00ff);
Yue Chen968bbc72016-01-19 16:45:45 -08007136#endif // !CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08007137
7138 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET))
7139 best_mbmode.mode = ZEROMV;
7140 }
Jingning Han67cf8902016-01-15 09:05:51 -08007141
Jingning Han28e03932016-01-20 17:40:47 -08007142 if (best_mbmode.mode == NEARMV) {
7143 uint8_t ref_frame_type = vp10_ref_frame_type(best_mbmode.ref_frame);
7144 best_mbmode.ref_mv_idx = best_ref_mv_idx[ref_frame_type];
7145 }
Jingning Hanaa5d53e2015-12-07 15:54:59 -08007146#endif
7147
Jingning Han3ee6db62015-08-05 19:00:31 -07007148 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
7149 rd_cost->rate = INT_MAX;
7150 rd_cost->rdcost = INT64_MAX;
7151 return;
7152 }
7153
7154 // If we used an estimate for the uv intra rd in the loop above...
7155 if (sf->use_uv_intra_rd_estimate) {
7156 // Do Intra UV best rd mode selection if best mode choice above was intra.
7157 if (best_mbmode.ref_frame[0] == INTRA_FRAME) {
7158 TX_SIZE uv_tx_size;
7159 *mbmi = best_mbmode;
7160 uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
7161 rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra[uv_tx_size],
7162 &rate_uv_tokenonly[uv_tx_size],
7163 &dist_uv[uv_tx_size],
7164 &skip_uv[uv_tx_size],
7165 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize,
7166 uv_tx_size);
7167 }
7168 }
7169
7170 assert((cm->interp_filter == SWITCHABLE) ||
7171 (cm->interp_filter == best_mbmode.interp_filter) ||
7172 !is_inter_block(&best_mbmode));
7173
7174 if (!cpi->rc.is_src_frame_alt_ref)
7175 vp10_update_rd_thresh_fact(tile_data->thresh_freq_fact,
7176 sf->adaptive_rd_thresh, bsize, best_mode_index);
7177
7178 // macroblock modes
7179 *mbmi = best_mbmode;
7180 x->skip |= best_skip2;
7181
7182 for (i = 0; i < REFERENCE_MODES; ++i) {
7183 if (best_pred_rd[i] == INT64_MAX)
7184 best_pred_diff[i] = INT_MIN;
7185 else
7186 best_pred_diff[i] = best_rd - best_pred_rd[i];
7187 }
7188
7189 if (!x->skip) {
7190 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
7191 if (best_filter_rd[i] == INT64_MAX)
7192 best_filter_diff[i] = 0;
7193 else
7194 best_filter_diff[i] = best_rd - best_filter_rd[i];
7195 }
7196 if (cm->interp_filter == SWITCHABLE)
7197 assert(best_filter_diff[SWITCHABLE_FILTERS] == 0);
7198 } else {
7199 vp10_zero(best_filter_diff);
7200 }
7201
7202 // TODO(yunqingwang): Moving this line in front of the above best_filter_diff
7203 // updating code causes PSNR loss. Need to figure out the confliction.
7204 x->skip |= best_mode_skippable;
7205
7206 if (!x->skip && !x->select_tx_size) {
7207 int has_high_freq_coeff = 0;
7208 int plane;
7209 int max_plane = is_inter_block(&xd->mi[0]->mbmi)
7210 ? MAX_MB_PLANE : 1;
7211 for (plane = 0; plane < max_plane; ++plane) {
7212 x->plane[plane].eobs = ctx->eobs_pbuf[plane][1];
7213 has_high_freq_coeff |= vp10_has_high_freq_in_plane(x, bsize, plane);
7214 }
7215
7216 for (plane = max_plane; plane < MAX_MB_PLANE; ++plane) {
7217 x->plane[plane].eobs = ctx->eobs_pbuf[plane][2];
7218 has_high_freq_coeff |= vp10_has_high_freq_in_plane(x, bsize, plane);
7219 }
7220
7221 best_mode_skippable |= !has_high_freq_coeff;
7222 }
7223
7224 assert(best_mode_index >= 0);
7225
7226 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
7227 best_filter_diff, best_mode_skippable);
7228}
7229
Yaowu Xu26a9afc2015-08-13 09:42:27 -07007230void vp10_rd_pick_inter_mode_sb_seg_skip(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07007231 TileDataEnc *tile_data,
7232 MACROBLOCK *x,
7233 RD_COST *rd_cost,
7234 BLOCK_SIZE bsize,
7235 PICK_MODE_CONTEXT *ctx,
7236 int64_t best_rd_so_far) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07007237 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07007238 MACROBLOCKD *const xd = &x->e_mbd;
7239 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7240 unsigned char segment_id = mbmi->segment_id;
7241 const int comp_pred = 0;
7242 int i;
7243 int64_t best_pred_diff[REFERENCE_MODES];
7244 int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
7245 unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
7246 vpx_prob comp_mode_p;
7247 INTERP_FILTER best_filter = SWITCHABLE;
7248 int64_t this_rd = INT64_MAX;
7249 int rate2 = 0;
7250 const int64_t distortion2 = 0;
7251
Jingning Han3ee6db62015-08-05 19:00:31 -07007252 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
7253 &comp_mode_p);
7254
7255 for (i = 0; i < MAX_REF_FRAMES; ++i)
7256 x->pred_sse[i] = INT_MAX;
7257 for (i = LAST_FRAME; i < MAX_REF_FRAMES; ++i)
7258 x->pred_mv_sad[i] = INT_MAX;
7259
7260 rd_cost->rate = INT_MAX;
7261
7262 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
7263
hui suc93e5cc2015-12-07 18:18:57 -08007264 mbmi->palette_mode_info.palette_size[0] = 0;
7265 mbmi->palette_mode_info.palette_size[1] = 0;
hui sube3559b2015-10-07 09:29:02 -07007266#if CONFIG_EXT_INTRA
7267 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
7268 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
7269#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07007270 mbmi->mode = ZEROMV;
7271 mbmi->uv_mode = DC_PRED;
7272 mbmi->ref_frame[0] = LAST_FRAME;
7273 mbmi->ref_frame[1] = NONE;
7274 mbmi->mv[0].as_int = 0;
7275 x->skip = 1;
7276
7277 if (cm->interp_filter != BILINEAR) {
7278 best_filter = EIGHTTAP;
7279 if (cm->interp_filter == SWITCHABLE &&
Debargha Mukherjee85514c42015-10-30 09:19:36 -07007280#if CONFIG_EXT_INTERP
7281 vp10_is_interp_needed(xd) &&
7282#endif // CONFIG_EXT_INTERP
Jingning Han3ee6db62015-08-05 19:00:31 -07007283 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
7284 int rs;
7285 int best_rs = INT_MAX;
7286 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
7287 mbmi->interp_filter = i;
7288 rs = vp10_get_switchable_rate(cpi, xd);
7289 if (rs < best_rs) {
7290 best_rs = rs;
7291 best_filter = mbmi->interp_filter;
7292 }
7293 }
7294 }
7295 }
7296 // Set the appropriate filter
7297 if (cm->interp_filter == SWITCHABLE) {
7298 mbmi->interp_filter = best_filter;
7299 rate2 += vp10_get_switchable_rate(cpi, xd);
7300 } else {
7301 mbmi->interp_filter = cm->interp_filter;
7302 }
7303
7304 if (cm->reference_mode == REFERENCE_MODE_SELECT)
7305 rate2 += vp10_cost_bit(comp_mode_p, comp_pred);
7306
7307 // Estimate the reference frame signaling cost and add it
7308 // to the rolling cost variable.
7309 rate2 += ref_costs_single[LAST_FRAME];
7310 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
7311
7312 rd_cost->rate = rate2;
7313 rd_cost->dist = distortion2;
7314 rd_cost->rdcost = this_rd;
7315
7316 if (this_rd >= best_rd_so_far) {
7317 rd_cost->rate = INT_MAX;
7318 rd_cost->rdcost = INT64_MAX;
7319 return;
7320 }
7321
7322 assert((cm->interp_filter == SWITCHABLE) ||
7323 (cm->interp_filter == mbmi->interp_filter));
7324
7325 vp10_update_rd_thresh_fact(tile_data->thresh_freq_fact,
7326 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
7327
7328 vp10_zero(best_pred_diff);
7329 vp10_zero(best_filter_diff);
7330
7331 if (!x->select_tx_size)
7332 swap_block_ptr(x, ctx, 1, 0, 0, MAX_MB_PLANE);
7333 store_coding_context(x, ctx, THR_ZEROMV,
7334 best_pred_diff, best_filter_diff, 0);
7335}
7336
Debargha Mukherjee3787b172015-11-19 16:51:16 -08007337void vp10_rd_pick_inter_mode_sub8x8(struct VP10_COMP *cpi,
7338 TileDataEnc *tile_data,
7339 struct macroblock *x,
7340 int mi_row, int mi_col,
7341 struct RD_COST *rd_cost,
7342#if CONFIG_SUPERTX
7343 int *returnrate_nocoef,
7344#endif // CONFIG_SUPERTX
7345 BLOCK_SIZE bsize,
7346 PICK_MODE_CONTEXT *ctx,
7347 int64_t best_rd_so_far) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07007348 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07007349 RD_OPT *const rd_opt = &cpi->rd;
7350 SPEED_FEATURES *const sf = &cpi->sf;
7351 MACROBLOCKD *const xd = &x->e_mbd;
7352 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7353 const struct segmentation *const seg = &cm->seg;
7354 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
7355 unsigned char segment_id = mbmi->segment_id;
7356 int comp_pred, i;
7357 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
Zoe Liu3ec16012015-11-12 02:12:17 -08007358 struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE];
7359 static const int flag_list[REFS_PER_FRAME + 1] = {
7360 0,
7361 VP9_LAST_FLAG,
7362#if CONFIG_EXT_REFS
7363 VP9_LAST2_FLAG,
7364 VP9_LAST3_FLAG,
7365 VP9_LAST4_FLAG,
7366#endif // CONFIG_EXT_REFS
7367 VP9_GOLD_FLAG,
7368 VP9_ALT_FLAG
7369 };
Jingning Han3ee6db62015-08-05 19:00:31 -07007370 int64_t best_rd = best_rd_so_far;
7371 int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
7372 int64_t best_pred_diff[REFERENCE_MODES];
7373 int64_t best_pred_rd[REFERENCE_MODES];
7374 int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
7375 int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
7376 MB_MODE_INFO best_mbmode;
7377 int ref_index, best_ref_index = 0;
7378 unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
7379 vpx_prob comp_mode_p;
7380 INTERP_FILTER tmp_best_filter = SWITCHABLE;
7381 int rate_uv_intra, rate_uv_tokenonly;
7382 int64_t dist_uv;
7383 int skip_uv;
7384 PREDICTION_MODE mode_uv = DC_PRED;
7385 const int intra_cost_penalty = vp10_get_intra_cost_penalty(
7386 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
Yue Chen1ac85872016-01-07 15:13:52 -08007387#if CONFIG_EXT_INTER
7388 int_mv seg_mvs[4][2][MAX_REF_FRAMES];
7389#else
Jingning Han3ee6db62015-08-05 19:00:31 -07007390 int_mv seg_mvs[4][MAX_REF_FRAMES];
Yue Chen1ac85872016-01-07 15:13:52 -08007391#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007392 b_mode_info best_bmodes[4];
7393 int best_skip2 = 0;
7394 int ref_frame_skip_mask[2] = { 0 };
7395 int64_t mask_filter = 0;
7396 int64_t filter_cache[SWITCHABLE_FILTER_CONTEXTS];
7397 int internal_active_edge =
7398 vp10_active_edge_sb(cpi, mi_row, mi_col) && vp10_internal_image_edge(cpi);
7399
Debargha Mukherjee3787b172015-11-19 16:51:16 -08007400#if CONFIG_SUPERTX
7401 best_rd_so_far = INT64_MAX;
7402 best_rd = best_rd_so_far;
7403 best_yrd = best_rd_so_far;
7404#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07007405 memset(x->zcoeff_blk[TX_4X4], 0, 4);
7406 vp10_zero(best_mbmode);
7407
hui sube3559b2015-10-07 09:29:02 -07007408#if CONFIG_EXT_INTRA
7409 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
7410 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
7411#endif // CONFIG_EXT_INTRA
Yue Chend1cad9c2016-01-27 14:18:53 -08007412#if CONFIG_OBMC
7413 mbmi->obmc = 0;
7414#endif // CONFIG_OBMC
hui sube3559b2015-10-07 09:29:02 -07007415
Jingning Han3ee6db62015-08-05 19:00:31 -07007416 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
7417 filter_cache[i] = INT64_MAX;
7418
7419 for (i = 0; i < 4; i++) {
7420 int j;
Yue Chen1ac85872016-01-07 15:13:52 -08007421#if CONFIG_EXT_INTER
7422 int k;
7423
7424 for (k = 0; k < 2; k++)
7425 for (j = 0; j < MAX_REF_FRAMES; j++)
7426 seg_mvs[i][k][j].as_int = INVALID_MV;
7427#else
Jingning Han3ee6db62015-08-05 19:00:31 -07007428 for (j = 0; j < MAX_REF_FRAMES; j++)
7429 seg_mvs[i][j].as_int = INVALID_MV;
Yue Chen1ac85872016-01-07 15:13:52 -08007430#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007431 }
7432
7433 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
7434 &comp_mode_p);
7435
7436 for (i = 0; i < REFERENCE_MODES; ++i)
7437 best_pred_rd[i] = INT64_MAX;
7438 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
7439 best_filter_rd[i] = INT64_MAX;
7440 rate_uv_intra = INT_MAX;
7441
7442 rd_cost->rate = INT_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08007443#if CONFIG_SUPERTX
7444 *returnrate_nocoef = INT_MAX;
7445#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07007446
7447 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
Jingning Han387a10e2015-12-09 09:07:39 -08007448 x->mbmi_ext->mode_context[ref_frame] = 0;
Yue Chen968bbc72016-01-19 16:45:45 -08007449#if CONFIG_REF_MV && CONFIG_EXT_INTER
7450 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
7451#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007452 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
7453 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
7454 frame_mv[NEARESTMV], frame_mv[NEARMV],
7455 yv12_mb);
7456 } else {
7457 ref_frame_skip_mask[0] |= (1 << ref_frame);
7458 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7459 }
7460 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Yue Chen1ac85872016-01-07 15:13:52 -08007461#if CONFIG_EXT_INTER
7462 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
7463#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007464 frame_mv[ZEROMV][ref_frame].as_int = 0;
7465 }
7466
hui suc93e5cc2015-12-07 18:18:57 -08007467 mbmi->palette_mode_info.palette_size[0] = 0;
7468 mbmi->palette_mode_info.palette_size[1] = 0;
7469
Jingning Han3ee6db62015-08-05 19:00:31 -07007470 for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
7471 int mode_excluded = 0;
7472 int64_t this_rd = INT64_MAX;
7473 int disable_skip = 0;
7474 int compmode_cost = 0;
7475 int rate2 = 0, rate_y = 0, rate_uv = 0;
7476 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
7477 int skippable = 0;
7478 int i;
7479 int this_skip2 = 0;
7480 int64_t total_sse = INT_MAX;
7481 int early_term = 0;
7482
7483 ref_frame = vp10_ref_order[ref_index].ref_frame[0];
7484 second_ref_frame = vp10_ref_order[ref_index].ref_frame[1];
7485
7486 // Look at the reference frame of the best mode so far and set the
7487 // skip mask to look at a subset of the remaining modes.
7488 if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
7489 if (ref_index == 3) {
7490 switch (best_mbmode.ref_frame[0]) {
7491 case INTRA_FRAME:
7492 break;
7493 case LAST_FRAME:
Zoe Liu3ec16012015-11-12 02:12:17 -08007494 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
7495#if CONFIG_EXT_REFS
7496 (1 << LAST2_FRAME) |
7497 (1 << LAST3_FRAME) |
7498 (1 << LAST4_FRAME) |
7499#endif // CONFIG_EXT_REFS
7500 (1 << ALTREF_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07007501 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7502 break;
Zoe Liu3ec16012015-11-12 02:12:17 -08007503#if CONFIG_EXT_REFS
7504 case LAST2_FRAME:
7505 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
7506 (1 << LAST3_FRAME) |
7507 (1 << LAST4_FRAME) |
7508 (1 << GOLDEN_FRAME) |
7509 (1 << ALTREF_FRAME);
7510 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7511 break;
7512 case LAST3_FRAME:
7513 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
7514 (1 << LAST2_FRAME) |
7515 (1 << LAST4_FRAME) |
7516 (1 << GOLDEN_FRAME) |
7517 (1 << ALTREF_FRAME);
7518 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7519 break;
7520 case LAST4_FRAME:
7521 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
7522 (1 << LAST2_FRAME) |
7523 (1 << LAST3_FRAME) |
7524 (1 << GOLDEN_FRAME) |
7525 (1 << ALTREF_FRAME);
7526 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7527 break;
7528#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07007529 case GOLDEN_FRAME:
Zoe Liu3ec16012015-11-12 02:12:17 -08007530 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
7531#if CONFIG_EXT_REFS
7532 (1 << LAST2_FRAME) |
7533 (1 << LAST3_FRAME) |
7534 (1 << LAST4_FRAME) |
7535#endif // CONFIG_EXT_REFS
7536 (1 << ALTREF_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07007537 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7538 break;
7539 case ALTREF_FRAME:
Zoe Liu3ec16012015-11-12 02:12:17 -08007540 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
7541#if CONFIG_EXT_REFS
7542 (1 << LAST2_FRAME) |
7543 (1 << LAST3_FRAME) |
7544 (1 << LAST4_FRAME) |
7545#endif // CONFIG_EXT_REFS
7546 (1 << LAST_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07007547 break;
7548 case NONE:
7549 case MAX_REF_FRAMES:
7550 assert(0 && "Invalid Reference frame");
7551 break;
7552 }
7553 }
7554 }
7555
7556 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
James Zern5e16d392015-08-17 18:19:22 -07007557 (ref_frame_skip_mask[1] & (1 << VPXMAX(0, second_ref_frame))))
Jingning Han3ee6db62015-08-05 19:00:31 -07007558 continue;
7559
7560 // Test best rd so far against threshold for trying this mode.
7561 if (!internal_active_edge &&
7562 rd_less_than_thresh(best_rd,
7563 rd_opt->threshes[segment_id][bsize][ref_index],
7564 tile_data->thresh_freq_fact[bsize][ref_index]))
7565 continue;
7566
7567 comp_pred = second_ref_frame > INTRA_FRAME;
7568 if (comp_pred) {
7569 if (!cpi->allow_comp_inter_inter)
7570 continue;
7571 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
7572 continue;
7573 // Do not allow compound prediction if the segment level reference frame
7574 // feature is in use as in this case there can only be one reference.
7575 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
7576 continue;
7577
7578 if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
7579 best_mbmode.ref_frame[0] == INTRA_FRAME)
7580 continue;
7581 }
7582
7583 // TODO(jingning, jkoleszar): scaling reference frame not supported for
7584 // sub8x8 blocks.
7585 if (ref_frame > INTRA_FRAME &&
7586 vp10_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
7587 continue;
7588
7589 if (second_ref_frame > INTRA_FRAME &&
7590 vp10_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
7591 continue;
7592
7593 if (comp_pred)
7594 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
7595 else if (ref_frame != INTRA_FRAME)
7596 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
7597
7598 // If the segment reference frame feature is enabled....
7599 // then do nothing if the current ref frame is not allowed..
7600 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
7601 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
7602 continue;
7603 // Disable this drop out case if the ref frame
7604 // segment level feature is enabled for this segment. This is to
7605 // prevent the possibility that we end up unable to pick any mode.
7606 } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
7607 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
7608 // unless ARNR filtering is enabled in which case we want
7609 // an unfiltered alternative. We allow near/nearest as well
7610 // because they may result in zero-zero MVs but be cheaper.
7611 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
7612 continue;
7613 }
7614
7615 mbmi->tx_size = TX_4X4;
7616 mbmi->uv_mode = DC_PRED;
7617 mbmi->ref_frame[0] = ref_frame;
7618 mbmi->ref_frame[1] = second_ref_frame;
7619 // Evaluate all sub-pel filters irrespective of whether we can use
7620 // them for this frame.
7621 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP
7622 : cm->interp_filter;
7623 x->skip = 0;
7624 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
7625
7626 // Select prediction reference frames.
7627 for (i = 0; i < MAX_MB_PLANE; i++) {
7628 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
7629 if (comp_pred)
7630 xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
7631 }
7632
Jingning Han704985e2015-10-08 12:05:03 -07007633#if CONFIG_VAR_TX
Jingning Han0f34e352015-11-15 20:52:51 -08007634 mbmi->inter_tx_size[0] = mbmi->tx_size;
Jingning Han704985e2015-10-08 12:05:03 -07007635#endif
7636
Jingning Han3ee6db62015-08-05 19:00:31 -07007637 if (ref_frame == INTRA_FRAME) {
7638 int rate;
7639 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y,
7640 &distortion_y, best_rd) >= best_rd)
7641 continue;
7642 rate2 += rate;
7643 rate2 += intra_cost_penalty;
7644 distortion2 += distortion_y;
7645
7646 if (rate_uv_intra == INT_MAX) {
7647 choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4,
7648 &rate_uv_intra,
7649 &rate_uv_tokenonly,
7650 &dist_uv, &skip_uv,
7651 &mode_uv);
7652 }
7653 rate2 += rate_uv_intra;
7654 rate_uv = rate_uv_tokenonly;
7655 distortion2 += dist_uv;
7656 distortion_uv = dist_uv;
7657 mbmi->uv_mode = mode_uv;
7658 } else {
7659 int rate;
7660 int64_t distortion;
7661 int64_t this_rd_thresh;
7662 int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
7663 int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
7664 int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
7665 int tmp_best_skippable = 0;
7666 int switchable_filter_index;
7667 int_mv *second_ref = comp_pred ?
7668 &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL;
7669 b_mode_info tmp_best_bmodes[16];
7670 MB_MODE_INFO tmp_best_mbmode;
7671 BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
7672 int pred_exists = 0;
7673 int uv_skippable;
Yue Chen1ac85872016-01-07 15:13:52 -08007674#if CONFIG_EXT_INTER
7675 int_mv compound_seg_newmvs[4][2];
7676 int i;
7677
7678 for (i = 0; i < 4; i++) {
7679 compound_seg_newmvs[i][0].as_int = INVALID_MV;
7680 compound_seg_newmvs[i][1].as_int = INVALID_MV;
7681 }
7682#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007683
7684 this_rd_thresh = (ref_frame == LAST_FRAME) ?
7685 rd_opt->threshes[segment_id][bsize][THR_LAST] :
7686 rd_opt->threshes[segment_id][bsize][THR_ALTR];
Zoe Liu3ec16012015-11-12 02:12:17 -08007687#if CONFIG_EXT_REFS
7688 this_rd_thresh = (ref_frame == LAST2_FRAME) ?
7689 rd_opt->threshes[segment_id][bsize][THR_LAST2] : this_rd_thresh;
7690 this_rd_thresh = (ref_frame == LAST3_FRAME) ?
7691 rd_opt->threshes[segment_id][bsize][THR_LAST3] : this_rd_thresh;
7692 this_rd_thresh = (ref_frame == LAST4_FRAME) ?
7693 rd_opt->threshes[segment_id][bsize][THR_LAST4] : this_rd_thresh;
7694#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07007695 this_rd_thresh = (ref_frame == GOLDEN_FRAME) ?
Zoe Liu3ec16012015-11-12 02:12:17 -08007696 rd_opt->threshes[segment_id][bsize][THR_GOLD] : this_rd_thresh;
Jingning Han3ee6db62015-08-05 19:00:31 -07007697 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
7698 filter_cache[i] = INT64_MAX;
7699
Debargha Mukherjeed46c1f22016-02-08 15:59:17 -08007700 // TODO(any): Add search of the tx_type to improve rd performance at the
7701 // expense of speed.
7702 mbmi->tx_type = DCT_DCT;
7703
Jingning Han3ee6db62015-08-05 19:00:31 -07007704 if (cm->interp_filter != BILINEAR) {
7705 tmp_best_filter = EIGHTTAP;
7706 if (x->source_variance < sf->disable_filter_search_var_thresh) {
7707 tmp_best_filter = EIGHTTAP;
7708 } else if (sf->adaptive_pred_interp_filter == 1 &&
7709 ctx->pred_interp_filter < SWITCHABLE) {
7710 tmp_best_filter = ctx->pred_interp_filter;
7711 } else if (sf->adaptive_pred_interp_filter == 2) {
7712 tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE ?
7713 ctx->pred_interp_filter : 0;
7714 } else {
7715 for (switchable_filter_index = 0;
7716 switchable_filter_index < SWITCHABLE_FILTERS;
7717 ++switchable_filter_index) {
7718 int newbest, rs;
7719 int64_t rs_rd;
7720 MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
7721 mbmi->interp_filter = switchable_filter_index;
7722 tmp_rd = rd_pick_best_sub8x8_mode(cpi, x,
7723 &mbmi_ext->ref_mvs[ref_frame][0],
7724 second_ref, best_yrd, &rate,
7725 &rate_y, &distortion,
7726 &skippable, &total_sse,
7727 (int) this_rd_thresh, seg_mvs,
Yue Chen1ac85872016-01-07 15:13:52 -08007728#if CONFIG_EXT_INTER
7729 compound_seg_newmvs,
7730#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007731 bsi, switchable_filter_index,
7732 mi_row, mi_col);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07007733#if CONFIG_EXT_INTERP
7734 if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
7735 mbmi->interp_filter != EIGHTTAP) // invalid configuration
7736 continue;
7737#endif // CONFIG_EXT_INTERP
Jingning Han3ee6db62015-08-05 19:00:31 -07007738 if (tmp_rd == INT64_MAX)
7739 continue;
7740 rs = vp10_get_switchable_rate(cpi, xd);
7741 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
7742 filter_cache[switchable_filter_index] = tmp_rd;
7743 filter_cache[SWITCHABLE_FILTERS] =
James Zern5e16d392015-08-17 18:19:22 -07007744 VPXMIN(filter_cache[SWITCHABLE_FILTERS], tmp_rd + rs_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07007745 if (cm->interp_filter == SWITCHABLE)
7746 tmp_rd += rs_rd;
7747
James Zern5e16d392015-08-17 18:19:22 -07007748 mask_filter = VPXMAX(mask_filter, tmp_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07007749
7750 newbest = (tmp_rd < tmp_best_rd);
7751 if (newbest) {
7752 tmp_best_filter = mbmi->interp_filter;
7753 tmp_best_rd = tmp_rd;
7754 }
7755 if ((newbest && cm->interp_filter == SWITCHABLE) ||
7756 (mbmi->interp_filter == cm->interp_filter &&
7757 cm->interp_filter != SWITCHABLE)) {
7758 tmp_best_rdu = tmp_rd;
7759 tmp_best_rate = rate;
7760 tmp_best_ratey = rate_y;
7761 tmp_best_distortion = distortion;
7762 tmp_best_sse = total_sse;
7763 tmp_best_skippable = skippable;
7764 tmp_best_mbmode = *mbmi;
7765 for (i = 0; i < 4; i++) {
7766 tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
7767 x->zcoeff_blk[TX_4X4][i] = !x->plane[0].eobs[i];
7768 }
7769 pred_exists = 1;
7770 if (switchable_filter_index == 0 &&
7771 sf->use_rd_breakout &&
7772 best_rd < INT64_MAX) {
7773 if (tmp_best_rdu / 2 > best_rd) {
7774 // skip searching the other filters if the first is
7775 // already substantially larger than the best so far
7776 tmp_best_filter = mbmi->interp_filter;
7777 tmp_best_rdu = INT64_MAX;
7778 break;
7779 }
7780 }
7781 }
7782 } // switchable_filter_index loop
7783 }
7784 }
7785
7786 if (tmp_best_rdu == INT64_MAX && pred_exists)
7787 continue;
7788
7789 mbmi->interp_filter = (cm->interp_filter == SWITCHABLE ?
7790 tmp_best_filter : cm->interp_filter);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07007791
Jingning Han3ee6db62015-08-05 19:00:31 -07007792 if (!pred_exists) {
7793 // Handles the special case when a filter that is not in the
Debargha Mukherjee85514c42015-10-30 09:19:36 -07007794 // switchable list (bilinear) is indicated at the frame level
Jingning Han3ee6db62015-08-05 19:00:31 -07007795 tmp_rd = rd_pick_best_sub8x8_mode(cpi, x,
7796 &x->mbmi_ext->ref_mvs[ref_frame][0],
7797 second_ref, best_yrd, &rate, &rate_y,
7798 &distortion, &skippable, &total_sse,
Yue Chen1ac85872016-01-07 15:13:52 -08007799 (int) this_rd_thresh, seg_mvs,
7800#if CONFIG_EXT_INTER
7801 compound_seg_newmvs,
7802#endif // CONFIG_EXT_INTER
7803 bsi, 0,
Jingning Han3ee6db62015-08-05 19:00:31 -07007804 mi_row, mi_col);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07007805#if CONFIG_EXT_INTERP
7806 if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
7807 mbmi->interp_filter != EIGHTTAP) {
7808 mbmi->interp_filter = EIGHTTAP;
Yue Chen1ac85872016-01-07 15:13:52 -08007809 tmp_rd = rd_pick_best_sub8x8_mode(cpi, x,
7810 &x->mbmi_ext->ref_mvs[ref_frame][0],
7811 second_ref, best_yrd, &rate, &rate_y,
7812 &distortion, &skippable, &total_sse,
7813 (int) this_rd_thresh, seg_mvs,
7814#if CONFIG_EXT_INTER
7815 compound_seg_newmvs,
7816#endif // CONFIG_EXT_INTER
7817 bsi, 0,
7818 mi_row, mi_col);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07007819 }
7820#endif // CONFIG_EXT_INTERP
Jingning Han3ee6db62015-08-05 19:00:31 -07007821 if (tmp_rd == INT64_MAX)
7822 continue;
7823 } else {
7824 total_sse = tmp_best_sse;
7825 rate = tmp_best_rate;
7826 rate_y = tmp_best_ratey;
7827 distortion = tmp_best_distortion;
7828 skippable = tmp_best_skippable;
7829 *mbmi = tmp_best_mbmode;
7830 for (i = 0; i < 4; i++)
7831 xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
7832 }
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08007833 // Add in the cost of the transform type
7834 if (!xd->lossless[mbmi->segment_id]) {
7835 int rate_tx_type = 0;
7836#if CONFIG_EXT_TX
7837 if (get_ext_tx_types(mbmi->tx_size, bsize, 1) > 1) {
7838 const int eset = get_ext_tx_set(mbmi->tx_size, bsize, 1);
7839 rate_tx_type =
7840 cpi->inter_tx_type_costs[eset][mbmi->tx_size][mbmi->tx_type];
7841 }
7842#else
7843 if (mbmi->tx_size < TX_32X32) {
7844 rate_tx_type = cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
7845 }
7846#endif
7847 rate += rate_tx_type;
7848 rate_y += rate_tx_type;
7849 }
Jingning Han3ee6db62015-08-05 19:00:31 -07007850
7851 rate2 += rate;
7852 distortion2 += distortion;
7853
7854 if (cm->interp_filter == SWITCHABLE)
7855 rate2 += vp10_get_switchable_rate(cpi, xd);
7856
7857 if (!mode_excluded)
7858 mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
7859 : cm->reference_mode == COMPOUND_REFERENCE;
7860
7861 compmode_cost = vp10_cost_bit(comp_mode_p, comp_pred);
7862
7863 tmp_best_rdu = best_rd -
James Zern5e16d392015-08-17 18:19:22 -07007864 VPXMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
7865 RDCOST(x->rdmult, x->rddiv, 0, total_sse));
Jingning Han3ee6db62015-08-05 19:00:31 -07007866
7867 if (tmp_best_rdu > 0) {
7868 // If even the 'Y' rd value of split is higher than best so far
7869 // then dont bother looking at UV
7870 vp10_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col,
7871 BLOCK_8X8);
7872 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
Jingning Hana8dad552015-10-08 16:46:10 -07007873#if CONFIG_VAR_TX
7874 if (!inter_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
7875 &uv_sse, BLOCK_8X8, tmp_best_rdu))
7876 continue;
7877#else
Jingning Han3ee6db62015-08-05 19:00:31 -07007878 if (!super_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
7879 &uv_sse, BLOCK_8X8, tmp_best_rdu))
7880 continue;
Jingning Hana8dad552015-10-08 16:46:10 -07007881#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07007882 rate2 += rate_uv;
7883 distortion2 += distortion_uv;
7884 skippable = skippable && uv_skippable;
7885 total_sse += uv_sse;
7886 }
7887 }
7888
7889 if (cm->reference_mode == REFERENCE_MODE_SELECT)
7890 rate2 += compmode_cost;
7891
7892 // Estimate the reference frame signaling cost and add it
7893 // to the rolling cost variable.
7894 if (second_ref_frame > INTRA_FRAME) {
7895 rate2 += ref_costs_comp[ref_frame];
7896 } else {
7897 rate2 += ref_costs_single[ref_frame];
7898 }
7899
7900 if (!disable_skip) {
7901 // Skip is never coded at the segment level for sub8x8 blocks and instead
7902 // always coded in the bitstream at the mode info level.
7903
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04007904 if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Jingning Han3ee6db62015-08-05 19:00:31 -07007905 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
7906 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
7907 // Add in the cost of the no skip flag.
7908 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
7909 } else {
7910 // FIXME(rbultje) make this work for splitmv also
7911 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
7912 distortion2 = total_sse;
7913 assert(total_sse >= 0);
7914 rate2 -= (rate_y + rate_uv);
7915 rate_y = 0;
7916 rate_uv = 0;
7917 this_skip2 = 1;
7918 }
7919 } else {
7920 // Add in the cost of the no skip flag.
7921 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
7922 }
7923
7924 // Calculate the final RD estimate for this mode.
7925 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
7926 }
7927
7928 if (!disable_skip && ref_frame == INTRA_FRAME) {
7929 for (i = 0; i < REFERENCE_MODES; ++i)
James Zern5e16d392015-08-17 18:19:22 -07007930 best_pred_rd[i] = VPXMIN(best_pred_rd[i], this_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07007931 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
James Zern5e16d392015-08-17 18:19:22 -07007932 best_filter_rd[i] = VPXMIN(best_filter_rd[i], this_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07007933 }
7934
7935 // Did this mode help.. i.e. is it the new best mode
7936 if (this_rd < best_rd || x->skip) {
7937 if (!mode_excluded) {
7938 int max_plane = MAX_MB_PLANE;
7939 // Note index of best mode so far
7940 best_ref_index = ref_index;
7941
7942 if (ref_frame == INTRA_FRAME) {
7943 /* required for left and above block mv */
7944 mbmi->mv[0].as_int = 0;
7945 max_plane = 1;
7946 }
7947
7948 rd_cost->rate = rate2;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08007949#if CONFIG_SUPERTX
7950 *returnrate_nocoef = rate2 - rate_y - rate_uv;
7951 if (!disable_skip)
7952 *returnrate_nocoef -= vp10_cost_bit(vp10_get_skip_prob(cm, xd),
7953 this_skip2);
7954 *returnrate_nocoef -= vp10_cost_bit(vp10_get_intra_inter_prob(cm, xd),
7955 mbmi->ref_frame[0] != INTRA_FRAME);
7956 assert(*returnrate_nocoef > 0);
7957#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07007958 rd_cost->dist = distortion2;
7959 rd_cost->rdcost = this_rd;
7960 best_rd = this_rd;
7961 best_yrd = best_rd -
7962 RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
7963 best_mbmode = *mbmi;
7964 best_skip2 = this_skip2;
7965 if (!x->select_tx_size)
7966 swap_block_ptr(x, ctx, 1, 0, 0, max_plane);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07007967
7968#if CONFIG_VAR_TX
7969 for (i = 0; i < MAX_MB_PLANE; ++i)
7970 memset(ctx->blk_skip[i], 0, sizeof(uint8_t) * ctx->num_4x4_blk);
7971#else
Jingning Han3ee6db62015-08-05 19:00:31 -07007972 memcpy(ctx->zcoeff_blk, x->zcoeff_blk[TX_4X4],
hui su088b05f2015-08-12 10:41:51 -07007973 sizeof(ctx->zcoeff_blk[0]) * ctx->num_4x4_blk);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07007974#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07007975
7976 for (i = 0; i < 4; i++)
7977 best_bmodes[i] = xd->mi[0]->bmi[i];
7978
7979 // TODO(debargha): enhance this test with a better distortion prediction
7980 // based on qp, activity mask and history
7981 if ((sf->mode_search_skip_flags & FLAG_EARLY_TERMINATE) &&
7982 (ref_index > MIN_EARLY_TERM_INDEX)) {
7983 int qstep = xd->plane[0].dequant[1];
7984 // TODO(debargha): Enhance this by specializing for each mode_index
7985 int scale = 4;
7986#if CONFIG_VP9_HIGHBITDEPTH
7987 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
7988 qstep >>= (xd->bd - 8);
7989 }
7990#endif // CONFIG_VP9_HIGHBITDEPTH
7991 if (x->source_variance < UINT_MAX) {
7992 const int var_adjust = (x->source_variance < 16);
7993 scale -= var_adjust;
7994 }
7995 if (ref_frame > INTRA_FRAME &&
7996 distortion2 * scale < qstep * qstep) {
7997 early_term = 1;
7998 }
7999 }
8000 }
8001 }
8002
8003 /* keep record of best compound/single-only prediction */
8004 if (!disable_skip && ref_frame != INTRA_FRAME) {
8005 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
8006
8007 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
8008 single_rate = rate2 - compmode_cost;
8009 hybrid_rate = rate2;
8010 } else {
8011 single_rate = rate2;
8012 hybrid_rate = rate2 + compmode_cost;
8013 }
8014
8015 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
8016 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
8017
8018 if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE])
8019 best_pred_rd[SINGLE_REFERENCE] = single_rd;
8020 else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE])
8021 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
8022
8023 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
8024 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
8025 }
8026
8027 /* keep record of best filter type */
8028 if (!mode_excluded && !disable_skip && ref_frame != INTRA_FRAME &&
8029 cm->interp_filter != BILINEAR) {
8030 int64_t ref = filter_cache[cm->interp_filter == SWITCHABLE ?
8031 SWITCHABLE_FILTERS : cm->interp_filter];
8032 int64_t adj_rd;
8033 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
8034 if (ref == INT64_MAX)
8035 adj_rd = 0;
8036 else if (filter_cache[i] == INT64_MAX)
8037 // when early termination is triggered, the encoder does not have
8038 // access to the rate-distortion cost. it only knows that the cost
8039 // should be above the maximum valid value. hence it takes the known
8040 // maximum plus an arbitrary constant as the rate-distortion cost.
8041 adj_rd = mask_filter - ref + 10;
8042 else
8043 adj_rd = filter_cache[i] - ref;
8044
8045 adj_rd += this_rd;
James Zern5e16d392015-08-17 18:19:22 -07008046 best_filter_rd[i] = VPXMIN(best_filter_rd[i], adj_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07008047 }
8048 }
8049
8050 if (early_term)
8051 break;
8052
8053 if (x->skip && !comp_pred)
8054 break;
8055 }
8056
8057 if (best_rd >= best_rd_so_far) {
8058 rd_cost->rate = INT_MAX;
8059 rd_cost->rdcost = INT64_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008060#if CONFIG_SUPERTX
8061 *returnrate_nocoef = INT_MAX;
8062#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07008063 return;
8064 }
8065
8066 // If we used an estimate for the uv intra rd in the loop above...
8067 if (sf->use_uv_intra_rd_estimate) {
8068 // Do Intra UV best rd mode selection if best mode choice above was intra.
8069 if (best_mbmode.ref_frame[0] == INTRA_FRAME) {
8070 *mbmi = best_mbmode;
8071 rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra,
8072 &rate_uv_tokenonly,
8073 &dist_uv,
8074 &skip_uv,
8075 BLOCK_8X8, TX_4X4);
8076 }
8077 }
8078
8079 if (best_rd == INT64_MAX) {
8080 rd_cost->rate = INT_MAX;
8081 rd_cost->dist = INT64_MAX;
8082 rd_cost->rdcost = INT64_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008083#if CONFIG_SUPERTX
8084 *returnrate_nocoef = INT_MAX;
8085#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07008086 return;
8087 }
8088
8089 assert((cm->interp_filter == SWITCHABLE) ||
8090 (cm->interp_filter == best_mbmode.interp_filter) ||
8091 !is_inter_block(&best_mbmode));
8092
8093 vp10_update_rd_thresh_fact(tile_data->thresh_freq_fact,
8094 sf->adaptive_rd_thresh, bsize, best_ref_index);
8095
8096 // macroblock modes
8097 *mbmi = best_mbmode;
8098 x->skip |= best_skip2;
8099 if (!is_inter_block(&best_mbmode)) {
8100 for (i = 0; i < 4; i++)
8101 xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
8102 } else {
8103 for (i = 0; i < 4; ++i)
8104 memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
8105
8106 mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
8107 mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
8108 }
8109
8110 for (i = 0; i < REFERENCE_MODES; ++i) {
8111 if (best_pred_rd[i] == INT64_MAX)
8112 best_pred_diff[i] = INT_MIN;
8113 else
8114 best_pred_diff[i] = best_rd - best_pred_rd[i];
8115 }
8116
8117 if (!x->skip) {
8118 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
8119 if (best_filter_rd[i] == INT64_MAX)
8120 best_filter_diff[i] = 0;
8121 else
8122 best_filter_diff[i] = best_rd - best_filter_rd[i];
8123 }
8124 if (cm->interp_filter == SWITCHABLE)
8125 assert(best_filter_diff[SWITCHABLE_FILTERS] == 0);
8126 } else {
8127 vp10_zero(best_filter_diff);
8128 }
8129
8130 store_coding_context(x, ctx, best_ref_index,
8131 best_pred_diff, best_filter_diff, 0);
8132}
Yue Chend1cad9c2016-01-27 14:18:53 -08008133
8134#if CONFIG_OBMC
8135void vp10_build_prediction_by_above_preds(VP10_COMP *cpi,
8136 MACROBLOCKD *xd,
8137 int mi_row, int mi_col,
8138 uint8_t *tmp_buf[MAX_MB_PLANE],
8139 int tmp_stride[MAX_MB_PLANE]) {
8140 VP10_COMMON *const cm = &cpi->common;
8141 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
8142 int i, j, mi_step, ref;
8143
8144 if (mi_row == 0)
8145 return;
8146
8147 for (i = 0; i < VPXMIN(xd->n8_w, cm->mi_cols - mi_col); i += mi_step) {
8148 int mi_row_offset = -1;
8149 int mi_col_offset = i;
8150 int mi_x, mi_y, bw, bh;
8151 MODE_INFO *above_mi = xd->mi[mi_col_offset +
8152 mi_row_offset * xd->mi_stride];
8153 MB_MODE_INFO *above_mbmi = &above_mi->mbmi;
8154
8155 mi_step = VPXMIN(xd->n8_w,
8156 num_8x8_blocks_wide_lookup[above_mbmi->sb_type]);
8157
8158 if (!is_inter_block(above_mbmi))
8159 continue;
8160
8161 for (j = 0; j < MAX_MB_PLANE; ++j) {
8162 struct macroblockd_plane *const pd = &xd->plane[j];
8163 setup_pred_plane(&pd->dst,
8164 tmp_buf[j], tmp_stride[j],
8165 0, i, NULL,
8166 pd->subsampling_x, pd->subsampling_y);
8167 }
8168 set_ref_ptrs(cm, xd, above_mbmi->ref_frame[0], above_mbmi->ref_frame[1]);
8169 for (ref = 0; ref < 1 + has_second_ref(above_mbmi); ++ref) {
8170 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi,
8171 above_mbmi->ref_frame[ref]);
8172 assert(cfg != NULL);
8173 vp10_setup_pre_planes(xd, ref, cfg, mi_row, mi_col + i,
8174 &xd->block_refs[ref]->sf);
8175 }
8176
8177 xd->mb_to_left_edge = -(((mi_col + i) * MI_SIZE) * 8);
8178 mi_x = (mi_col + i) << MI_SIZE_LOG2;
8179 mi_y = mi_row << MI_SIZE_LOG2;
8180
8181 for (j = 0; j < MAX_MB_PLANE; ++j) {
8182 const struct macroblockd_plane *pd = &xd->plane[j];
8183 bw = (mi_step * 8) >> pd->subsampling_x;
8184 bh = VPXMAX((num_4x4_blocks_high_lookup[bsize] * 2) >> pd->subsampling_y,
8185 4);
8186
8187 if (above_mbmi->sb_type < BLOCK_8X8) {
8188 const PARTITION_TYPE bp = BLOCK_8X8 - above_mbmi->sb_type;
8189 const int have_vsplit = bp != PARTITION_HORZ;
8190 const int have_hsplit = bp != PARTITION_VERT;
8191 const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
8192 const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);
8193 const int pw = 8 >> (have_vsplit | pd->subsampling_x);
8194 int x, y;
8195
8196 for (y = 0; y < num_4x4_h; ++y)
8197 for (x = 0; x < num_4x4_w; ++x) {
8198 if ((bp == PARTITION_HORZ || bp == PARTITION_SPLIT)
8199 && y == 0 && !pd->subsampling_y)
8200 continue;
8201
8202 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
8203 y * 2 + x, bw, bh,
8204 4 * x, 0, pw, bh, mi_x, mi_y);
8205 }
8206 } else {
8207 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0,
8208 bw, bh, 0, 0, bw, bh, mi_x, mi_y);
8209 }
8210 }
8211 }
8212 xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8);
8213}
8214
8215void vp10_build_prediction_by_left_preds(VP10_COMP *cpi,
8216 MACROBLOCKD *xd,
8217 int mi_row, int mi_col,
8218 uint8_t *tmp_buf[MAX_MB_PLANE],
8219 int tmp_stride[MAX_MB_PLANE]) {
8220 VP10_COMMON *const cm = &cpi->common;
8221 const TileInfo *const tile = &xd->tile;
8222 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
8223 int i, j, mi_step, ref;
8224
8225 if (mi_col == 0 || (mi_col - 1 < tile->mi_col_start) ||
8226 (mi_col - 1) >= tile->mi_col_end)
8227 return;
8228
8229 for (i = 0; i < VPXMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) {
8230 int mi_row_offset = i;
8231 int mi_col_offset = -1;
8232 int mi_x, mi_y, bw, bh;
8233 MODE_INFO *left_mi = xd->mi[mi_col_offset +
8234 mi_row_offset * xd->mi_stride];
8235 MB_MODE_INFO *left_mbmi = &left_mi->mbmi;
8236
8237 mi_step = VPXMIN(xd->n8_h,
8238 num_8x8_blocks_high_lookup[left_mbmi->sb_type]);
8239
8240 if (!is_inter_block(left_mbmi))
8241 continue;
8242
8243 for (j = 0; j < MAX_MB_PLANE; ++j) {
8244 struct macroblockd_plane *const pd = &xd->plane[j];
8245 setup_pred_plane(&pd->dst,
8246 tmp_buf[j], tmp_stride[j],
8247 i, 0, NULL,
8248 pd->subsampling_x, pd->subsampling_y);
8249 }
8250 set_ref_ptrs(cm, xd, left_mbmi->ref_frame[0], left_mbmi->ref_frame[1]);
8251 for (ref = 0; ref < 1 + has_second_ref(left_mbmi); ++ref) {
8252 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi,
8253 left_mbmi->ref_frame[ref]);
8254 assert(cfg != NULL);
8255 vp10_setup_pre_planes(xd, ref, cfg, mi_row + i, mi_col,
8256 &xd->block_refs[ref]->sf);
8257 }
8258
8259 xd->mb_to_top_edge = -(((mi_row + i) * MI_SIZE) * 8);
8260 mi_x = mi_col << MI_SIZE_LOG2;
8261 mi_y = (mi_row + i) << MI_SIZE_LOG2;
8262
8263 for (j = 0; j < MAX_MB_PLANE; ++j) {
8264 const struct macroblockd_plane *pd = &xd->plane[j];
8265 bw = VPXMAX((num_4x4_blocks_wide_lookup[bsize] * 2) >> pd->subsampling_x,
8266 4);
8267 bh = (mi_step << MI_SIZE_LOG2) >> pd->subsampling_y;
8268
8269 if (left_mbmi->sb_type < BLOCK_8X8) {
8270 const PARTITION_TYPE bp = BLOCK_8X8 - left_mbmi->sb_type;
8271 const int have_vsplit = bp != PARTITION_HORZ;
8272 const int have_hsplit = bp != PARTITION_VERT;
8273 const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
8274 const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);
8275 const int ph = 8 >> (have_hsplit | pd->subsampling_y);
8276 int x, y;
8277
8278 for (y = 0; y < num_4x4_h; ++y)
8279 for (x = 0; x < num_4x4_w; ++x) {
8280 if ((bp == PARTITION_VERT || bp == PARTITION_SPLIT)
8281 && x == 0 && !pd->subsampling_x)
8282 continue;
8283
8284 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
8285 y * 2 + x, bw, bh,
8286 0, 4 * y, bw, ph, mi_x, mi_y);
8287 }
8288 } else {
8289 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0,
8290 bw, bh, 0, 0, bw, bh, mi_x, mi_y);
8291 }
8292 }
8293 }
8294 xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8);
8295}
8296#endif // CONFIG_OBMC