blob: 63163d76cdb58df9240821e300c2da024beedd12 [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 Mukherjeeda2d4a72016-02-12 16:44:33 -080085const double ext_tx_th = 0.99;
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
Sarah Parker09368fc2016-03-07 11:00:03 -080090const double ADST_FLIP_SVM[8] = {-7.3283, -3.0450, -3.2450, 3.6403, // vert
91 -9.4204, -3.1821, -4.6851, 4.1469}; // horz
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -080092
Jingning Han3ee6db62015-08-05 19:00:31 -070093typedef struct {
94 PREDICTION_MODE mode;
95 MV_REFERENCE_FRAME ref_frame[2];
96} MODE_DEFINITION;
97
98typedef struct {
99 MV_REFERENCE_FRAME ref_frame[2];
100} REF_DEFINITION;
101
102struct rdcost_block_args {
Jingning Han71c15602015-10-13 12:40:39 -0700103 const VP10_COMP *cpi;
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}},
Geza Lore7ded0382016-02-22 10:55:32 +0000265
266#if CONFIG_EXT_INTER
267 {ZEROMV, {LAST_FRAME, INTRA_FRAME}},
268 {NEARESTMV, {LAST_FRAME, INTRA_FRAME}},
269 {NEARMV, {LAST_FRAME, INTRA_FRAME}},
270 {NEWMV, {LAST_FRAME, INTRA_FRAME}},
271
272#if CONFIG_EXT_REFS
273 {ZEROMV, {LAST2_FRAME, INTRA_FRAME}},
274 {NEARESTMV, {LAST2_FRAME, INTRA_FRAME}},
275 {NEARMV, {LAST2_FRAME, INTRA_FRAME}},
276 {NEWMV, {LAST2_FRAME, INTRA_FRAME}},
277
278 {ZEROMV, {LAST3_FRAME, INTRA_FRAME}},
279 {NEARESTMV, {LAST3_FRAME, INTRA_FRAME}},
280 {NEARMV, {LAST3_FRAME, INTRA_FRAME}},
281 {NEWMV, {LAST3_FRAME, INTRA_FRAME}},
282
283 {ZEROMV, {LAST4_FRAME, INTRA_FRAME}},
284 {NEARESTMV, {LAST4_FRAME, INTRA_FRAME}},
285 {NEARMV, {LAST4_FRAME, INTRA_FRAME}},
286 {NEWMV, {LAST4_FRAME, INTRA_FRAME}},
287#endif // CONFIG_EXT_REFS
288
289 {ZEROMV, {GOLDEN_FRAME, INTRA_FRAME}},
290 {NEARESTMV, {GOLDEN_FRAME, INTRA_FRAME}},
291 {NEARMV, {GOLDEN_FRAME, INTRA_FRAME}},
292 {NEWMV, {GOLDEN_FRAME, INTRA_FRAME}},
293
294 {ZEROMV, {ALTREF_FRAME, INTRA_FRAME}},
295 {NEARESTMV, {ALTREF_FRAME, INTRA_FRAME}},
296 {NEARMV, {ALTREF_FRAME, INTRA_FRAME}},
297 {NEWMV, {ALTREF_FRAME, INTRA_FRAME}},
298#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -0700299};
300
301static const REF_DEFINITION vp10_ref_order[MAX_REFS] = {
302 {{LAST_FRAME, NONE}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800303#if CONFIG_EXT_REFS
304 {{LAST2_FRAME, NONE}},
305 {{LAST3_FRAME, NONE}},
306 {{LAST4_FRAME, NONE}},
307#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700308 {{GOLDEN_FRAME, NONE}},
309 {{ALTREF_FRAME, NONE}},
310 {{LAST_FRAME, ALTREF_FRAME}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800311#if CONFIG_EXT_REFS
312 {{LAST2_FRAME, ALTREF_FRAME}},
313 {{LAST3_FRAME, ALTREF_FRAME}},
314 {{LAST4_FRAME, ALTREF_FRAME}},
315#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700316 {{GOLDEN_FRAME, ALTREF_FRAME}},
317 {{INTRA_FRAME, NONE}},
318};
319
hui su5d011cb2015-09-15 12:44:13 -0700320static INLINE int write_uniform_cost(int n, int v) {
321 int l = get_unsigned_bits(n), m = (1 << l) - n;
322 if (l == 0)
323 return 0;
324 if (v < m)
325 return (l - 1) * vp10_cost_bit(128, 0);
326 else
327 return l * vp10_cost_bit(128, 0);
328}
329
Jingning Han3ee6db62015-08-05 19:00:31 -0700330static void swap_block_ptr(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
331 int m, int n, int min_plane, int max_plane) {
332 int i;
333
334 for (i = min_plane; i < max_plane; ++i) {
335 struct macroblock_plane *const p = &x->plane[i];
336 struct macroblockd_plane *const pd = &x->e_mbd.plane[i];
337
338 p->coeff = ctx->coeff_pbuf[i][m];
339 p->qcoeff = ctx->qcoeff_pbuf[i][m];
340 pd->dqcoeff = ctx->dqcoeff_pbuf[i][m];
341 p->eobs = ctx->eobs_pbuf[i][m];
342
343 ctx->coeff_pbuf[i][m] = ctx->coeff_pbuf[i][n];
344 ctx->qcoeff_pbuf[i][m] = ctx->qcoeff_pbuf[i][n];
345 ctx->dqcoeff_pbuf[i][m] = ctx->dqcoeff_pbuf[i][n];
346 ctx->eobs_pbuf[i][m] = ctx->eobs_pbuf[i][n];
347
348 ctx->coeff_pbuf[i][n] = p->coeff;
349 ctx->qcoeff_pbuf[i][n] = p->qcoeff;
350 ctx->dqcoeff_pbuf[i][n] = pd->dqcoeff;
351 ctx->eobs_pbuf[i][n] = p->eobs;
352 }
353}
354
Sarah Parker09368fc2016-03-07 11:00:03 -0800355// constants for prune 1 and prune 2 decision boundaries
356#define FAST_EXT_TX_CORR_MID 0.0
357#define FAST_EXT_TX_EDST_MID 0.1
358#define FAST_EXT_TX_CORR_MARGIN 0.5
359#define FAST_EXT_TX_EDST_MARGIN 0.05
360
Sarah Parker2ca7d422016-03-01 10:12:13 -0800361typedef enum {
362 DCT_1D = 0,
363 ADST_1D = 1,
364 FLIPADST_1D = 2,
365 DST_1D = 3,
366 TX_TYPES_1D = 4,
367} TX_TYPE_1D;
368
Sarah Parker09368fc2016-03-07 11:00:03 -0800369static void get_energy_distribution_fine(const VP10_COMP *cpi,
370 BLOCK_SIZE bsize,
371 uint8_t *src, int src_stride,
372 uint8_t *dst, int dst_stride,
373 double *hordist, double *verdist) {
374 int bw = 4 << (b_width_log2_lookup[bsize]);
375 int bh = 4 << (b_height_log2_lookup[bsize]);
376 unsigned int esq[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
377 unsigned int var[16];
378 double total = 0;
379 const int f_index = bsize - 6;
380 if (f_index < 0) {
381 int i, j, index;
382 int w_shift = bw == 8 ? 1 : 2;
383 int h_shift = bh == 8 ? 1 : 2;
384 for (i = 0; i < bh; ++i)
385 for (j = 0; j < bw; ++j) {
386 index = (j >> w_shift) + ((i >> h_shift) << 2);
387 esq[index] += (src[j + i * src_stride] - dst[j + i * dst_stride]) *
388 (src[j + i * src_stride] - dst[j + i * dst_stride]);
389 }
390 } else {
391 var[0] = cpi->fn_ptr[f_index].vf(src, src_stride,
392 dst, dst_stride, &esq[0]);
393 var[1] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride,
394 dst + bw / 4, dst_stride, &esq[1]);
395 var[2] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride,
396 dst + bw / 2, dst_stride, &esq[2]);
397 var[3] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
398 dst + 3 * bw / 4, dst_stride, &esq[3]);
399 src += bh / 4 * src_stride;
400 dst += bh / 4 * dst_stride;
401
402 var[4] = cpi->fn_ptr[f_index].vf(src, src_stride,
403 dst, dst_stride, &esq[4]);
404 var[5] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride,
405 dst + bw / 4, dst_stride, &esq[5]);
406 var[6] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride,
407 dst + bw / 2, dst_stride, &esq[6]);
408 var[7] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
409 dst + 3 * bw / 4, dst_stride, &esq[7]);
410 src += bh / 4 * src_stride;
411 dst += bh / 4 * dst_stride;
412
413 var[8] = cpi->fn_ptr[f_index].vf(src, src_stride,
414 dst, dst_stride, &esq[8]);
415 var[9] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride,
416 dst + bw / 4, dst_stride, &esq[9]);
417 var[10] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride,
418 dst + bw / 2, dst_stride, &esq[10]);
419 var[11] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
420 dst + 3 * bw / 4, dst_stride, &esq[11]);
421 src += bh / 4 * src_stride;
422 dst += bh / 4 * dst_stride;
423
424 var[12] = cpi->fn_ptr[f_index].vf(src, src_stride,
425 dst, dst_stride, &esq[12]);
426 var[13] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride,
427 dst + bw / 4, dst_stride, &esq[13]);
428 var[14] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride,
429 dst + bw / 2, dst_stride, &esq[14]);
430 var[15] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
431 dst + 3 * bw / 4, dst_stride, &esq[15]);
432 }
433
434 total = esq[0] + esq[1] + esq[2] + esq[3] +
435 esq[4] + esq[5] + esq[6] + esq[7] +
436 esq[8] + esq[9] + esq[10] + esq[11] +
437 esq[12] + esq[13] + esq[14] + esq[15];
438 if (total > 0) {
439 const double e_recip = 1.0 / total;
440 hordist[0] = ((double)esq[0] + (double)esq[4] + (double)esq[8] +
441 (double)esq[12]) * e_recip;
442 hordist[1] = ((double)esq[1] + (double)esq[5] + (double)esq[9] +
443 (double)esq[13]) * e_recip;
444 hordist[2] = ((double)esq[2] + (double)esq[6] + (double)esq[10] +
445 (double)esq[14]) * e_recip;
446 verdist[0] = ((double)esq[0] + (double)esq[1] + (double)esq[2] +
447 (double)esq[3]) * e_recip;
448 verdist[1] = ((double)esq[4] + (double)esq[5] + (double)esq[6] +
449 (double)esq[7]) * e_recip;
450 verdist[2] = ((double)esq[8] + (double)esq[9] + (double)esq[10] +
451 (double)esq[11]) * e_recip;
452 } else {
453 hordist[0] = verdist[0] = 0.25;
454 hordist[1] = verdist[1] = 0.25;
455 hordist[2] = verdist[2] = 0.25;
456 }
457 (void) var[0];
458 (void) var[1];
459 (void) var[2];
460 (void) var[3];
461 (void) var[4];
462 (void) var[5];
463 (void) var[6];
464 (void) var[7];
465 (void) var[8];
466 (void) var[9];
467 (void) var[10];
468 (void) var[11];
469 (void) var[12];
470 (void) var[13];
471 (void) var[14];
472 (void) var[15];
473}
474
475int adst_vs_flipadst(const VP10_COMP *cpi,
476 BLOCK_SIZE bsize,
477 uint8_t *src, int src_stride,
478 uint8_t *dst, int dst_stride,
479 double *hdist, double *vdist) {
480 int prune_bitmask = 0;
481 double svm_proj_h = 0, svm_proj_v = 0;
482 get_energy_distribution_fine(cpi, bsize, src, src_stride,
483 dst, dst_stride, hdist, vdist);
484
485
486
487 svm_proj_v = vdist[0] * ADST_FLIP_SVM[0] +
488 vdist[1] * ADST_FLIP_SVM[1] +
489 vdist[2] * ADST_FLIP_SVM[2] + ADST_FLIP_SVM[3];
490 svm_proj_h = hdist[0] * ADST_FLIP_SVM[4] +
491 hdist[1] * ADST_FLIP_SVM[5] +
492 hdist[2] * ADST_FLIP_SVM[6] + ADST_FLIP_SVM[7];
493 if (svm_proj_v > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
494 prune_bitmask |= 1 << FLIPADST_1D;
495 else if (svm_proj_v < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
496 prune_bitmask |= 1 << ADST_1D;
497
498 if (svm_proj_h > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
499 prune_bitmask |= 1 << (FLIPADST_1D + 8);
500 else if (svm_proj_h < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
501 prune_bitmask |= 1 << (ADST_1D + 8);
502
503 return prune_bitmask;
504}
505
506#if CONFIG_EXT_TX
507static void get_horver_correlation(int16_t *diff, int stride,
508 int w, int h,
509 double *hcorr, double *vcorr) {
510 // Returns hor/ver correlation coefficient
511 const int num = (h - 1) * (w - 1);
512 double num_r;
513 int i, j;
514 int64_t xy_sum = 0, xz_sum = 0;
515 int64_t x_sum = 0, y_sum = 0, z_sum = 0;
516 int64_t x2_sum = 0, y2_sum = 0, z2_sum = 0;
517 double x_var_n, y_var_n, z_var_n, xy_var_n, xz_var_n;
518 *hcorr = *vcorr = 1;
519
520 assert(num > 0);
521 num_r = 1.0 / num;
522 for (i = 1; i < h; ++i) {
523 for (j = 1; j < w; ++j) {
524 const int16_t x = diff[i * stride + j];
525 const int16_t y = diff[i * stride + j - 1];
526 const int16_t z = diff[(i - 1) * stride + j];
527 xy_sum += x * y;
528 xz_sum += x * z;
529 x_sum += x;
530 y_sum += y;
531 z_sum += z;
532 x2_sum += x * x;
533 y2_sum += y * y;
534 z2_sum += z * z;
535 }
536 }
537 x_var_n = x2_sum - (x_sum * x_sum) * num_r;
538 y_var_n = y2_sum - (y_sum * y_sum) * num_r;
539 z_var_n = z2_sum - (z_sum * z_sum) * num_r;
540 xy_var_n = xy_sum - (x_sum * y_sum) * num_r;
541 xz_var_n = xz_sum - (x_sum * z_sum) * num_r;
542 if (x_var_n > 0 && y_var_n > 0) {
543 *hcorr = xy_var_n / sqrt(x_var_n * y_var_n);
544 *hcorr = *hcorr < 0 ? 0 : *hcorr;
545 }
546 if (x_var_n > 0 && z_var_n > 0) {
547 *vcorr = xz_var_n / sqrt(x_var_n * z_var_n);
548 *vcorr = *vcorr < 0 ? 0 : *vcorr;
549 }
550}
551
552int dct_vs_dst(int16_t *diff, int stride, int w, int h,
553 double *hcorr, double *vcorr) {
554 int prune_bitmask = 0;
555 get_horver_correlation(diff, stride, w, h, hcorr, vcorr);
556
557 if (*vcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
558 prune_bitmask |= 1 << DST_1D;
559 else if (*vcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
560 prune_bitmask |= 1 << DCT_1D;
561
562 if (*hcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
563 prune_bitmask |= 1 << (DST_1D + 8);
564 else if (*hcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
565 prune_bitmask |= 1 << (DCT_1D + 8);
566 return prune_bitmask;
567}
568
569// Performance drop: 0.5%, Speed improvement: 24%
Sarah Parker2ca7d422016-03-01 10:12:13 -0800570static int prune_two_for_sby(const VP10_COMP *cpi,
571 BLOCK_SIZE bsize,
572 MACROBLOCK *x,
573 MACROBLOCKD *xd) {
Sarah Parker09368fc2016-03-07 11:00:03 -0800574 struct macroblock_plane *const p = &x->plane[0];
575 struct macroblockd_plane *const pd = &xd->plane[0];
576 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
577 const int bw = 4 << (b_width_log2_lookup[bs]);
578 const int bh = 4 << (b_height_log2_lookup[bs]);
579 double hdist[3] = {0, 0, 0}, vdist[3] = {0, 0, 0};
580 double hcorr, vcorr;
581 vp10_subtract_plane(x, bsize, 0);
582 return adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride, pd->dst.buf,
583 pd->dst.stride, hdist, vdist) |
584 dct_vs_dst(p->src_diff, bw, bw, bh, &hcorr, &vcorr);
Sarah Parker2ca7d422016-03-01 10:12:13 -0800585}
586
587static int prune_three_for_sby(const VP10_COMP *cpi,
588 BLOCK_SIZE bsize,
589 MACROBLOCK *x,
590 MACROBLOCKD *xd) {
591 (void) cpi;
592 (void) bsize;
593 (void) x;
594 (void) xd;
Sarah Parker09368fc2016-03-07 11:00:03 -0800595 return 0;
Sarah Parker2ca7d422016-03-01 10:12:13 -0800596}
597
598#endif // CONFIG_EXT_TX
599
Sarah Parker09368fc2016-03-07 11:00:03 -0800600// Performance drop: 0.3%, Speed improvement: 5%
Sarah Parker2ca7d422016-03-01 10:12:13 -0800601static int prune_one_for_sby(const VP10_COMP *cpi,
602 BLOCK_SIZE bsize,
603 MACROBLOCK *x,
604 MACROBLOCKD *xd) {
Sarah Parker09368fc2016-03-07 11:00:03 -0800605 struct macroblock_plane *const p = &x->plane[0];
606 struct macroblockd_plane *const pd = &xd->plane[0];
607 double hdist[3] = {0, 0, 0}, vdist[3] = {0, 0, 0};
608 vp10_subtract_plane(x, bsize, 0);
609 return adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride, pd->dst.buf,
610 pd->dst.stride, hdist, vdist);
Sarah Parker2ca7d422016-03-01 10:12:13 -0800611}
612
613static int prune_tx_types(const VP10_COMP *cpi,
614 BLOCK_SIZE bsize,
615 MACROBLOCK *x,
616 MACROBLOCKD *xd) {
617 switch (cpi->sf.tx_type_search) {
618 case NO_PRUNE:
619 return 0;
620 break;
621 case PRUNE_ONE :
622 return prune_one_for_sby(cpi, bsize, x, xd);
623 break;
624 #if CONFIG_EXT_TX
625 case PRUNE_TWO :
626 return prune_two_for_sby(cpi, bsize, x, xd);
627 break;
628 case PRUNE_THREE :
629 return prune_three_for_sby(cpi, bsize, x, xd);
630 break;
631 #endif
632 }
633 assert(0);
634 return 0;
635}
636
637static int do_tx_type_search(TX_TYPE tx_type,
638 int prune) {
639// TODO(sarahparker) implement for non ext tx
640#if CONFIG_EXT_TX
641 static TX_TYPE_1D vtx_tab[TX_TYPES] = {
642 DCT_1D,
643 ADST_1D,
644 DCT_1D,
645 ADST_1D,
646 FLIPADST_1D,
647 DCT_1D,
648 FLIPADST_1D,
649 ADST_1D,
650 FLIPADST_1D,
651 DST_1D,
652 DCT_1D,
653 DST_1D,
654 ADST_1D,
655 DST_1D,
656 FLIPADST_1D,
657 DST_1D,
658 };
659 static TX_TYPE_1D htx_tab[TX_TYPES] = {
660 DCT_1D,
661 DCT_1D,
662 ADST_1D,
663 ADST_1D,
664 DCT_1D,
665 FLIPADST_1D,
666 FLIPADST_1D,
667 FLIPADST_1D,
668 ADST_1D,
669 DCT_1D,
670 DST_1D,
671 ADST_1D,
672 DST_1D,
673 FLIPADST_1D,
674 DST_1D,
675 DST_1D,
676 };
Sarah Parker09368fc2016-03-07 11:00:03 -0800677 if (tx_type >= IDTX)
Sarah Parker2ca7d422016-03-01 10:12:13 -0800678 return 1;
679 return !(((prune >> vtx_tab[tx_type]) & 1) |
Sarah Parker09368fc2016-03-07 11:00:03 -0800680 ((prune >> (htx_tab[tx_type] + 8)) & 1));
Sarah Parker2ca7d422016-03-01 10:12:13 -0800681#else
682 // temporary to avoid compiler warnings
683 (void) tx_type;
684 (void) prune;
685 return 1;
686#endif
687}
688
Yaowu Xu26a9afc2015-08-13 09:42:27 -0700689static void model_rd_for_sb(VP10_COMP *cpi, BLOCK_SIZE bsize,
Jingning Han3ee6db62015-08-05 19:00:31 -0700690 MACROBLOCK *x, MACROBLOCKD *xd,
691 int *out_rate_sum, int64_t *out_dist_sum,
692 int *skip_txfm_sb, int64_t *skip_sse_sb) {
693 // Note our transform coeffs are 8 times an orthogonal transform.
694 // Hence quantizer step is also 8 times. To get effective quantizer
695 // we need to divide by 8 before sending to modeling function.
696 int i;
697 int64_t rate_sum = 0;
698 int64_t dist_sum = 0;
699 const int ref = xd->mi[0]->mbmi.ref_frame[0];
700 unsigned int sse;
701 unsigned int var = 0;
702 unsigned int sum_sse = 0;
703 int64_t total_sse = 0;
704 int skip_flag = 1;
705 const int shift = 6;
706 int rate;
707 int64_t dist;
708 const int dequant_shift =
709#if CONFIG_VP9_HIGHBITDEPTH
710 (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ?
711 xd->bd - 5 :
712#endif // CONFIG_VP9_HIGHBITDEPTH
713 3;
714
715 x->pred_sse[ref] = 0;
716
717 for (i = 0; i < MAX_MB_PLANE; ++i) {
718 struct macroblock_plane *const p = &x->plane[i];
719 struct macroblockd_plane *const pd = &xd->plane[i];
720 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
721 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
722 const BLOCK_SIZE unit_size = txsize_to_bsize[max_tx_size];
723 const int64_t dc_thr = p->quant_thred[0] >> shift;
724 const int64_t ac_thr = p->quant_thred[1] >> shift;
725 // The low thresholds are used to measure if the prediction errors are
726 // low enough so that we can skip the mode search.
James Zern5e16d392015-08-17 18:19:22 -0700727 const int64_t low_dc_thr = VPXMIN(50, dc_thr >> 2);
728 const int64_t low_ac_thr = VPXMIN(80, ac_thr >> 2);
Sarah Parker2ca7d422016-03-01 10:12:13 -0800729 int bw_shift = (b_width_log2_lookup[bs] - b_width_log2_lookup[unit_size]);
730 int bh_shift = (b_height_log2_lookup[bs] - b_width_log2_lookup[unit_size]);
731 int bw = 1 << bw_shift;
732 int bh = 1 << bh_shift;
Jingning Han3ee6db62015-08-05 19:00:31 -0700733 int idx, idy;
734 int lw = b_width_log2_lookup[unit_size] + 2;
735 int lh = b_height_log2_lookup[unit_size] + 2;
736
737 sum_sse = 0;
738
739 for (idy = 0; idy < bh; ++idy) {
740 for (idx = 0; idx < bw; ++idx) {
741 uint8_t *src = p->src.buf + (idy * p->src.stride << lh) + (idx << lw);
742 uint8_t *dst = pd->dst.buf + (idy * pd->dst.stride << lh) + (idx << lh);
Sarah Parker2ca7d422016-03-01 10:12:13 -0800743 int block_idx = (idy << bw_shift) + idx;
Jingning Han3ee6db62015-08-05 19:00:31 -0700744 int low_err_skip = 0;
745
746 var = cpi->fn_ptr[unit_size].vf(src, p->src.stride,
747 dst, pd->dst.stride, &sse);
748 x->bsse[(i << 2) + block_idx] = sse;
749 sum_sse += sse;
750
751 x->skip_txfm[(i << 2) + block_idx] = SKIP_TXFM_NONE;
752 if (!x->select_tx_size) {
753 // Check if all ac coefficients can be quantized to zero.
754 if (var < ac_thr || var == 0) {
755 x->skip_txfm[(i << 2) + block_idx] = SKIP_TXFM_AC_ONLY;
756
757 // Check if dc coefficient can be quantized to zero.
758 if (sse - var < dc_thr || sse == var) {
759 x->skip_txfm[(i << 2) + block_idx] = SKIP_TXFM_AC_DC;
760
761 if (!sse || (var < low_ac_thr && sse - var < low_dc_thr))
762 low_err_skip = 1;
763 }
764 }
765 }
766
767 if (skip_flag && !low_err_skip)
768 skip_flag = 0;
769
770 if (i == 0)
771 x->pred_sse[ref] += sse;
772 }
773 }
774
775 total_sse += sum_sse;
776
777 // Fast approximate the modelling function.
778 if (cpi->sf.simple_model_rd_from_var) {
779 int64_t rate;
780 const int64_t square_error = sum_sse;
781 int quantizer = (pd->dequant[1] >> dequant_shift);
782
783 if (quantizer < 120)
Alex Converseb3ad8122016-02-10 14:12:26 -0800784 rate = (square_error * (280 - quantizer)) >> (16 - VP9_PROB_COST_SHIFT);
Jingning Han3ee6db62015-08-05 19:00:31 -0700785 else
786 rate = 0;
787 dist = (square_error * quantizer) >> 8;
788 rate_sum += rate;
789 dist_sum += dist;
790 } else {
791 vp10_model_rd_from_var_lapndz(sum_sse, num_pels_log2_lookup[bs],
792 pd->dequant[1] >> dequant_shift,
793 &rate, &dist);
794 rate_sum += rate;
795 dist_sum += dist;
796 }
797 }
798
799 *skip_txfm_sb = skip_flag;
800 *skip_sse_sb = total_sse << 4;
801 *out_rate_sum = (int)rate_sum;
802 *out_dist_sum = dist_sum << 4;
803}
804
805int64_t vp10_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff,
806 intptr_t block_size, int64_t *ssz) {
807 int i;
808 int64_t error = 0, sqcoeff = 0;
809
810 for (i = 0; i < block_size; i++) {
811 const int diff = coeff[i] - dqcoeff[i];
812 error += diff * diff;
813 sqcoeff += coeff[i] * coeff[i];
814 }
815
816 *ssz = sqcoeff;
817 return error;
818}
819
820int64_t vp10_block_error_fp_c(const int16_t *coeff, const int16_t *dqcoeff,
821 int block_size) {
822 int i;
823 int64_t error = 0;
824
825 for (i = 0; i < block_size; i++) {
826 const int diff = coeff[i] - dqcoeff[i];
827 error += diff * diff;
828 }
829
830 return error;
831}
832
833#if CONFIG_VP9_HIGHBITDEPTH
834int64_t vp10_highbd_block_error_c(const tran_low_t *coeff,
835 const tran_low_t *dqcoeff,
836 intptr_t block_size,
837 int64_t *ssz, int bd) {
838 int i;
839 int64_t error = 0, sqcoeff = 0;
840 int shift = 2 * (bd - 8);
841 int rounding = shift > 0 ? 1 << (shift - 1) : 0;
842
843 for (i = 0; i < block_size; i++) {
844 const int64_t diff = coeff[i] - dqcoeff[i];
845 error += diff * diff;
846 sqcoeff += (int64_t)coeff[i] * (int64_t)coeff[i];
847 }
848 assert(error >= 0 && sqcoeff >= 0);
849 error = (error + rounding) >> shift;
850 sqcoeff = (sqcoeff + rounding) >> shift;
851
852 *ssz = sqcoeff;
853 return error;
854}
855#endif // CONFIG_VP9_HIGHBITDEPTH
856
857/* The trailing '0' is a terminator which is used inside cost_coeffs() to
858 * decide whether to include cost of a trailing EOB node or not (i.e. we
859 * can skip this if the last coefficient in this transform block, e.g. the
860 * 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block,
861 * were non-zero). */
862static const int16_t band_counts[TX_SIZES][8] = {
863 { 1, 2, 3, 4, 3, 16 - 13, 0 },
864 { 1, 2, 3, 4, 11, 64 - 21, 0 },
865 { 1, 2, 3, 4, 11, 256 - 21, 0 },
866 { 1, 2, 3, 4, 11, 1024 - 21, 0 },
867};
868static int cost_coeffs(MACROBLOCK *x,
869 int plane, int block,
Jingning Han2cdc1272015-10-09 09:57:42 -0700870#if CONFIG_VAR_TX
871 int coeff_ctx,
872#else
Jingning Han3ee6db62015-08-05 19:00:31 -0700873 ENTROPY_CONTEXT *A, ENTROPY_CONTEXT *L,
Jingning Han2cdc1272015-10-09 09:57:42 -0700874#endif
Jingning Han3ee6db62015-08-05 19:00:31 -0700875 TX_SIZE tx_size,
876 const int16_t *scan, const int16_t *nb,
877 int use_fast_coef_costing) {
878 MACROBLOCKD *const xd = &x->e_mbd;
879 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
880 const struct macroblock_plane *p = &x->plane[plane];
881 const struct macroblockd_plane *pd = &xd->plane[plane];
882 const PLANE_TYPE type = pd->plane_type;
883 const int16_t *band_count = &band_counts[tx_size][1];
884 const int eob = p->eobs[block];
885 const tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
886 unsigned int (*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
887 x->token_costs[tx_size][type][is_inter_block(mbmi)];
888 uint8_t token_cache[32 * 32];
Jingning Han2cdc1272015-10-09 09:57:42 -0700889#if CONFIG_VAR_TX
890 int pt = coeff_ctx;
891#else
Jingning Han3ee6db62015-08-05 19:00:31 -0700892 int pt = combine_entropy_contexts(*A, *L);
Jingning Han2cdc1272015-10-09 09:57:42 -0700893#endif
Jingning Han3ee6db62015-08-05 19:00:31 -0700894 int c, cost;
895#if CONFIG_VP9_HIGHBITDEPTH
Alex Converseb3ad8122016-02-10 14:12:26 -0800896 const int *cat6_high_cost = vp10_get_high_cost_table(xd->bd);
Jingning Han3ee6db62015-08-05 19:00:31 -0700897#else
Alex Converseb3ad8122016-02-10 14:12:26 -0800898 const int *cat6_high_cost = vp10_get_high_cost_table(8);
Jingning Han3ee6db62015-08-05 19:00:31 -0700899#endif
900
Debargha Mukherjee3787b172015-11-19 16:51:16 -0800901#if !CONFIG_VAR_TX && !CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -0700902 // Check for consistency of tx_size with mode info
903 assert(type == PLANE_TYPE_Y ? mbmi->tx_size == tx_size
904 : get_uv_tx_size(mbmi, pd) == tx_size);
Debargha Mukherjee3787b172015-11-19 16:51:16 -0800905#endif // !CONFIG_VAR_TX && !CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -0700906
907 if (eob == 0) {
908 // single eob token
909 cost = token_costs[0][0][pt][EOB_TOKEN];
910 c = 0;
911 } else {
Julia Robsonc6eba0b2016-02-17 15:52:31 +0000912 if (use_fast_coef_costing) {
913 int band_left = *band_count++;
Jingning Han3ee6db62015-08-05 19:00:31 -0700914
Julia Robsonc6eba0b2016-02-17 15:52:31 +0000915 // dc token
916 int v = qcoeff[0];
917 int16_t prev_t;
918 cost = vp10_get_token_cost(v, &prev_t, cat6_high_cost);
919 cost += (*token_costs)[0][pt][prev_t];
Jingning Han3ee6db62015-08-05 19:00:31 -0700920
Julia Robsonc6eba0b2016-02-17 15:52:31 +0000921 token_cache[0] = vp10_pt_energy_class[prev_t];
922 ++token_costs;
Jingning Han3ee6db62015-08-05 19:00:31 -0700923
Julia Robsonc6eba0b2016-02-17 15:52:31 +0000924 // ac tokens
925 for (c = 1; c < eob; c++) {
926 const int rc = scan[c];
927 int16_t t;
Jingning Han3ee6db62015-08-05 19:00:31 -0700928
Julia Robsonc6eba0b2016-02-17 15:52:31 +0000929 v = qcoeff[rc];
930 cost += vp10_get_token_cost(v, &t, cat6_high_cost);
931 cost += (*token_costs)[!prev_t][!prev_t][t];
932 prev_t = t;
933 if (!--band_left) {
934 band_left = *band_count++;
935 ++token_costs;
936 }
Jingning Han3ee6db62015-08-05 19:00:31 -0700937 }
Jingning Han3ee6db62015-08-05 19:00:31 -0700938
Julia Robsonc6eba0b2016-02-17 15:52:31 +0000939 // eob token
940 if (band_left)
Jingning Han3ee6db62015-08-05 19:00:31 -0700941 cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
Julia Robsonc6eba0b2016-02-17 15:52:31 +0000942
943 } else { // !use_fast_coef_costing
944 int band_left = *band_count++;
945
946 // dc token
947 int v = qcoeff[0];
948 int16_t tok;
949 unsigned int (*tok_cost_ptr)[COEFF_CONTEXTS][ENTROPY_TOKENS];
950 cost = vp10_get_token_cost(v, &tok, cat6_high_cost);
951 cost += (*token_costs)[0][pt][tok];
952
953 token_cache[0] = vp10_pt_energy_class[tok];
954 ++token_costs;
955
956 tok_cost_ptr = &((*token_costs)[!tok]);
957
958 // ac tokens
959 for (c = 1; c < eob; c++) {
960 const int rc = scan[c];
961
962 v = qcoeff[rc];
963 cost += vp10_get_token_cost(v, &tok, cat6_high_cost);
964 pt = get_coef_context(nb, token_cache, c);
965 cost += (*tok_cost_ptr)[pt][tok];
966 token_cache[rc] = vp10_pt_energy_class[tok];
967 if (!--band_left) {
968 band_left = *band_count++;
969 ++token_costs;
970 }
971 tok_cost_ptr = &((*token_costs)[!tok]);
972 }
973
974 // eob token
975 if (band_left) {
Jingning Han3ee6db62015-08-05 19:00:31 -0700976 pt = get_coef_context(nb, token_cache, c);
977 cost += (*token_costs)[0][pt][EOB_TOKEN];
978 }
979 }
980 }
981
Jingning Han2cdc1272015-10-09 09:57:42 -0700982#if !CONFIG_VAR_TX
Jingning Han3ee6db62015-08-05 19:00:31 -0700983 // is eob first coefficient;
984 *A = *L = (c > 0);
Jingning Han2cdc1272015-10-09 09:57:42 -0700985#endif
Jingning Han3ee6db62015-08-05 19:00:31 -0700986
987 return cost;
988}
989
Geza Lore3c4b56c2016-02-16 09:54:29 +0000990static void dist_block(const VP10_COMP *cpi, MACROBLOCK *x, int plane,
991 int block, int blk_row, int blk_col, TX_SIZE tx_size,
Jingning Han3ee6db62015-08-05 19:00:31 -0700992 int64_t *out_dist, int64_t *out_sse) {
Geza Lore3c4b56c2016-02-16 09:54:29 +0000993 if (cpi->sf.use_transform_domain_distortion) {
994 // Transform domain distortion computation is more accurate as it does
995 // not involve an inverse transform, but it is less accurate.
996 const int ss_txfrm_size = tx_size << 1;
997 MACROBLOCKD* const xd = &x->e_mbd;
998 const struct macroblock_plane *const p = &x->plane[plane];
999 const struct macroblockd_plane *const pd = &xd->plane[plane];
1000 int64_t this_sse;
1001 int shift = tx_size == TX_32X32 ? 0 : 2;
1002 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
1003 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Jingning Han3ee6db62015-08-05 19:00:31 -07001004#if CONFIG_VP9_HIGHBITDEPTH
Geza Lore3c4b56c2016-02-16 09:54:29 +00001005 const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
1006 *out_dist = vp10_highbd_block_error(coeff, dqcoeff, 16 << ss_txfrm_size,
1007 &this_sse, bd) >> shift;
Jingning Han3ee6db62015-08-05 19:00:31 -07001008#else
Geza Lore3c4b56c2016-02-16 09:54:29 +00001009 *out_dist = vp10_block_error(coeff, dqcoeff, 16 << ss_txfrm_size,
1010 &this_sse) >> shift;
Jingning Han3ee6db62015-08-05 19:00:31 -07001011#endif // CONFIG_VP9_HIGHBITDEPTH
Geza Lore3c4b56c2016-02-16 09:54:29 +00001012 *out_sse = this_sse >> shift;
1013 } else {
1014 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
1015 const int bs = 4*num_4x4_blocks_wide_lookup[tx_bsize];
1016
1017 const MACROBLOCKD *xd = &x->e_mbd;
1018 const struct macroblock_plane *p = &x->plane[plane];
1019 const struct macroblockd_plane *pd = &xd->plane[plane];
1020
1021 const int src_stride = x->plane[plane].src.stride;
1022 const int dst_stride = xd->plane[plane].dst.stride;
1023 const int src_idx = 4 * (blk_row * src_stride + blk_col);
1024 const int dst_idx = 4 * (blk_row * dst_stride + blk_col);
1025 const uint8_t *src = &x->plane[plane].src.buf[src_idx];
1026 const uint8_t *dst = &xd->plane[plane].dst.buf[dst_idx];
1027 const tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1028 const uint16_t *eob = &p->eobs[block];
1029
1030 unsigned int tmp;
1031
1032 assert(cpi != NULL);
1033
1034 cpi->fn_ptr[tx_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
1035 *out_sse = (int64_t)tmp * 16;
1036
1037 if (*eob) {
1038 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
1039#if CONFIG_VP9_HIGHBITDEPTH
1040 DECLARE_ALIGNED(16, uint16_t, recon16[32 * 32]); // MAX TX_SIZE**2
1041 uint8_t *recon = (uint8_t*)recon16;
1042#else
1043 DECLARE_ALIGNED(16, uint8_t, recon[32 * 32]); // MAX TX_SIZE**2
1044#endif // CONFIG_VP9_HIGHBITDEPTH
1045
1046 const PLANE_TYPE plane_type = plane == 0 ? PLANE_TYPE_Y : PLANE_TYPE_UV;
1047
1048 INV_TXFM_PARAM inv_txfm_param;
1049
1050 inv_txfm_param.tx_type = get_tx_type(plane_type, xd, block, tx_size);
1051 inv_txfm_param.tx_size = tx_size;
1052 inv_txfm_param.eob = *eob;
1053 inv_txfm_param.lossless = xd->lossless[mbmi->segment_id];
1054
1055#if CONFIG_VP9_HIGHBITDEPTH
1056 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1057 recon = CONVERT_TO_BYTEPTR(recon);
1058 inv_txfm_param.bd = xd->bd;
1059 vpx_highbd_convolve_copy(dst, dst_stride, recon, 32,
1060 NULL, 0, NULL, 0, bs, bs, xd->bd);
1061 highbd_inv_txfm_add(dqcoeff, recon, 32, &inv_txfm_param);
1062 } else
1063#endif // CONFIG_VP9_HIGHBITDEPTH
1064 {
1065 vpx_convolve_copy(dst, dst_stride, recon, 32,
1066 NULL, 0, NULL, 0, bs, bs);
1067 inv_txfm_add(dqcoeff, recon, 32, &inv_txfm_param);
1068 }
1069
1070 cpi->fn_ptr[tx_bsize].vf(src, src_stride, recon, 32, &tmp);
1071 }
1072
1073 *out_dist = (int64_t)tmp * 16;
1074 }
Jingning Han3ee6db62015-08-05 19:00:31 -07001075}
1076
Jingning Hanebc48ef2015-10-07 11:43:48 -07001077static int rate_block(int plane, int block, int blk_row, int blk_col,
Jingning Han3ee6db62015-08-05 19:00:31 -07001078 TX_SIZE tx_size, struct rdcost_block_args* args) {
Jingning Han2cdc1272015-10-09 09:57:42 -07001079#if CONFIG_VAR_TX
1080 int coeff_ctx = combine_entropy_contexts(*(args->t_above + blk_col),
1081 *(args->t_left + blk_row));
1082 int coeff_cost = cost_coeffs(args->x, plane, block, coeff_ctx,
1083 tx_size, args->so->scan, args->so->neighbors,
1084 args->use_fast_coef_costing);
1085 const struct macroblock_plane *p = &args->x->plane[plane];
1086 *(args->t_above + blk_col) = !(p->eobs[block] == 0);
1087 *(args->t_left + blk_row) = !(p->eobs[block] == 0);
1088 return coeff_cost;
1089#else
1090 return cost_coeffs(args->x, plane, block,
1091 args->t_above + blk_col,
1092 args->t_left + blk_row,
1093 tx_size, args->so->scan, args->so->neighbors,
Jingning Han3ee6db62015-08-05 19:00:31 -07001094 args->use_fast_coef_costing);
Geza Lore3c4b56c2016-02-16 09:54:29 +00001095#endif // CONFIG_VAR_TX
Jingning Han3ee6db62015-08-05 19:00:31 -07001096}
1097
Jingning Hanebc48ef2015-10-07 11:43:48 -07001098static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
1099 BLOCK_SIZE plane_bsize,
Jingning Han3ee6db62015-08-05 19:00:31 -07001100 TX_SIZE tx_size, void *arg) {
1101 struct rdcost_block_args *args = arg;
1102 MACROBLOCK *const x = args->x;
1103 MACROBLOCKD *const xd = &x->e_mbd;
1104 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1105 int64_t rd1, rd2, rd;
1106 int rate;
1107 int64_t dist;
1108 int64_t sse;
1109
1110 if (args->exit_early)
1111 return;
1112
1113 if (!is_inter_block(mbmi)) {
Jingning Han71c15602015-10-13 12:40:39 -07001114 struct encode_b_args arg = {x, NULL, &mbmi->skip};
Jingning Han71c15602015-10-13 12:40:39 -07001115 vp10_encode_block_intra(plane, block, blk_row, blk_col,
1116 plane_bsize, tx_size, &arg);
Geza Loreabd00502016-02-12 16:04:35 +00001117
Geza Lore3c4b56c2016-02-16 09:54:29 +00001118 if (args->cpi->sf.use_transform_domain_distortion) {
1119 dist_block(args->cpi, x, plane, block, blk_row, blk_col,
1120 tx_size, &dist, &sse);
1121 } else {
1122 // Note that the encode block_intra call above already calls
1123 // inv_txfm_add, so we can't just call dist_block here.
Geza Loreabd00502016-02-12 16:04:35 +00001124 const int bs = 4 << tx_size;
1125 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
1126 const vpx_variance_fn_t variance = args->cpi->fn_ptr[tx_bsize].vf;
1127
1128 const struct macroblock_plane *const p = &x->plane[plane];
1129 const struct macroblockd_plane *const pd = &xd->plane[plane];
1130
1131 const int src_stride = p->src.stride;
1132 const int dst_stride = pd->dst.stride;
1133 const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
1134
1135 const uint8_t *src = &p->src.buf[4 * (blk_row * src_stride + blk_col)];
1136 const uint8_t *dst = &pd->dst.buf[4 * (blk_row * dst_stride + blk_col)];
1137 const int16_t *diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
1138
1139 unsigned int tmp;
Geza Lore3c4b56c2016-02-16 09:54:29 +00001140
1141 sse = vpx_sum_squares_2d_i16(diff, diff_stride, bs);
Yaowu Xu0c0f3ef2016-02-18 15:42:19 -08001142#if CONFIG_VP9_HIGHBITDEPTH
Debargha Mukherjee389efb22016-02-24 11:25:20 -08001143 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
1144 sse = ROUNDZ_POWER_OF_TWO(sse, (xd->bd - 8) * 2);
Geza Lore3c4b56c2016-02-16 09:54:29 +00001145#endif // CONFIG_VP9_HIGHBITDEPTH
1146 sse = (int64_t)sse * 16;
1147
Geza Loreabd00502016-02-12 16:04:35 +00001148 variance(src, src_stride, dst, dst_stride, &tmp);
1149 dist = (int64_t)tmp * 16;
1150 }
Jingning Han3ee6db62015-08-05 19:00:31 -07001151 } else if (max_txsize_lookup[plane_bsize] == tx_size) {
1152 if (x->skip_txfm[(plane << 2) + (block >> (tx_size << 1))] ==
1153 SKIP_TXFM_NONE) {
1154 // full forward transform and quantization
Jingning Hancaeb10b2015-10-22 17:25:00 -07001155 vp10_xform_quant(x, plane, block, blk_row, blk_col,
Angie Chiang88cae8b2015-11-25 13:07:13 -08001156 plane_bsize, tx_size, VP10_XFORM_QUANT_B);
Geza Lore3c4b56c2016-02-16 09:54:29 +00001157 dist_block(args->cpi, x, plane, block, blk_row, blk_col,
1158 tx_size, &dist, &sse);
Jingning Han3ee6db62015-08-05 19:00:31 -07001159 } else if (x->skip_txfm[(plane << 2) + (block >> (tx_size << 1))] ==
1160 SKIP_TXFM_AC_ONLY) {
1161 // compute DC coefficient
1162 tran_low_t *const coeff = BLOCK_OFFSET(x->plane[plane].coeff, block);
1163 tran_low_t *const dqcoeff = BLOCK_OFFSET(xd->plane[plane].dqcoeff, block);
Angie Chiang88cae8b2015-11-25 13:07:13 -08001164 vp10_xform_quant(x, plane, block, blk_row, blk_col,
1165 plane_bsize, tx_size, VP10_XFORM_QUANT_DC);
Jingning Han3ee6db62015-08-05 19:00:31 -07001166 sse = x->bsse[(plane << 2) + (block >> (tx_size << 1))] << 4;
1167 dist = sse;
1168 if (x->plane[plane].eobs[block]) {
1169 const int64_t orig_sse = (int64_t)coeff[0] * coeff[0];
1170 const int64_t resd_sse = coeff[0] - dqcoeff[0];
1171 int64_t dc_correct = orig_sse - resd_sse * resd_sse;
1172#if CONFIG_VP9_HIGHBITDEPTH
1173 dc_correct >>= ((xd->bd - 8) * 2);
1174#endif
1175 if (tx_size != TX_32X32)
1176 dc_correct >>= 2;
1177
James Zern5e16d392015-08-17 18:19:22 -07001178 dist = VPXMAX(0, sse - dc_correct);
Jingning Han3ee6db62015-08-05 19:00:31 -07001179 }
1180 } else {
1181 // SKIP_TXFM_AC_DC
1182 // skip forward transform
1183 x->plane[plane].eobs[block] = 0;
1184 sse = x->bsse[(plane << 2) + (block >> (tx_size << 1))] << 4;
1185 dist = sse;
1186 }
1187 } else {
1188 // full forward transform and quantization
Angie Chiang88cae8b2015-11-25 13:07:13 -08001189 vp10_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1190 VP10_XFORM_QUANT_B);
Geza Lore3c4b56c2016-02-16 09:54:29 +00001191 dist_block(args->cpi, x, plane, block, blk_row, blk_col,
1192 tx_size, &dist, &sse);
Jingning Han3ee6db62015-08-05 19:00:31 -07001193 }
1194
1195 rd = RDCOST(x->rdmult, x->rddiv, 0, dist);
1196 if (args->this_rd + rd > args->best_rd) {
1197 args->exit_early = 1;
1198 return;
1199 }
1200
Jingning Hanebc48ef2015-10-07 11:43:48 -07001201 rate = rate_block(plane, block, blk_row, blk_col, tx_size, args);
Jingning Han3ee6db62015-08-05 19:00:31 -07001202 rd1 = RDCOST(x->rdmult, x->rddiv, rate, dist);
1203 rd2 = RDCOST(x->rdmult, x->rddiv, 0, sse);
1204
1205 // TODO(jingning): temporarily enabled only for luma component
James Zern5e16d392015-08-17 18:19:22 -07001206 rd = VPXMIN(rd1, rd2);
Jingning Han3ee6db62015-08-05 19:00:31 -07001207 if (plane == 0)
1208 x->zcoeff_blk[tx_size][block] = !x->plane[plane].eobs[block] ||
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001209 (rd1 > rd2 && !xd->lossless[mbmi->segment_id]);
Jingning Han3ee6db62015-08-05 19:00:31 -07001210
1211 args->this_rate += rate;
1212 args->this_dist += dist;
1213 args->this_sse += sse;
1214 args->this_rd += rd;
1215
1216 if (args->this_rd > args->best_rd) {
1217 args->exit_early = 1;
1218 return;
1219 }
1220
1221 args->skippable &= !x->plane[plane].eobs[block];
1222}
1223
1224static void txfm_rd_in_plane(MACROBLOCK *x,
Jingning Han71c15602015-10-13 12:40:39 -07001225 const VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07001226 int *rate, int64_t *distortion,
1227 int *skippable, int64_t *sse,
1228 int64_t ref_best_rd, int plane,
1229 BLOCK_SIZE bsize, TX_SIZE tx_size,
1230 int use_fast_coef_casting) {
1231 MACROBLOCKD *const xd = &x->e_mbd;
1232 const struct macroblockd_plane *const pd = &xd->plane[plane];
hui su5eed74e2015-08-18 16:57:07 -07001233 TX_TYPE tx_type;
Jingning Han3ee6db62015-08-05 19:00:31 -07001234 struct rdcost_block_args args;
1235 vp10_zero(args);
1236 args.x = x;
Jingning Han71c15602015-10-13 12:40:39 -07001237 args.cpi = cpi;
Jingning Han3ee6db62015-08-05 19:00:31 -07001238 args.best_rd = ref_best_rd;
1239 args.use_fast_coef_costing = use_fast_coef_casting;
1240 args.skippable = 1;
1241
1242 if (plane == 0)
1243 xd->mi[0]->mbmi.tx_size = tx_size;
1244
1245 vp10_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
1246
hui sub3cc3a02015-08-24 14:37:54 -07001247 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001248 args.so = get_scan(tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Jingning Han3ee6db62015-08-05 19:00:31 -07001249
1250 vp10_foreach_transformed_block_in_plane(xd, bsize, plane,
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001251 block_rd_txfm, &args);
Jingning Han3ee6db62015-08-05 19:00:31 -07001252 if (args.exit_early) {
1253 *rate = INT_MAX;
1254 *distortion = INT64_MAX;
1255 *sse = INT64_MAX;
1256 *skippable = 0;
1257 } else {
1258 *distortion = args.this_dist;
1259 *rate = args.this_rate;
1260 *sse = args.this_sse;
1261 *skippable = args.skippable;
1262 }
1263}
1264
Debargha Mukherjee3787b172015-11-19 16:51:16 -08001265#if CONFIG_SUPERTX
1266void vp10_txfm_rd_in_plane_supertx(MACROBLOCK *x,
Geza Lore3c4b56c2016-02-16 09:54:29 +00001267 const VP10_COMP *cpi,
Debargha Mukherjee3787b172015-11-19 16:51:16 -08001268 int *rate, int64_t *distortion,
1269 int *skippable, int64_t *sse,
1270 int64_t ref_best_rd, int plane,
1271 BLOCK_SIZE bsize, TX_SIZE tx_size,
1272 int use_fast_coef_casting) {
1273 MACROBLOCKD *const xd = &x->e_mbd;
1274 const struct macroblockd_plane *const pd = &xd->plane[plane];
1275 struct rdcost_block_args args;
1276 TX_TYPE tx_type;
1277
1278 vp10_zero(args);
Geza Lore3c4b56c2016-02-16 09:54:29 +00001279 args.cpi = cpi;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08001280 args.x = x;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08001281 args.best_rd = ref_best_rd;
1282 args.use_fast_coef_costing = use_fast_coef_casting;
1283
1284 if (plane == 0)
1285 xd->mi[0]->mbmi.tx_size = tx_size;
1286
1287 vp10_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
1288
1289 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
1290 args.so = get_scan(tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
1291
1292 block_rd_txfm(plane, 0, 0, 0, get_plane_block_size(bsize, pd),
1293 tx_size, &args);
1294
1295 if (args.exit_early) {
1296 *rate = INT_MAX;
1297 *distortion = INT64_MAX;
1298 *sse = INT64_MAX;
1299 *skippable = 0;
1300 } else {
1301 *distortion = args.this_dist;
1302 *rate = args.this_rate;
1303 *sse = args.this_sse;
1304 *skippable = !x->plane[plane].eobs[0];
1305 }
1306}
1307#endif // CONFIG_SUPERTX
1308
Yaowu Xu26a9afc2015-08-13 09:42:27 -07001309static void choose_largest_tx_size(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07001310 int *rate, int64_t *distortion,
1311 int *skip, int64_t *sse,
1312 int64_t ref_best_rd,
1313 BLOCK_SIZE bs) {
1314 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
Yaowu Xufc7cbd12015-08-13 09:36:53 -07001315 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07001316 const TX_SIZE largest_tx_size = tx_mode_to_biggest_tx_size[cm->tx_mode];
1317 MACROBLOCKD *const xd = &x->e_mbd;
1318 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001319 TX_TYPE tx_type, best_tx_type = DCT_DCT;
hui su6c81e372015-09-29 12:09:15 -07001320 int r, s;
1321 int64_t d, psse, this_rd, best_rd = INT64_MAX;
1322 vpx_prob skip_prob = vp10_get_skip_prob(cm, xd);
1323 int s0 = vp10_cost_bit(skip_prob, 0);
1324 int s1 = vp10_cost_bit(skip_prob, 1);
Sarah Parker2ca7d422016-03-01 10:12:13 -08001325 const int is_inter = is_inter_block(mbmi);
1326 int prune = 0;
Yaowu Xu0367f322016-01-11 10:27:35 -08001327#if CONFIG_EXT_TX
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001328 int ext_tx_set;
hui su6c81e372015-09-29 12:09:15 -07001329#endif // CONFIG_EXT_TX
Jingning Han3ee6db62015-08-05 19:00:31 -07001330
Sarah Parker2ca7d422016-03-01 10:12:13 -08001331 if (is_inter && cpi->sf.tx_type_search > 0)
1332 prune = prune_tx_types(cpi, bs, x, xd);
James Zern5e16d392015-08-17 18:19:22 -07001333 mbmi->tx_size = VPXMIN(max_tx_size, largest_tx_size);
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001334
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001335#if CONFIG_EXT_TX
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001336 ext_tx_set = get_ext_tx_set(mbmi->tx_size, bs, is_inter);
1337
Debargha Mukherjee8d69a6e2016-01-06 14:36:13 -08001338 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1 &&
Yaowu Xu5a27b3b2015-10-22 12:18:52 -07001339 !xd->lossless[mbmi->segment_id]) {
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001340 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
1341 if (is_inter) {
1342 if (!ext_tx_used_inter[ext_tx_set][tx_type])
1343 continue;
Sarah Parker2ca7d422016-03-01 10:12:13 -08001344 if (cpi->sf.tx_type_search > 0) {
1345 if (!do_tx_type_search(tx_type, prune))
1346 continue;
1347 } else if (ext_tx_set == 1 &&
1348 tx_type >= DST_ADST && tx_type < IDTX &&
1349 best_tx_type == DCT_DCT) {
1350 tx_type = IDTX - 1;
1351 continue;
1352 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001353 } else {
hui sud894d342015-11-18 11:24:26 -08001354 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
Yaowu Xu0367f322016-01-11 10:27:35 -08001355 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode])
hui sud894d342015-11-18 11:24:26 -08001356 continue;
1357 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001358 if (!ext_tx_used_intra[ext_tx_set][tx_type])
1359 continue;
Sarah Parker2ca7d422016-03-01 10:12:13 -08001360 if (ext_tx_set == 1 &&
1361 tx_type >= DST_ADST && tx_type < IDTX &&
1362 best_tx_type == DCT_DCT) {
1363 tx_type = IDTX - 1;
1364 continue;
1365 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001366 }
1367
1368 mbmi->tx_type = tx_type;
hui su6c81e372015-09-29 12:09:15 -07001369
Jingning Han71c15602015-10-13 12:40:39 -07001370 txfm_rd_in_plane(x,
Jingning Han71c15602015-10-13 12:40:39 -07001371 cpi,
Jingning Han71c15602015-10-13 12:40:39 -07001372 &r, &d, &s,
hui su6c81e372015-09-29 12:09:15 -07001373 &psse, ref_best_rd, 0, bs, mbmi->tx_size,
1374 cpi->sf.use_fast_coef_costing);
1375
1376 if (r == INT_MAX)
1377 continue;
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001378 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1) {
1379 if (is_inter) {
1380 if (ext_tx_set > 0)
1381 r += cpi->inter_tx_type_costs[ext_tx_set]
1382 [mbmi->tx_size][mbmi->tx_type];
1383 } else {
hui sud894d342015-11-18 11:24:26 -08001384 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001385 r += cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size]
1386 [mbmi->mode][mbmi->tx_type];
1387 }
hui su3fa01292015-09-28 18:38:00 -07001388 }
hui su6c81e372015-09-29 12:09:15 -07001389
1390 if (s)
1391 this_rd = RDCOST(x->rdmult, x->rddiv, s1, psse);
1392 else
1393 this_rd = RDCOST(x->rdmult, x->rddiv, r + s0, d);
Yaowu Xu5a27b3b2015-10-22 12:18:52 -07001394 if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] && !s)
hui su6c81e372015-09-29 12:09:15 -07001395 this_rd = VPXMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, psse));
1396
hui su4f16f112015-10-02 10:45:27 -07001397 if (this_rd < ((best_tx_type == DCT_DCT) ? ext_tx_th : 1) * best_rd) {
hui su6c81e372015-09-29 12:09:15 -07001398 best_rd = this_rd;
hui su4f16f112015-10-02 10:45:27 -07001399 best_tx_type = mbmi->tx_type;
hui su6c81e372015-09-29 12:09:15 -07001400 }
1401 }
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001402 }
hui su6c81e372015-09-29 12:09:15 -07001403
Yaowu Xu0367f322016-01-11 10:27:35 -08001404#else // CONFIG_EXT_TX
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001405 if (mbmi->tx_size < TX_32X32 &&
1406 !xd->lossless[mbmi->segment_id]) {
1407 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
1408 mbmi->tx_type = tx_type;
Yaowu Xu0367f322016-01-11 10:27:35 -08001409 txfm_rd_in_plane(x,
Yaowu Xu0367f322016-01-11 10:27:35 -08001410 cpi,
Yaowu Xu0367f322016-01-11 10:27:35 -08001411 &r, &d, &s,
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001412 &psse, ref_best_rd, 0, bs, mbmi->tx_size,
1413 cpi->sf.use_fast_coef_costing);
1414 if (r == INT_MAX)
1415 continue;
Sarah Parker2ca7d422016-03-01 10:12:13 -08001416 if (is_inter) {
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001417 r += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Sarah Parker2ca7d422016-03-01 10:12:13 -08001418 if (cpi->sf.tx_type_search > 0 && !do_tx_type_search(tx_type, prune))
1419 continue;
1420 } else {
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001421 r += cpi->intra_tx_type_costs[mbmi->tx_size]
1422 [intra_mode_to_tx_type_context[mbmi->mode]]
1423 [mbmi->tx_type];
Sarah Parker2ca7d422016-03-01 10:12:13 -08001424 }
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001425 if (s)
1426 this_rd = RDCOST(x->rdmult, x->rddiv, s1, psse);
1427 else
1428 this_rd = RDCOST(x->rdmult, x->rddiv, r + s0, d);
1429 if (is_inter && !xd->lossless[mbmi->segment_id] && !s)
1430 this_rd = VPXMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, psse));
1431
1432 if (this_rd < ((best_tx_type == DCT_DCT) ? ext_tx_th : 1) * best_rd) {
1433 best_rd = this_rd;
1434 best_tx_type = mbmi->tx_type;
1435 }
1436 }
1437 }
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001438#endif // CONFIG_EXT_TX
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001439 mbmi->tx_type = best_tx_type;
Jingning Han3ee6db62015-08-05 19:00:31 -07001440
Jingning Han71c15602015-10-13 12:40:39 -07001441 txfm_rd_in_plane(x,
Jingning Han71c15602015-10-13 12:40:39 -07001442 cpi,
Jingning Han71c15602015-10-13 12:40:39 -07001443 rate, distortion, skip,
Jingning Han3ee6db62015-08-05 19:00:31 -07001444 sse, ref_best_rd, 0, bs,
1445 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
1446}
1447
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001448static void choose_smallest_tx_size(VP10_COMP *cpi, MACROBLOCK *x,
1449 int *rate, int64_t *distortion,
1450 int *skip, int64_t *sse,
1451 int64_t ref_best_rd,
1452 BLOCK_SIZE bs) {
1453 MACROBLOCKD *const xd = &x->e_mbd;
1454 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1455
1456 mbmi->tx_size = TX_4X4;
Debargha Mukherjee4e406f72016-01-22 03:29:39 -08001457 mbmi->tx_type = DCT_DCT;
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001458
Jingning Han71c15602015-10-13 12:40:39 -07001459 txfm_rd_in_plane(x,
Jingning Han71c15602015-10-13 12:40:39 -07001460 cpi,
Jingning Han71c15602015-10-13 12:40:39 -07001461 rate, distortion, skip,
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001462 sse, ref_best_rd, 0, bs,
1463 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
1464}
1465
Yaowu Xu26a9afc2015-08-13 09:42:27 -07001466static void choose_tx_size_from_rd(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07001467 int *rate,
1468 int64_t *distortion,
1469 int *skip,
1470 int64_t *psse,
1471 int64_t ref_best_rd,
1472 BLOCK_SIZE bs) {
1473 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
Yaowu Xufc7cbd12015-08-13 09:36:53 -07001474 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07001475 MACROBLOCKD *const xd = &x->e_mbd;
1476 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1477 vpx_prob skip_prob = vp10_get_skip_prob(cm, xd);
hui su38debe52015-09-20 19:18:00 -07001478 int r, s;
1479 int64_t d, sse;
1480 int64_t rd = INT64_MAX;
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08001481 int n;
Jingning Han3ee6db62015-08-05 19:00:31 -07001482 int s0, s1;
hui su38debe52015-09-20 19:18:00 -07001483 int64_t best_rd = INT64_MAX, last_rd = INT64_MAX;
Jingning Han3ee6db62015-08-05 19:00:31 -07001484 TX_SIZE best_tx = max_tx_size;
1485 int start_tx, end_tx;
hui su38debe52015-09-20 19:18:00 -07001486 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001487 const int is_inter = is_inter_block(mbmi);
Sarah Parker2ca7d422016-03-01 10:12:13 -08001488 TX_TYPE tx_type, best_tx_type = DCT_DCT;
1489 int prune = 0;
Yaowu Xu0367f322016-01-11 10:27:35 -08001490#if CONFIG_EXT_TX
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001491 int ext_tx_set;
hui su07154b02015-09-22 10:34:18 -07001492#endif // CONFIG_EXT_TX
1493
Sarah Parker2ca7d422016-03-01 10:12:13 -08001494 if (is_inter && cpi->sf.tx_type_search > 0)
1495 prune = prune_tx_types(cpi, bs, x, xd);
1496
Jingning Han3ee6db62015-08-05 19:00:31 -07001497 assert(skip_prob > 0);
1498 s0 = vp10_cost_bit(skip_prob, 0);
1499 s1 = vp10_cost_bit(skip_prob, 1);
1500
hui su38debe52015-09-20 19:18:00 -07001501 if (tx_select) {
Jingning Han3ee6db62015-08-05 19:00:31 -07001502 start_tx = max_tx_size;
1503 end_tx = 0;
1504 } else {
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001505 const TX_SIZE chosen_tx_size =
1506 VPXMIN(max_tx_size, tx_mode_to_biggest_tx_size[cm->tx_mode]);
Jingning Han3ee6db62015-08-05 19:00:31 -07001507 start_tx = chosen_tx_size;
1508 end_tx = chosen_tx_size;
1509 }
1510
hui su38debe52015-09-20 19:18:00 -07001511 *distortion = INT64_MAX;
1512 *rate = INT_MAX;
1513 *skip = 0;
1514 *psse = INT64_MAX;
1515
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001516 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001517 last_rd = INT64_MAX;
hui su07154b02015-09-22 10:34:18 -07001518 for (n = start_tx; n >= end_tx; --n) {
hui su954e5602016-03-07 15:25:50 -08001519 const int r_tx_size =
1520 cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)][n];
hui su329e3402016-02-10 10:52:14 -08001521 if (FIXED_TX_TYPE && tx_type != get_default_tx_type(0, xd, 0, n))
1522 continue;
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001523#if CONFIG_EXT_TX
1524 ext_tx_set = get_ext_tx_set(n, bs, is_inter);
1525 if (is_inter) {
1526 if (!ext_tx_used_inter[ext_tx_set][tx_type])
1527 continue;
Sarah Parker2ca7d422016-03-01 10:12:13 -08001528 if (cpi->sf.tx_type_search > 0) {
1529 if (!do_tx_type_search(tx_type, prune))
1530 continue;
1531 } else if (ext_tx_set == 1 &&
1532 tx_type >= DST_ADST && tx_type < IDTX &&
1533 best_tx_type == DCT_DCT) {
1534 tx_type = IDTX - 1;
1535 continue;
1536 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001537 } else {
hui sud894d342015-11-18 11:24:26 -08001538 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
Yaowu Xu0367f322016-01-11 10:27:35 -08001539 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode])
hui sud894d342015-11-18 11:24:26 -08001540 continue;
1541 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001542 if (!ext_tx_used_intra[ext_tx_set][tx_type])
1543 continue;
Sarah Parker2ca7d422016-03-01 10:12:13 -08001544 if (ext_tx_set == 1 &&
1545 tx_type >= DST_ADST && tx_type < IDTX &&
1546 best_tx_type == DCT_DCT) {
1547 tx_type = IDTX - 1;
1548 break;
1549 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001550 }
1551 mbmi->tx_type = tx_type;
Jingning Han71c15602015-10-13 12:40:39 -07001552 txfm_rd_in_plane(x,
Jingning Han71c15602015-10-13 12:40:39 -07001553 cpi,
Jingning Han71c15602015-10-13 12:40:39 -07001554 &r, &d, &s,
hui su07154b02015-09-22 10:34:18 -07001555 &sse, ref_best_rd, 0, bs, n,
1556 cpi->sf.use_fast_coef_costing);
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001557 if (get_ext_tx_types(n, bs, is_inter) > 1 &&
1558 !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1559 r != INT_MAX) {
1560 if (is_inter) {
1561 if (ext_tx_set > 0)
1562 r += cpi->inter_tx_type_costs[ext_tx_set]
1563 [mbmi->tx_size][mbmi->tx_type];
1564 } else {
hui sud894d342015-11-18 11:24:26 -08001565 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001566 r += cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size]
1567 [mbmi->mode][mbmi->tx_type];
1568 }
hui su3fa01292015-09-28 18:38:00 -07001569 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001570#else // CONFIG_EXT_TX
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001571 if (n >= TX_32X32 && tx_type != DCT_DCT) {
1572 continue;
1573 }
1574 mbmi->tx_type = tx_type;
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001575 txfm_rd_in_plane(x,
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001576 cpi,
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001577 &r, &d, &s,
1578 &sse, ref_best_rd, 0, bs, n,
1579 cpi->sf.use_fast_coef_costing);
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001580 if (n < TX_32X32 &&
1581 !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
hui su329e3402016-02-10 10:52:14 -08001582 r != INT_MAX && !FIXED_TX_TYPE) {
Sarah Parker2ca7d422016-03-01 10:12:13 -08001583 if (is_inter) {
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001584 r += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Sarah Parker2ca7d422016-03-01 10:12:13 -08001585 if (cpi->sf.tx_type_search > 0 && !do_tx_type_search(tx_type, prune))
1586 continue;
1587 } else {
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001588 r += cpi->intra_tx_type_costs[mbmi->tx_size]
1589 [intra_mode_to_tx_type_context[mbmi->mode]]
1590 [mbmi->tx_type];
Sarah Parker2ca7d422016-03-01 10:12:13 -08001591 }
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001592 }
hui su07154b02015-09-22 10:34:18 -07001593#endif // CONFIG_EXT_TX
1594
1595 if (r == INT_MAX)
1596 continue;
1597
hui su07154b02015-09-22 10:34:18 -07001598 if (s) {
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001599 if (is_inter) {
hui su07154b02015-09-22 10:34:18 -07001600 rd = RDCOST(x->rdmult, x->rddiv, s1, sse);
hui su07154b02015-09-22 10:34:18 -07001601 } else {
1602 rd = RDCOST(x->rdmult, x->rddiv, s1 + r_tx_size * tx_select, sse);
1603 }
1604 } else {
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001605 rd = RDCOST(x->rdmult, x->rddiv, r + s0 + r_tx_size * tx_select, d);
hui su07154b02015-09-22 10:34:18 -07001606 }
1607
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001608 if (tx_select && !(s && is_inter))
1609 r += r_tx_size;
1610
1611 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] && !s)
hui su07154b02015-09-22 10:34:18 -07001612 rd = VPXMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, sse));
1613
1614 // Early termination in transform size search.
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001615 if (cpi->sf.tx_size_search_breakout &&
1616 (rd == INT64_MAX ||
Jingning Han35b3bd32015-11-10 16:02:33 -08001617 (s == 1 && tx_type != DCT_DCT && n < start_tx) ||
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001618 (n < (int) max_tx_size && rd > last_rd)))
hui su07154b02015-09-22 10:34:18 -07001619 break;
1620
1621 last_rd = rd;
hui su4f16f112015-10-02 10:45:27 -07001622 if (rd <
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001623 (is_inter && best_tx_type == DCT_DCT ? ext_tx_th : 1) *
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001624 best_rd) {
hui su07154b02015-09-22 10:34:18 -07001625 best_tx = n;
1626 best_rd = rd;
1627 *distortion = d;
1628 *rate = r;
1629 *skip = s;
1630 *psse = sse;
hui su4f16f112015-10-02 10:45:27 -07001631 best_tx_type = mbmi->tx_type;
hui su07154b02015-09-22 10:34:18 -07001632 }
Jingning Han3ee6db62015-08-05 19:00:31 -07001633 }
Jingning Han3ee6db62015-08-05 19:00:31 -07001634 }
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001635
Jingning Han3ee6db62015-08-05 19:00:31 -07001636 mbmi->tx_size = best_tx;
hui su4f16f112015-10-02 10:45:27 -07001637 mbmi->tx_type = best_tx_type;
Jingning Han02734b62016-03-09 09:30:17 -08001638
1639#if !CONFIG_EXT_TX
Julia Robson9fe188e2016-01-21 17:14:29 +00001640 if (mbmi->tx_size >= TX_32X32)
1641 assert(mbmi->tx_type == DCT_DCT);
Jingning Han02734b62016-03-09 09:30:17 -08001642#endif
1643
Jingning Han71c15602015-10-13 12:40:39 -07001644 txfm_rd_in_plane(x,
Jingning Han71c15602015-10-13 12:40:39 -07001645 cpi,
Jingning Han71c15602015-10-13 12:40:39 -07001646 &r, &d, &s,
hui su07154b02015-09-22 10:34:18 -07001647 &sse, ref_best_rd, 0, bs, best_tx,
1648 cpi->sf.use_fast_coef_costing);
Jingning Han3ee6db62015-08-05 19:00:31 -07001649}
1650
Yaowu Xu26a9afc2015-08-13 09:42:27 -07001651static void super_block_yrd(VP10_COMP *cpi, MACROBLOCK *x, int *rate,
Jingning Han3ee6db62015-08-05 19:00:31 -07001652 int64_t *distortion, int *skip,
1653 int64_t *psse, BLOCK_SIZE bs,
1654 int64_t ref_best_rd) {
1655 MACROBLOCKD *xd = &x->e_mbd;
1656 int64_t sse;
1657 int64_t *ret_sse = psse ? psse : &sse;
1658
1659 assert(bs == xd->mi[0]->mbmi.sb_type);
1660
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08001661 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001662 choose_smallest_tx_size(cpi, x, rate, distortion, skip, ret_sse,
1663 ref_best_rd, bs);
hui su66f2f652015-11-16 16:58:15 -08001664 } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
Jingning Han3ee6db62015-08-05 19:00:31 -07001665 choose_largest_tx_size(cpi, x, rate, distortion, skip, ret_sse, ref_best_rd,
1666 bs);
1667 } else {
1668 choose_tx_size_from_rd(cpi, x, rate, distortion, skip, ret_sse,
1669 ref_best_rd, bs);
1670 }
1671}
1672
1673static int conditional_skipintra(PREDICTION_MODE mode,
1674 PREDICTION_MODE best_intra_mode) {
1675 if (mode == D117_PRED &&
1676 best_intra_mode != V_PRED &&
1677 best_intra_mode != D135_PRED)
1678 return 1;
1679 if (mode == D63_PRED &&
1680 best_intra_mode != V_PRED &&
1681 best_intra_mode != D45_PRED)
1682 return 1;
1683 if (mode == D207_PRED &&
1684 best_intra_mode != H_PRED &&
1685 best_intra_mode != D45_PRED)
1686 return 1;
1687 if (mode == D153_PRED &&
1688 best_intra_mode != H_PRED &&
1689 best_intra_mode != D135_PRED)
1690 return 1;
1691 return 0;
1692}
1693
hui su78b0bd02016-02-23 15:22:25 -08001694static int rd_pick_palette_intra_sby(VP10_COMP *cpi, MACROBLOCK *x,
1695 BLOCK_SIZE bsize,
1696 int palette_ctx, int dc_mode_cost,
1697 PALETTE_MODE_INFO *palette_mode_info,
1698 uint8_t *best_palette_color_map,
1699 TX_SIZE *best_tx,
1700 PREDICTION_MODE *mode_selected,
1701 int64_t *best_rd) {
hui suc93e5cc2015-12-07 18:18:57 -08001702 MACROBLOCKD *const xd = &x->e_mbd;
1703 MODE_INFO *const mic = xd->mi[0];
hui su78b0bd02016-02-23 15:22:25 -08001704 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
1705 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
1706 int this_rate, this_rate_tokenonly, s, colors, n;
1707 int rate_overhead = 0;
hui suc93e5cc2015-12-07 18:18:57 -08001708 int64_t this_distortion, this_rd;
hui su78b0bd02016-02-23 15:22:25 -08001709 const int src_stride = x->plane[0].src.stride;
1710 const uint8_t *const src = x->plane[0].src.buf;
hui suc93e5cc2015-12-07 18:18:57 -08001711
1712#if CONFIG_VP9_HIGHBITDEPTH
1713 if (cpi->common.use_highbitdepth)
1714 colors = vp10_count_colors_highbd(src, src_stride, rows, cols,
1715 cpi->common.bit_depth);
1716 else
1717#endif // CONFIG_VP9_HIGHBITDEPTH
1718 colors = vp10_count_colors(src, src_stride, rows, cols);
1719 palette_mode_info->palette_size[0] = 0;
hui su78b0bd02016-02-23 15:22:25 -08001720#if CONFIG_EXT_INTRA
1721 mic->mbmi.ext_intra_mode_info.use_ext_intra_mode[0] = 0;
1722#endif // CONFIG_EXT_INTRA
hui suc93e5cc2015-12-07 18:18:57 -08001723
1724 if (colors > 1 && colors <= 64 && cpi->common.allow_screen_content_tools) {
1725 int r, c, i, j, k;
hui su78b0bd02016-02-23 15:22:25 -08001726 const int max_itr = 50;
hui suc93e5cc2015-12-07 18:18:57 -08001727 int color_ctx, color_idx = 0;
1728 int color_order[PALETTE_MAX_SIZE];
hui su78b0bd02016-02-23 15:22:25 -08001729 double *const data = x->palette_buffer->kmeans_data_buf;
1730 uint8_t *const indices = x->palette_buffer->kmeans_indices_buf;
1731 uint8_t *const pre_indices = x->palette_buffer->kmeans_pre_indices_buf;
hui suc93e5cc2015-12-07 18:18:57 -08001732 double centroids[PALETTE_MAX_SIZE];
hui su78b0bd02016-02-23 15:22:25 -08001733 uint8_t *const color_map = xd->plane[0].color_index_map;
hui suc93e5cc2015-12-07 18:18:57 -08001734 double lb, ub, val;
hui su78b0bd02016-02-23 15:22:25 -08001735 MB_MODE_INFO *const mbmi = &mic->mbmi;
1736 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
hui suc93e5cc2015-12-07 18:18:57 -08001737#if CONFIG_VP9_HIGHBITDEPTH
1738 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
1739 if (cpi->common.use_highbitdepth)
1740 lb = ub = src16[0];
1741 else
1742#endif // CONFIG_VP9_HIGHBITDEPTH
1743 lb = ub = src[0];
1744
1745#if CONFIG_VP9_HIGHBITDEPTH
1746 if (cpi->common.use_highbitdepth) {
1747 for (r = 0; r < rows; ++r) {
1748 for (c = 0; c < cols; ++c) {
1749 val = src16[r * src_stride + c];
1750 data[r * cols + c] = val;
1751 if (val < lb)
1752 lb = val;
1753 else if (val > ub)
1754 ub = val;
1755 }
1756 }
1757 } else {
1758#endif // CONFIG_VP9_HIGHBITDEPTH
1759 for (r = 0; r < rows; ++r) {
1760 for (c = 0; c < cols; ++c) {
1761 val = src[r * src_stride + c];
1762 data[r * cols + c] = val;
1763 if (val < lb)
1764 lb = val;
1765 else if (val > ub)
1766 ub = val;
1767 }
1768 }
1769#if CONFIG_VP9_HIGHBITDEPTH
1770 }
1771#endif // CONFIG_VP9_HIGHBITDEPTH
1772
hui su78b0bd02016-02-23 15:22:25 -08001773 mbmi->mode = DC_PRED;
1774#if CONFIG_EXT_INTRA
1775 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
1776#endif // CONFIG_EXT_INTRA
hui suc93e5cc2015-12-07 18:18:57 -08001777
1778 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors;
1779 n >= 2; --n) {
1780 for (i = 0; i < n; ++i)
1781 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
1782 vp10_k_means(data, centroids, indices, pre_indices, rows * cols,
1783 n, 1, max_itr);
1784 vp10_insertion_sort(centroids, n);
1785 for (i = 0; i < n; ++i)
1786 centroids[i] = round(centroids[i]);
1787 // remove duplicates
1788 i = 1;
1789 k = n;
1790 while (i < k) {
1791 if (centroids[i] == centroids[i - 1]) {
1792 j = i;
1793 while (j < k - 1) {
1794 centroids[j] = centroids[j + 1];
1795 ++j;
1796 }
1797 --k;
1798 } else {
1799 ++i;
1800 }
1801 }
1802
1803#if CONFIG_VP9_HIGHBITDEPTH
1804 if (cpi->common.use_highbitdepth)
1805 for (i = 0; i < k; ++i)
Yaowu Xu3c28b4a2016-02-08 09:41:43 -08001806 pmi->palette_colors[i] = clip_pixel_highbd((int)round(centroids[i]),
1807 cpi->common.bit_depth);
hui suc93e5cc2015-12-07 18:18:57 -08001808 else
1809#endif // CONFIG_VP9_HIGHBITDEPTH
1810 for (i = 0; i < k; ++i)
1811 pmi->palette_colors[i] = clip_pixel((int)round(centroids[i]));
1812 pmi->palette_size[0] = k;
1813
1814 vp10_calc_indices(data, centroids, indices, rows * cols, k, 1);
1815 for (r = 0; r < rows; ++r)
1816 for (c = 0; c < cols; ++c)
hui su78b0bd02016-02-23 15:22:25 -08001817 color_map[r * cols + c] = indices[r * cols + c];
hui suc93e5cc2015-12-07 18:18:57 -08001818
1819 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
1820 &s, NULL, bsize, *best_rd);
1821 if (this_rate_tokenonly == INT_MAX)
1822 continue;
1823
1824 this_rate = this_rate_tokenonly + dc_mode_cost +
1825 cpi->common.bit_depth * k * vp10_cost_bit(128, 0) +
hui su78b0bd02016-02-23 15:22:25 -08001826 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - 2] +
1827 write_uniform_cost(k, color_map[0]) +
hui suc93e5cc2015-12-07 18:18:57 -08001828 vp10_cost_bit(vp10_default_palette_y_mode_prob[bsize - BLOCK_8X8]
hui su78b0bd02016-02-23 15:22:25 -08001829 [palette_ctx], 1);
hui suc93e5cc2015-12-07 18:18:57 -08001830 for (i = 0; i < rows; ++i) {
1831 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
1832 color_ctx = vp10_get_palette_color_context(color_map, cols, i, j,
1833 k, color_order);
1834 for (r = 0; r < k; ++r)
1835 if (color_map[i * cols + j] == color_order[r]) {
1836 color_idx = r;
1837 break;
1838 }
hui su78b0bd02016-02-23 15:22:25 -08001839 assert(color_idx >= 0 && color_idx < k);
hui suc93e5cc2015-12-07 18:18:57 -08001840 this_rate +=
1841 cpi->palette_y_color_cost[k - 2][color_ctx][color_idx];
1842 }
1843 }
1844 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
1845
1846 if (this_rd < *best_rd) {
1847 *best_rd = this_rd;
hui su78b0bd02016-02-23 15:22:25 -08001848 *palette_mode_info = *pmi;
1849 memcpy(best_palette_color_map, color_map,
1850 rows * cols * sizeof(color_map[0]));
hui suc93e5cc2015-12-07 18:18:57 -08001851 *mode_selected = DC_PRED;
hui su78b0bd02016-02-23 15:22:25 -08001852 *best_tx = mbmi->tx_size;
1853 rate_overhead = this_rate - this_rate_tokenonly;
hui suc93e5cc2015-12-07 18:18:57 -08001854 }
1855 }
1856 }
hui su78b0bd02016-02-23 15:22:25 -08001857
1858 return rate_overhead;
hui suc93e5cc2015-12-07 18:18:57 -08001859}
1860
Yaowu Xu26a9afc2015-08-13 09:42:27 -07001861static int64_t rd_pick_intra4x4block(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07001862 int row, int col,
1863 PREDICTION_MODE *best_mode,
1864 const int *bmode_costs,
1865 ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
1866 int *bestrate, int *bestratey,
1867 int64_t *bestdistortion,
1868 BLOCK_SIZE bsize, int64_t rd_thresh) {
1869 PREDICTION_MODE mode;
1870 MACROBLOCKD *const xd = &x->e_mbd;
1871 int64_t best_rd = rd_thresh;
1872 struct macroblock_plane *p = &x->plane[0];
1873 struct macroblockd_plane *pd = &xd->plane[0];
1874 const int src_stride = p->src.stride;
1875 const int dst_stride = pd->dst.stride;
1876 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
1877 uint8_t *dst_init = &pd->dst.buf[row * 4 * src_stride + col * 4];
1878 ENTROPY_CONTEXT ta[2], tempa[2];
1879 ENTROPY_CONTEXT tl[2], templ[2];
1880 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1881 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1882 int idx, idy;
1883 uint8_t best_dst[8 * 8];
1884#if CONFIG_VP9_HIGHBITDEPTH
1885 uint16_t best_dst16[8 * 8];
1886#endif
1887
1888 memcpy(ta, a, sizeof(ta));
1889 memcpy(tl, l, sizeof(tl));
1890 xd->mi[0]->mbmi.tx_size = TX_4X4;
hui suc93e5cc2015-12-07 18:18:57 -08001891 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07001892
1893#if CONFIG_VP9_HIGHBITDEPTH
1894 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1895 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
1896 int64_t this_rd;
1897 int ratey = 0;
1898 int64_t distortion = 0;
1899 int rate = bmode_costs[mode];
1900
1901 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode)))
1902 continue;
1903
1904 // Only do the oblique modes if the best so far is
1905 // one of the neighboring directional modes
1906 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
1907 if (conditional_skipintra(mode, *best_mode))
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001908 continue;
Jingning Han3ee6db62015-08-05 19:00:31 -07001909 }
1910
1911 memcpy(tempa, ta, sizeof(ta));
1912 memcpy(templ, tl, sizeof(tl));
1913
1914 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
1915 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
1916 const int block = (row + idy) * 2 + (col + idx);
1917 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
1918 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
1919 int16_t *const src_diff = vp10_raster_block_offset_int16(BLOCK_8X8,
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001920 block,
1921 p->src_diff);
Jingning Han3ee6db62015-08-05 19:00:31 -07001922 tran_low_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block);
1923 xd->mi[0]->bmi[block].as_mode = mode;
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001924 vp10_predict_intra_block(xd, 1, 1, TX_4X4, mode, dst, dst_stride,
Jingning Han3ee6db62015-08-05 19:00:31 -07001925 dst, dst_stride,
1926 col + idx, row + idy, 0);
1927 vpx_highbd_subtract_block(4, 4, src_diff, 8, src, src_stride,
1928 dst, dst_stride, xd->bd);
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001929 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
hui sub3cc3a02015-08-24 14:37:54 -07001930 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001931 const scan_order *so = get_scan(TX_4X4, tx_type, 0);
Jingning Han20484042015-10-21 17:38:00 -07001932#if CONFIG_VAR_TX
1933 const int coeff_ctx = combine_entropy_contexts(*(tempa + idx),
1934 *(templ + idy));
Geza Lore432e8752016-01-22 13:57:28 +00001935#endif // CONFIG_VAR_TX
Yaowu Xu7c514e22015-09-28 15:55:46 -07001936 vp10_highbd_fwd_txfm_4x4(src_diff, coeff, 8, DCT_DCT, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07001937 vp10_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
Jingning Han20484042015-10-21 17:38:00 -07001938#if CONFIG_VAR_TX
Geza Lore432e8752016-01-22 13:57:28 +00001939 ratey += cost_coeffs(x, 0, block, coeff_ctx, TX_4X4, so->scan,
1940 so->neighbors, cpi->sf.use_fast_coef_costing);
1941 *(tempa + idx) = !(p->eobs[block] == 0);
1942 *(templ + idy) = !(p->eobs[block] == 0);
Jingning Han20484042015-10-21 17:38:00 -07001943#else
Geza Lore432e8752016-01-22 13:57:28 +00001944 ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy,
Jingning Han20484042015-10-21 17:38:00 -07001945 TX_4X4,
Jingning Han3ee6db62015-08-05 19:00:31 -07001946 so->scan, so->neighbors,
1947 cpi->sf.use_fast_coef_costing);
Geza Lore432e8752016-01-22 13:57:28 +00001948#endif // CONFIG_VAR_TX
Jingning Han3ee6db62015-08-05 19:00:31 -07001949 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1950 goto next_highbd;
hui sud76e5b32015-08-13 16:27:19 -07001951 vp10_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block),
1952 dst, dst_stride, p->eobs[block],
Yaowu Xu7c514e22015-09-28 15:55:46 -07001953 xd->bd, DCT_DCT, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07001954 } else {
Yue Chenef8f7c12016-03-04 09:48:57 -08001955 int64_t dist;
1956 unsigned int tmp;
hui sub3cc3a02015-08-24 14:37:54 -07001957 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001958 const scan_order *so = get_scan(TX_4X4, tx_type, 0);
Jingning Han20484042015-10-21 17:38:00 -07001959#if CONFIG_VAR_TX
1960 const int coeff_ctx = combine_entropy_contexts(*(tempa + idx),
1961 *(templ + idy));
Geza Lore432e8752016-01-22 13:57:28 +00001962#endif // CONFIG_VAR_TX
Yaowu Xu7c514e22015-09-28 15:55:46 -07001963 vp10_highbd_fwd_txfm_4x4(src_diff, coeff, 8, tx_type, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07001964 vp10_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
Jingning Han20484042015-10-21 17:38:00 -07001965#if CONFIG_VAR_TX
Geza Lore432e8752016-01-22 13:57:28 +00001966 ratey += cost_coeffs(x, 0, block, coeff_ctx, TX_4X4, so->scan,
1967 so->neighbors, cpi->sf.use_fast_coef_costing);
1968 *(tempa + idx) = !(p->eobs[block] == 0);
1969 *(templ + idy) = !(p->eobs[block] == 0);
Jingning Han20484042015-10-21 17:38:00 -07001970#else
Geza Lore432e8752016-01-22 13:57:28 +00001971 ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy,
1972 TX_4X4, so->scan, so->neighbors,
Jingning Han3ee6db62015-08-05 19:00:31 -07001973 cpi->sf.use_fast_coef_costing);
Geza Lore432e8752016-01-22 13:57:28 +00001974#endif // CONFIG_VAR_TX
hui sud76e5b32015-08-13 16:27:19 -07001975 vp10_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block),
1976 dst, dst_stride, p->eobs[block],
Yaowu Xu7c514e22015-09-28 15:55:46 -07001977 xd->bd, tx_type, 0);
Yue Chenef8f7c12016-03-04 09:48:57 -08001978 cpi->fn_ptr[BLOCK_4X4].vf(src, src_stride, dst, dst_stride, &tmp);
1979 dist = (int64_t)tmp << 4;
1980 distortion += dist;
1981 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1982 goto next_highbd;
Jingning Han3ee6db62015-08-05 19:00:31 -07001983 }
1984 }
1985 }
1986
1987 rate += ratey;
1988 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
1989
1990 if (this_rd < best_rd) {
1991 *bestrate = rate;
1992 *bestratey = ratey;
1993 *bestdistortion = distortion;
1994 best_rd = this_rd;
1995 *best_mode = mode;
1996 memcpy(a, tempa, sizeof(tempa));
1997 memcpy(l, templ, sizeof(templ));
1998 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
1999 memcpy(best_dst16 + idy * 8,
2000 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
2001 num_4x4_blocks_wide * 4 * sizeof(uint16_t));
2002 }
2003 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07002004next_highbd:
Jingning Han3ee6db62015-08-05 19:00:31 -07002005 {}
2006 }
Geza Lore432e8752016-01-22 13:57:28 +00002007
Jingning Han481b8342015-09-11 08:56:06 -07002008 if (best_rd >= rd_thresh)
Jingning Han3ee6db62015-08-05 19:00:31 -07002009 return best_rd;
2010
2011 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
2012 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
2013 best_dst16 + idy * 8,
2014 num_4x4_blocks_wide * 4 * sizeof(uint16_t));
2015 }
2016
2017 return best_rd;
2018 }
2019#endif // CONFIG_VP9_HIGHBITDEPTH
2020
2021 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2022 int64_t this_rd;
2023 int ratey = 0;
2024 int64_t distortion = 0;
2025 int rate = bmode_costs[mode];
2026
2027 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode)))
2028 continue;
2029
2030 // Only do the oblique modes if the best so far is
2031 // one of the neighboring directional modes
2032 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2033 if (conditional_skipintra(mode, *best_mode))
Debargha Mukherjee8a429242015-10-12 12:30:55 -07002034 continue;
Jingning Han3ee6db62015-08-05 19:00:31 -07002035 }
2036
2037 memcpy(tempa, ta, sizeof(ta));
2038 memcpy(templ, tl, sizeof(tl));
2039
2040 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
2041 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
2042 const int block = (row + idy) * 2 + (col + idx);
2043 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2044 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
2045 int16_t *const src_diff =
2046 vp10_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff);
2047 tran_low_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block);
2048 xd->mi[0]->bmi[block].as_mode = mode;
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04002049 vp10_predict_intra_block(xd, 1, 1, TX_4X4, mode, dst, dst_stride,
Jingning Han3ee6db62015-08-05 19:00:31 -07002050 dst, dst_stride, col + idx, row + idy, 0);
2051 vpx_subtract_block(4, 4, src_diff, 8, src, src_stride, dst, dst_stride);
2052
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04002053 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
hui sub3cc3a02015-08-24 14:37:54 -07002054 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07002055 const scan_order *so = get_scan(TX_4X4, tx_type, 0);
Jingning Han2cdc1272015-10-09 09:57:42 -07002056#if CONFIG_VAR_TX
Geza Lore432e8752016-01-22 13:57:28 +00002057 const int coeff_ctx = combine_entropy_contexts(*(tempa + idx),
2058 *(templ + idy));
Jingning Han2cdc1272015-10-09 09:57:42 -07002059#endif
Yaowu Xu7c514e22015-09-28 15:55:46 -07002060 vp10_fwd_txfm_4x4(src_diff, coeff, 8, DCT_DCT, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07002061 vp10_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
Jingning Han2cdc1272015-10-09 09:57:42 -07002062#if CONFIG_VAR_TX
2063 ratey += cost_coeffs(x, 0, block, coeff_ctx, TX_4X4, so->scan,
2064 so->neighbors, cpi->sf.use_fast_coef_costing);
2065 *(tempa + idx) = !(p->eobs[block] == 0);
2066 *(templ + idy) = !(p->eobs[block] == 0);
2067#else
2068 ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy,
2069 TX_4X4,
Jingning Han3ee6db62015-08-05 19:00:31 -07002070 so->scan, so->neighbors,
2071 cpi->sf.use_fast_coef_costing);
Jingning Han2cdc1272015-10-09 09:57:42 -07002072#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07002073 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2074 goto next;
hui sud76e5b32015-08-13 16:27:19 -07002075 vp10_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block),
Yaowu Xu7c514e22015-09-28 15:55:46 -07002076 dst, dst_stride, p->eobs[block], DCT_DCT, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07002077 } else {
Yue Chenef8f7c12016-03-04 09:48:57 -08002078 int64_t dist;
2079 unsigned int tmp;
hui sub3cc3a02015-08-24 14:37:54 -07002080 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07002081 const scan_order *so = get_scan(TX_4X4, tx_type, 0);
Jingning Han2cdc1272015-10-09 09:57:42 -07002082#if CONFIG_VAR_TX
Geza Lore432e8752016-01-22 13:57:28 +00002083 const int coeff_ctx = combine_entropy_contexts(*(tempa + idx),
2084 *(templ + idy));
Jingning Han2cdc1272015-10-09 09:57:42 -07002085#endif
Yaowu Xu7c514e22015-09-28 15:55:46 -07002086 vp10_fwd_txfm_4x4(src_diff, coeff, 8, tx_type, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07002087 vp10_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
Jingning Han2cdc1272015-10-09 09:57:42 -07002088#if CONFIG_VAR_TX
2089 ratey += cost_coeffs(x, 0, block, coeff_ctx, TX_4X4, so->scan,
2090 so->neighbors, cpi->sf.use_fast_coef_costing);
2091 *(tempa + idx) = !(p->eobs[block] == 0);
2092 *(templ + idy) = !(p->eobs[block] == 0);
2093#else
2094 ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy,
2095 TX_4X4, so->scan, so->neighbors,
2096 cpi->sf.use_fast_coef_costing);
2097#endif
hui sud76e5b32015-08-13 16:27:19 -07002098 vp10_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block),
Yaowu Xu7c514e22015-09-28 15:55:46 -07002099 dst, dst_stride, p->eobs[block], tx_type, 0);
Yue Chenef8f7c12016-03-04 09:48:57 -08002100 cpi->fn_ptr[BLOCK_4X4].vf(src, src_stride, dst, dst_stride, &tmp);
2101 dist = (int64_t)tmp << 4;
2102 distortion += dist;
2103 // To use the pixel domain distortion, the step below needs to be
2104 // put behind the inv txfm. Compared to calculating the distortion
2105 // in the frequency domain, the overhead of encoding effort is low.
2106 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2107 goto next;
Jingning Han3ee6db62015-08-05 19:00:31 -07002108 }
2109 }
2110 }
2111
2112 rate += ratey;
2113 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2114
2115 if (this_rd < best_rd) {
2116 *bestrate = rate;
2117 *bestratey = ratey;
2118 *bestdistortion = distortion;
2119 best_rd = this_rd;
2120 *best_mode = mode;
2121 memcpy(a, tempa, sizeof(tempa));
2122 memcpy(l, templ, sizeof(templ));
2123 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
2124 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
2125 num_4x4_blocks_wide * 4);
2126 }
2127 next:
2128 {}
2129 }
2130
Jingning Hanf1376972015-09-10 12:42:21 -07002131 if (best_rd >= rd_thresh)
Jingning Han3ee6db62015-08-05 19:00:31 -07002132 return best_rd;
2133
2134 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
2135 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
2136 num_4x4_blocks_wide * 4);
2137
2138 return best_rd;
2139}
2140
Yaowu Xu26a9afc2015-08-13 09:42:27 -07002141static int64_t rd_pick_intra_sub_8x8_y_mode(VP10_COMP *cpi, MACROBLOCK *mb,
Jingning Han3ee6db62015-08-05 19:00:31 -07002142 int *rate, int *rate_y,
2143 int64_t *distortion,
2144 int64_t best_rd) {
2145 int i, j;
2146 const MACROBLOCKD *const xd = &mb->e_mbd;
2147 MODE_INFO *const mic = xd->mi[0];
2148 const MODE_INFO *above_mi = xd->above_mi;
2149 const MODE_INFO *left_mi = xd->left_mi;
2150 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
2151 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2152 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2153 int idx, idy;
2154 int cost = 0;
2155 int64_t total_distortion = 0;
2156 int tot_rate_y = 0;
2157 int64_t total_rd = 0;
2158 ENTROPY_CONTEXT t_above[4], t_left[4];
hui su1559afd2015-12-30 10:27:19 -08002159 const int *bmode_costs = cpi->mbmode_cost[0];
Jingning Han3ee6db62015-08-05 19:00:31 -07002160
2161 memcpy(t_above, xd->plane[0].above_context, sizeof(t_above));
2162 memcpy(t_left, xd->plane[0].left_context, sizeof(t_left));
2163
hui sube3559b2015-10-07 09:29:02 -07002164#if CONFIG_EXT_INTRA
2165 mic->mbmi.ext_intra_mode_info.use_ext_intra_mode[0] = 0;
hui su3b1c7662016-01-12 16:38:58 -08002166 mic->mbmi.intra_filter = INTRA_FILTER_LINEAR;
hui sube3559b2015-10-07 09:29:02 -07002167#endif // CONFIG_EXT_INTRA
2168
Debargha Mukherjeed46c1f22016-02-08 15:59:17 -08002169 // TODO(any): Add search of the tx_type to improve rd performance at the
2170 // expense of speed.
2171 mic->mbmi.tx_type = DCT_DCT;
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08002172 mic->mbmi.tx_size = TX_4X4;
Debargha Mukherjeed46c1f22016-02-08 15:59:17 -08002173
Jingning Han3ee6db62015-08-05 19:00:31 -07002174 // Pick modes for each sub-block (of size 4x4, 4x8, or 8x4) in an 8x8 block.
2175 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
2176 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
2177 PREDICTION_MODE best_mode = DC_PRED;
2178 int r = INT_MAX, ry = INT_MAX;
2179 int64_t d = INT64_MAX, this_rd = INT64_MAX;
2180 i = idy * 2 + idx;
2181 if (cpi->common.frame_type == KEY_FRAME) {
2182 const PREDICTION_MODE A = vp10_above_block_mode(mic, above_mi, i);
2183 const PREDICTION_MODE L = vp10_left_block_mode(mic, left_mi, i);
2184
2185 bmode_costs = cpi->y_mode_costs[A][L];
2186 }
2187
2188 this_rd = rd_pick_intra4x4block(cpi, mb, idy, idx, &best_mode,
2189 bmode_costs, t_above + idx, t_left + idy,
2190 &r, &ry, &d, bsize, best_rd - total_rd);
2191 if (this_rd >= best_rd - total_rd)
2192 return INT64_MAX;
2193
2194 total_rd += this_rd;
2195 cost += r;
2196 total_distortion += d;
2197 tot_rate_y += ry;
2198
2199 mic->bmi[i].as_mode = best_mode;
2200 for (j = 1; j < num_4x4_blocks_high; ++j)
2201 mic->bmi[i + j * 2].as_mode = best_mode;
2202 for (j = 1; j < num_4x4_blocks_wide; ++j)
2203 mic->bmi[i + j].as_mode = best_mode;
2204
2205 if (total_rd >= best_rd)
2206 return INT64_MAX;
2207 }
2208 }
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08002209 mic->mbmi.mode = mic->bmi[3].as_mode;
2210
2211 // Add in the cost of the transform type
2212 if (!xd->lossless[mic->mbmi.segment_id]) {
2213 int rate_tx_type = 0;
2214#if CONFIG_EXT_TX
2215 if (get_ext_tx_types(TX_4X4, bsize, 0) > 1) {
2216 const int eset = get_ext_tx_set(TX_4X4, bsize, 0);
2217 rate_tx_type =
2218 cpi->intra_tx_type_costs[eset][TX_4X4]
2219 [mic->mbmi.mode][mic->mbmi.tx_type];
2220 }
2221#else
2222 rate_tx_type =
2223 cpi->intra_tx_type_costs[TX_4X4]
2224 [intra_mode_to_tx_type_context[mic->mbmi.mode]]
2225 [mic->mbmi.tx_type];
2226#endif
2227 assert(mic->mbmi.tx_size == TX_4X4);
2228 cost += rate_tx_type;
2229 tot_rate_y += rate_tx_type;
2230 }
Jingning Han3ee6db62015-08-05 19:00:31 -07002231
2232 *rate = cost;
2233 *rate_y = tot_rate_y;
2234 *distortion = total_distortion;
Jingning Han3ee6db62015-08-05 19:00:31 -07002235
2236 return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
2237}
2238
hui sube3559b2015-10-07 09:29:02 -07002239#if CONFIG_EXT_INTRA
2240// Return 1 if an ext intra mode is selected; return 0 otherwise.
2241static int rd_pick_ext_intra_sby(VP10_COMP *cpi, MACROBLOCK *x,
2242 int *rate, int *rate_tokenonly,
2243 int64_t *distortion, int *skippable,
2244 BLOCK_SIZE bsize, int mode_cost,
2245 int64_t *best_rd) {
2246 MACROBLOCKD *const xd = &x->e_mbd;
2247 MODE_INFO *const mic = xd->mi[0];
2248 MB_MODE_INFO *mbmi = &mic->mbmi;
2249 int this_rate, this_rate_tokenonly, s;
2250 int ext_intra_selected_flag = 0;
hui su4aa50c12015-11-10 12:09:59 -08002251 int64_t this_distortion, this_rd;
hui sube3559b2015-10-07 09:29:02 -07002252 EXT_INTRA_MODE mode;
2253 TX_SIZE best_tx_size = TX_4X4;
2254 EXT_INTRA_MODE_INFO ext_intra_mode_info;
hui sube3559b2015-10-07 09:29:02 -07002255 TX_TYPE best_tx_type;
hui sube3559b2015-10-07 09:29:02 -07002256
2257 vp10_zero(ext_intra_mode_info);
2258 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 1;
2259 mbmi->mode = DC_PRED;
hui su78b0bd02016-02-23 15:22:25 -08002260 mbmi->palette_mode_info.palette_size[0] = 0;
hui sube3559b2015-10-07 09:29:02 -07002261
hui su4aa50c12015-11-10 12:09:59 -08002262 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
2263 mbmi->ext_intra_mode_info.ext_intra_mode[0] = mode;
2264 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
2265 &s, NULL, bsize, *best_rd);
2266 if (this_rate_tokenonly == INT_MAX)
2267 continue;
hui sube3559b2015-10-07 09:29:02 -07002268
hui su4aa50c12015-11-10 12:09:59 -08002269 this_rate = this_rate_tokenonly +
2270 vp10_cost_bit(cpi->common.fc->ext_intra_probs[0], 1) +
2271 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
2272 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui sube3559b2015-10-07 09:29:02 -07002273
hui su4aa50c12015-11-10 12:09:59 -08002274 if (this_rd < *best_rd) {
2275 *best_rd = this_rd;
2276 best_tx_size = mic->mbmi.tx_size;
2277 ext_intra_mode_info = mbmi->ext_intra_mode_info;
hui su4aa50c12015-11-10 12:09:59 -08002278 best_tx_type = mic->mbmi.tx_type;
hui su4aa50c12015-11-10 12:09:59 -08002279 *rate = this_rate;
2280 *rate_tokenonly = this_rate_tokenonly;
2281 *distortion = this_distortion;
2282 *skippable = s;
2283 ext_intra_selected_flag = 1;
hui sube3559b2015-10-07 09:29:02 -07002284 }
2285 }
2286
2287 if (ext_intra_selected_flag) {
2288 mbmi->mode = DC_PRED;
2289 mbmi->tx_size = best_tx_size;
2290 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] =
2291 ext_intra_mode_info.use_ext_intra_mode[0];
2292 mbmi->ext_intra_mode_info.ext_intra_mode[0] =
2293 ext_intra_mode_info.ext_intra_mode[0];
hui sube3559b2015-10-07 09:29:02 -07002294 mbmi->tx_type = best_tx_type;
hui sube3559b2015-10-07 09:29:02 -07002295 return 1;
2296 } else {
2297 return 0;
2298 }
2299}
hui su4aa50c12015-11-10 12:09:59 -08002300
hui su5a7c8d82016-02-08 10:39:17 -08002301static void pick_intra_angle_routine_sby(VP10_COMP *cpi, MACROBLOCK *x,
2302 int *rate, int *rate_tokenonly,
2303 int64_t *distortion, int *skippable,
2304 int *best_angle_delta,
2305 TX_SIZE *best_tx_size,
2306 TX_TYPE *best_tx_type,
2307 INTRA_FILTER *best_filter,
2308 BLOCK_SIZE bsize, int rate_overhead,
2309 int64_t *best_rd) {
2310 int this_rate, this_rate_tokenonly, s;
2311 int64_t this_distortion, this_rd;
2312 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
2313 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
2314 &s, NULL, bsize, *best_rd);
2315 if (this_rate_tokenonly == INT_MAX)
2316 return;
2317
2318 this_rate = this_rate_tokenonly + rate_overhead;
2319 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
2320
2321 if (this_rd < *best_rd) {
2322 *best_rd = this_rd;
2323 *best_angle_delta = mbmi->angle_delta[0];
2324 *best_tx_size = mbmi->tx_size;
2325 *best_filter = mbmi->intra_filter;
2326 *best_tx_type = mbmi->tx_type;
2327 *rate = this_rate;
2328 *rate_tokenonly = this_rate_tokenonly;
2329 *distortion = this_distortion;
2330 *skippable = s;
2331 }
2332}
2333
hui su4aa50c12015-11-10 12:09:59 -08002334static int64_t rd_pick_intra_angle_sby(VP10_COMP *cpi, MACROBLOCK *x,
2335 int *rate, int *rate_tokenonly,
2336 int64_t *distortion, int *skippable,
2337 BLOCK_SIZE bsize, int rate_overhead,
2338 int64_t best_rd) {
2339 MACROBLOCKD *const xd = &x->e_mbd;
2340 MODE_INFO *const mic = xd->mi[0];
2341 MB_MODE_INFO *mbmi = &mic->mbmi;
2342 int this_rate, this_rate_tokenonly, s;
hui su3b1c7662016-01-12 16:38:58 -08002343 int angle_delta, best_angle_delta = 0, p_angle;
2344 const int intra_filter_ctx = vp10_get_pred_context_intra_interp(xd);
2345 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
hui su4aa50c12015-11-10 12:09:59 -08002346 const double rd_adjust = 1.2;
2347 int64_t this_distortion, this_rd, sse_dummy;
2348 TX_SIZE best_tx_size = mic->mbmi.tx_size;
hui su4aa50c12015-11-10 12:09:59 -08002349 TX_TYPE best_tx_type = mbmi->tx_type;
hui su4aa50c12015-11-10 12:09:59 -08002350
2351 if (ANGLE_FAST_SEARCH) {
2352 int deltas_level1[3] = {0, -2, 2};
2353 int deltas_level2[3][2] = {
2354 {-1, 1}, {-3, -1}, {1, 3},
2355 };
2356 const int level1 = 3, level2 = 2;
2357 int i, j, best_i = -1;
2358
2359 for (i = 0; i < level1; ++i) {
2360 mic->mbmi.angle_delta[0] = deltas_level1[i];
hui su3b1c7662016-01-12 16:38:58 -08002361 p_angle = mode_to_angle_map[mbmi->mode] +
2362 mbmi->angle_delta[0] * ANGLE_STEP;
2363 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
Yaowu Xu28eb7842016-03-07 16:23:26 -08002364 int64_t tmp_best_rd;
hui su5b618b72016-02-03 11:32:25 -08002365 if ((FILTER_FAST_SEARCH || !pick_intra_filter(p_angle)) &&
2366 filter != INTRA_FILTER_LINEAR)
hui su4aa50c12015-11-10 12:09:59 -08002367 continue;
hui su3b1c7662016-01-12 16:38:58 -08002368 mic->mbmi.intra_filter = filter;
Yaowu Xu28eb7842016-03-07 16:23:26 -08002369 tmp_best_rd = (i == 0 && filter == INTRA_FILTER_LINEAR &&
2370 best_rd < INT64_MAX) ? (int64_t)(best_rd * rd_adjust) : best_rd;
hui su4aa50c12015-11-10 12:09:59 -08002371 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
Yaowu Xu28eb7842016-03-07 16:23:26 -08002372 &s, NULL, bsize, tmp_best_rd);
hui su3b1c7662016-01-12 16:38:58 -08002373 if (this_rate_tokenonly == INT_MAX) {
2374 if (i == 0 && filter == INTRA_FILTER_LINEAR)
2375 return best_rd;
2376 else
2377 continue;
2378 }
2379 this_rate = this_rate_tokenonly + rate_overhead +
2380 cpi->intra_filter_cost[intra_filter_ctx][filter];
hui su4aa50c12015-11-10 12:09:59 -08002381 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui su3b1c7662016-01-12 16:38:58 -08002382 if (i == 0 && filter == INTRA_FILTER_LINEAR &&
2383 best_rd < INT64_MAX && this_rd > best_rd * rd_adjust)
2384 return best_rd;
hui su4aa50c12015-11-10 12:09:59 -08002385 if (this_rd < best_rd) {
hui su3b1c7662016-01-12 16:38:58 -08002386 best_i = i;
hui su4aa50c12015-11-10 12:09:59 -08002387 best_rd = this_rd;
2388 best_angle_delta = mbmi->angle_delta[0];
2389 best_tx_size = mbmi->tx_size;
hui su3b1c7662016-01-12 16:38:58 -08002390 best_filter = mbmi->intra_filter;
hui su4aa50c12015-11-10 12:09:59 -08002391 best_tx_type = mbmi->tx_type;
hui su4aa50c12015-11-10 12:09:59 -08002392 *rate = this_rate;
2393 *rate_tokenonly = this_rate_tokenonly;
2394 *distortion = this_distortion;
2395 *skippable = s;
2396 }
2397 }
2398 }
hui su3b1c7662016-01-12 16:38:58 -08002399
2400 if (best_i >= 0) {
2401 for (j = 0; j < level2; ++j) {
2402 mic->mbmi.angle_delta[0] = deltas_level2[best_i][j];
2403 p_angle = mode_to_angle_map[mbmi->mode] +
2404 mbmi->angle_delta[0] * ANGLE_STEP;
2405 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2406 mic->mbmi.intra_filter = filter;
hui su5b618b72016-02-03 11:32:25 -08002407 if ((FILTER_FAST_SEARCH || !pick_intra_filter(p_angle)) &&
2408 filter != INTRA_FILTER_LINEAR)
hui su3b1c7662016-01-12 16:38:58 -08002409 continue;
hui su5a7c8d82016-02-08 10:39:17 -08002410 pick_intra_angle_routine_sby(cpi, x, rate, rate_tokenonly,
2411 distortion, skippable,
2412 &best_angle_delta, &best_tx_size,
2413 &best_tx_type, &best_filter, bsize,
2414 rate_overhead +
2415 cpi->intra_filter_cost
2416 [intra_filter_ctx][filter],
2417 &best_rd);
hui su3b1c7662016-01-12 16:38:58 -08002418 }
2419 }
2420 }
hui su4aa50c12015-11-10 12:09:59 -08002421 } else {
2422 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
2423 ++angle_delta) {
hui su3b1c7662016-01-12 16:38:58 -08002424 mbmi->angle_delta[0] = angle_delta;
2425 p_angle = mode_to_angle_map[mbmi->mode] +
2426 mbmi->angle_delta[0] * ANGLE_STEP;
2427 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2428 mic->mbmi.intra_filter = filter;
hui su5b618b72016-02-03 11:32:25 -08002429 if ((FILTER_FAST_SEARCH || !pick_intra_filter(p_angle)) &&
2430 filter != INTRA_FILTER_LINEAR)
hui su3b1c7662016-01-12 16:38:58 -08002431 continue;
hui su5a7c8d82016-02-08 10:39:17 -08002432 pick_intra_angle_routine_sby(cpi, x, rate, rate_tokenonly,
2433 distortion, skippable,
2434 &best_angle_delta, &best_tx_size,
2435 &best_tx_type, &best_filter, bsize,
2436 rate_overhead +
2437 cpi->intra_filter_cost
2438 [intra_filter_ctx][filter],
2439 &best_rd);
hui su4aa50c12015-11-10 12:09:59 -08002440 }
2441 }
2442 }
2443
hui su5b618b72016-02-03 11:32:25 -08002444 if (FILTER_FAST_SEARCH && *rate_tokenonly < INT_MAX) {
2445 mbmi->angle_delta[0] = best_angle_delta;
2446 p_angle = mode_to_angle_map[mbmi->mode] +
2447 mbmi->angle_delta[0] * ANGLE_STEP;
2448 if (pick_intra_filter(p_angle)) {
2449 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
2450 mic->mbmi.intra_filter = filter;
hui su5a7c8d82016-02-08 10:39:17 -08002451 pick_intra_angle_routine_sby(cpi, x, rate, rate_tokenonly,
2452 distortion, skippable,
2453 &best_angle_delta, &best_tx_size,
2454 &best_tx_type, &best_filter, bsize,
2455 rate_overhead + cpi->intra_filter_cost
2456 [intra_filter_ctx][filter], &best_rd);
hui su5b618b72016-02-03 11:32:25 -08002457 }
2458 }
2459 }
2460
hui su4aa50c12015-11-10 12:09:59 -08002461 mbmi->tx_size = best_tx_size;
2462 mbmi->angle_delta[0] = best_angle_delta;
hui su3b1c7662016-01-12 16:38:58 -08002463 mic->mbmi.intra_filter = best_filter;
hui su4aa50c12015-11-10 12:09:59 -08002464 mbmi->tx_type = best_tx_type;
hui su4aa50c12015-11-10 12:09:59 -08002465
2466 if (*rate_tokenonly < INT_MAX) {
2467 txfm_rd_in_plane(x,
hui su4aa50c12015-11-10 12:09:59 -08002468 cpi,
hui su4aa50c12015-11-10 12:09:59 -08002469 &this_rate_tokenonly, &this_distortion, &s,
2470 &sse_dummy, INT64_MAX, 0, bsize, mbmi->tx_size,
2471 cpi->sf.use_fast_coef_costing);
2472 }
2473
2474 return best_rd;
2475}
hui sud7c8bc72015-11-12 19:18:32 -08002476
Yaowu Xu28eb7842016-03-07 16:23:26 -08002477static INLINE int get_angle_index(double angle) {
hui sud7c8bc72015-11-12 19:18:32 -08002478 const double step = 22.5, base = 45;
2479 return (int)round((angle - base) / step);
2480}
2481
2482static void angle_estimation(const uint8_t *src, int src_stride,
2483 int rows, int cols, double *hist) {
2484 int r, c, i, index;
2485 const double pi = 3.1415;
2486 double angle, dx, dy;
2487 double temp, divisor = 0;
2488
2489 for (i = 0; i < DIRECTIONAL_MODES; ++i)
2490 hist[i] = 0;
2491
2492 src += src_stride;
2493 for (r = 1; r < rows; ++r) {
2494 for (c = 1; c < cols; ++c) {
2495 dx = src[c] - src[c - 1];
2496 dy = src[c] - src[c - src_stride];
2497 temp = dx * dx + dy * dy;
2498 if (dy == 0)
2499 angle = 90;
2500 else
2501 angle = (atan((double)dx / (double)dy)) * 180 / pi;
2502 assert(angle >= -90 && angle <= 90);
2503 index = get_angle_index(angle + 180);
2504 if (index < DIRECTIONAL_MODES) {
2505 hist[index] += temp;
2506 divisor += temp;
2507 }
2508 if (angle > 0) {
2509 index = get_angle_index(angle);
2510 if (index >= 0) {
2511 hist[index] += temp;
2512 divisor += temp;
2513 }
2514 }
2515 }
2516 src += src_stride;
2517 }
2518
2519 if (divisor < 1)
2520 divisor = 1;
2521 for (i = 0; i < DIRECTIONAL_MODES; ++i)
2522 hist[i] /= divisor;
2523}
2524
2525#if CONFIG_VP9_HIGHBITDEPTH
2526static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
2527 int rows, int cols, double *hist) {
2528 int r, c, i, index;
2529 const double pi = 3.1415;
2530 double angle, dx, dy;
2531 double temp, divisor = 0;
2532 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
2533
2534 for (i = 0; i < DIRECTIONAL_MODES; ++i)
2535 hist[i] = 0;
2536
2537 src += src_stride;
2538 for (r = 1; r < rows; ++r) {
2539 for (c = 1; c < cols; ++c) {
2540 dx = src[c] - src[c - 1];
2541 dy = src[c] - src[c - src_stride];
2542 temp = dx * dx + dy * dy;
2543 if (dy == 0)
2544 angle = 90;
2545 else
2546 angle = (atan((double)dx / (double)dy)) * 180 / pi;
2547 assert(angle >= -90 && angle <= 90);
2548 index = get_angle_index(angle + 180);
2549 if (index < DIRECTIONAL_MODES) {
2550 hist[index] += temp;
2551 divisor += temp;
2552 }
2553 if (angle > 0) {
2554 index = get_angle_index(angle);
2555 if (index >= 0) {
2556 hist[index] += temp;
2557 divisor += temp;
2558 }
2559 }
2560 }
2561 src += src_stride;
2562 }
2563
2564 if (divisor < 1)
2565 divisor = 1;
2566 for (i = 0; i < DIRECTIONAL_MODES; ++i)
2567 hist[i] /= divisor;
2568}
2569#endif // CONFIG_VP9_HIGHBITDEPTH
hui sube3559b2015-10-07 09:29:02 -07002570#endif // CONFIG_EXT_INTRA
2571
Jingning Han3ee6db62015-08-05 19:00:31 -07002572// This function is used only for intra_only frames
Yaowu Xu26a9afc2015-08-13 09:42:27 -07002573static int64_t rd_pick_intra_sby_mode(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07002574 int *rate, int *rate_tokenonly,
2575 int64_t *distortion, int *skippable,
2576 BLOCK_SIZE bsize,
2577 int64_t best_rd) {
2578 PREDICTION_MODE mode;
2579 PREDICTION_MODE mode_selected = DC_PRED;
2580 MACROBLOCKD *const xd = &x->e_mbd;
2581 MODE_INFO *const mic = xd->mi[0];
2582 int this_rate, this_rate_tokenonly, s;
2583 int64_t this_distortion, this_rd;
2584 TX_SIZE best_tx = TX_4X4;
hui sube3559b2015-10-07 09:29:02 -07002585#if CONFIG_EXT_INTRA
hui su3b1c7662016-01-12 16:38:58 -08002586 const int intra_filter_ctx = vp10_get_pred_context_intra_interp(xd);
hui sube3559b2015-10-07 09:29:02 -07002587 EXT_INTRA_MODE_INFO ext_intra_mode_info;
hui su4aa50c12015-11-10 12:09:59 -08002588 int is_directional_mode, rate_overhead, best_angle_delta = 0;
hui su3b1c7662016-01-12 16:38:58 -08002589 INTRA_FILTER best_filter = INTRA_FILTER_LINEAR;
hui sud7c8bc72015-11-12 19:18:32 -08002590 uint8_t directional_mode_skip_mask[INTRA_MODES];
2591 const int src_stride = x->plane[0].src.stride;
2592 const uint8_t *src = x->plane[0].src.buf;
2593 double hist[DIRECTIONAL_MODES];
hui sube3559b2015-10-07 09:29:02 -07002594#endif // CONFIG_EXT_INTRA
hui su4f16f112015-10-02 10:45:27 -07002595 TX_TYPE best_tx_type = DCT_DCT;
Jingning Han3ee6db62015-08-05 19:00:31 -07002596 int *bmode_costs;
hui suc93e5cc2015-12-07 18:18:57 -08002597 PALETTE_MODE_INFO palette_mode_info;
hui su78b0bd02016-02-23 15:22:25 -08002598 PALETTE_MODE_INFO *const pmi = &mic->mbmi.palette_mode_info;
hui suc93e5cc2015-12-07 18:18:57 -08002599 uint8_t *best_palette_color_map = cpi->common.allow_screen_content_tools ?
2600 x->palette_buffer->best_palette_color_map : NULL;
2601 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
2602 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
2603 int palette_ctx = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07002604 const MODE_INFO *above_mi = xd->above_mi;
2605 const MODE_INFO *left_mi = xd->left_mi;
2606 const PREDICTION_MODE A = vp10_above_block_mode(mic, above_mi, 0);
2607 const PREDICTION_MODE L = vp10_left_block_mode(mic, left_mi, 0);
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08002608 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
Jingning Han3ee6db62015-08-05 19:00:31 -07002609 bmode_costs = cpi->y_mode_costs[A][L];
2610
hui sube3559b2015-10-07 09:29:02 -07002611#if CONFIG_EXT_INTRA
2612 ext_intra_mode_info.use_ext_intra_mode[0] = 0;
2613 mic->mbmi.ext_intra_mode_info.use_ext_intra_mode[0] = 0;
hui su4aa50c12015-11-10 12:09:59 -08002614 mic->mbmi.angle_delta[0] = 0;
hui sud7c8bc72015-11-12 19:18:32 -08002615 memset(directional_mode_skip_mask, 0,
2616 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
2617#if CONFIG_VP9_HIGHBITDEPTH
2618 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
2619 highbd_angle_estimation(src, src_stride, rows, cols, hist);
2620 else
2621#endif
2622 angle_estimation(src, src_stride, rows, cols, hist);
2623
2624 for (mode = 0; mode < INTRA_MODES; ++mode) {
2625 if (mode != DC_PRED && mode != TM_PRED) {
2626 int index = get_angle_index((double)mode_to_angle_map[mode]);
2627 double score, weight = 1.0;
2628 score = hist[index];
2629 if (index > 0) {
2630 score += hist[index - 1] * 0.5;
2631 weight += 0.5;
2632 }
2633 if (index < DIRECTIONAL_MODES - 1) {
2634 score += hist[index + 1] * 0.5;
2635 weight += 0.5;
2636 }
2637 score /= weight;
2638 if (score < ANGLE_SKIP_THRESH)
2639 directional_mode_skip_mask[mode] = 1;
2640 }
2641 }
hui sube3559b2015-10-07 09:29:02 -07002642#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07002643 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
hui suc93e5cc2015-12-07 18:18:57 -08002644 palette_mode_info.palette_size[0] = 0;
hui su78b0bd02016-02-23 15:22:25 -08002645 pmi->palette_size[0] = 0;
hui suc93e5cc2015-12-07 18:18:57 -08002646 if (above_mi)
2647 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
2648 if (left_mi)
2649 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
hui su5d011cb2015-09-15 12:44:13 -07002650
Jingning Han3ee6db62015-08-05 19:00:31 -07002651 /* Y Search for intra prediction mode */
hui sube3559b2015-10-07 09:29:02 -07002652 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
Jingning Han3ee6db62015-08-05 19:00:31 -07002653 mic->mbmi.mode = mode;
hui su4aa50c12015-11-10 12:09:59 -08002654#if CONFIG_EXT_INTRA
2655 is_directional_mode = (mode != DC_PRED && mode != TM_PRED);
hui sud7c8bc72015-11-12 19:18:32 -08002656 if (is_directional_mode && directional_mode_skip_mask[mode])
2657 continue;
hui su4aa50c12015-11-10 12:09:59 -08002658 if (is_directional_mode) {
hui sud7c8bc72015-11-12 19:18:32 -08002659 rate_overhead = bmode_costs[mode] +
2660 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
2661 this_rate_tokenonly = INT_MAX;
2662 this_rd =
2663 rd_pick_intra_angle_sby(cpi, x, &this_rate, &this_rate_tokenonly,
2664 &this_distortion, &s, bsize, rate_overhead,
2665 best_rd);
hui su4aa50c12015-11-10 12:09:59 -08002666 } else {
2667 mic->mbmi.angle_delta[0] = 0;
2668 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
2669 &s, NULL, bsize, best_rd);
2670 }
2671#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07002672 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
hui su4aa50c12015-11-10 12:09:59 -08002673 &s, NULL, bsize, best_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07002674
2675 if (this_rate_tokenonly == INT_MAX)
2676 continue;
2677
2678 this_rate = this_rate_tokenonly + bmode_costs[mode];
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08002679
2680 if (!xd->lossless[xd->mi[0]->mbmi.segment_id]) {
2681 // super_block_yrd above includes the cost of the tx_size in the
2682 // tokenonly rate, but for intra blocks, tx_size is always coded
2683 // (prediction granularity), so we account for it in the full rate,
2684 // not the tokenonly rate.
hui su954e5602016-03-07 15:25:50 -08002685 this_rate_tokenonly -=
2686 cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
2687 [mic->mbmi.tx_size];
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08002688 }
hui suc93e5cc2015-12-07 18:18:57 -08002689 if (cpi->common.allow_screen_content_tools && mode == DC_PRED)
2690 this_rate +=
2691 vp10_cost_bit(vp10_default_palette_y_mode_prob[bsize - BLOCK_8X8]
2692 [palette_ctx], 0);
hui sube3559b2015-10-07 09:29:02 -07002693#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08002694 if (mode == DC_PRED && ALLOW_FILTER_INTRA_MODES)
hui sube3559b2015-10-07 09:29:02 -07002695 this_rate += vp10_cost_bit(cpi->common.fc->ext_intra_probs[0], 0);
hui su3b1c7662016-01-12 16:38:58 -08002696 if (is_directional_mode) {
2697 int p_angle;
hui su4aa50c12015-11-10 12:09:59 -08002698 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
2699 MAX_ANGLE_DELTAS +
2700 mic->mbmi.angle_delta[0]);
hui su3b1c7662016-01-12 16:38:58 -08002701 p_angle = mode_to_angle_map[mic->mbmi.mode] +
2702 mic->mbmi.angle_delta[0] * ANGLE_STEP;
2703 if (pick_intra_filter(p_angle))
2704 this_rate +=
2705 cpi->intra_filter_cost[intra_filter_ctx][mic->mbmi.intra_filter];
2706 }
hui sube3559b2015-10-07 09:29:02 -07002707#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07002708 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
2709
2710 if (this_rd < best_rd) {
2711 mode_selected = mode;
2712 best_rd = this_rd;
2713 best_tx = mic->mbmi.tx_size;
hui su4aa50c12015-11-10 12:09:59 -08002714#if CONFIG_EXT_INTRA
2715 best_angle_delta = mic->mbmi.angle_delta[0];
hui su3b1c7662016-01-12 16:38:58 -08002716 best_filter = mic->mbmi.intra_filter;
hui su4aa50c12015-11-10 12:09:59 -08002717#endif // CONFIG_EXT_INTRA
hui su4f16f112015-10-02 10:45:27 -07002718 best_tx_type = mic->mbmi.tx_type;
Jingning Han3ee6db62015-08-05 19:00:31 -07002719 *rate = this_rate;
2720 *rate_tokenonly = this_rate_tokenonly;
2721 *distortion = this_distortion;
2722 *skippable = s;
2723 }
2724 }
2725
hui suc93e5cc2015-12-07 18:18:57 -08002726 if (cpi->common.allow_screen_content_tools)
2727 rd_pick_palette_intra_sby(cpi, x, bsize, palette_ctx, bmode_costs[DC_PRED],
2728 &palette_mode_info, best_palette_color_map,
2729 &best_tx, &mode_selected, &best_rd);
2730
hui sube3559b2015-10-07 09:29:02 -07002731#if CONFIG_EXT_INTRA
hui su78b0bd02016-02-23 15:22:25 -08002732 if (ALLOW_FILTER_INTRA_MODES) {
hui suc93e5cc2015-12-07 18:18:57 -08002733 if (rd_pick_ext_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
2734 skippable, bsize, bmode_costs[DC_PRED],
2735 &best_rd)) {
2736 mode_selected = mic->mbmi.mode;
2737 best_tx = mic->mbmi.tx_size;
2738 ext_intra_mode_info = mic->mbmi.ext_intra_mode_info;
hui suc93e5cc2015-12-07 18:18:57 -08002739 best_tx_type = mic->mbmi.tx_type;
hui suc93e5cc2015-12-07 18:18:57 -08002740 }
hui sube3559b2015-10-07 09:29:02 -07002741 }
2742
2743 mic->mbmi.ext_intra_mode_info.use_ext_intra_mode[0] =
2744 ext_intra_mode_info.use_ext_intra_mode[0];
2745 if (ext_intra_mode_info.use_ext_intra_mode[0]) {
2746 mic->mbmi.ext_intra_mode_info.ext_intra_mode[0] =
2747 ext_intra_mode_info.ext_intra_mode[0];
hui su78b0bd02016-02-23 15:22:25 -08002748 palette_mode_info.palette_size[0] = 0;
hui sube3559b2015-10-07 09:29:02 -07002749 }
2750#endif // CONFIG_EXT_INTRA
2751
Jingning Han3ee6db62015-08-05 19:00:31 -07002752 mic->mbmi.mode = mode_selected;
2753 mic->mbmi.tx_size = best_tx;
hui su4aa50c12015-11-10 12:09:59 -08002754#if CONFIG_EXT_INTRA
2755 mic->mbmi.angle_delta[0] = best_angle_delta;
hui su3b1c7662016-01-12 16:38:58 -08002756 mic->mbmi.intra_filter = best_filter;
hui su4aa50c12015-11-10 12:09:59 -08002757#endif // CONFIG_EXT_INTRA
hui su4f16f112015-10-02 10:45:27 -07002758 mic->mbmi.tx_type = best_tx_type;
hui su78b0bd02016-02-23 15:22:25 -08002759 pmi->palette_size[0] = palette_mode_info.palette_size[0];
hui suc93e5cc2015-12-07 18:18:57 -08002760 if (palette_mode_info.palette_size[0] > 0) {
hui su78b0bd02016-02-23 15:22:25 -08002761 memcpy(pmi->palette_colors, palette_mode_info.palette_colors,
hui suc93e5cc2015-12-07 18:18:57 -08002762 PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
2763 memcpy(xd->plane[0].color_index_map, best_palette_color_map,
2764 rows * cols * sizeof(best_palette_color_map[0]));
2765 }
Jingning Han3ee6db62015-08-05 19:00:31 -07002766
2767 return best_rd;
2768}
2769
Jingning Hana8dad552015-10-08 16:46:10 -07002770#if CONFIG_VAR_TX
Jingning Han4c6c82a2016-02-09 17:51:49 -08002771void vp10_tx_block_rd_b(const VP10_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
2772 int blk_row, int blk_col, int plane, int block,
2773 int plane_bsize, int coeff_ctx,
2774 int *rate, int64_t *dist, int64_t *bsse, int *skip) {
Jingning Han2cdc1272015-10-09 09:57:42 -07002775 MACROBLOCKD *xd = &x->e_mbd;
2776 const struct macroblock_plane *const p = &x->plane[plane];
2777 struct macroblockd_plane *const pd = &xd->plane[plane];
Yaowu Xu5c613ea2016-03-01 09:17:17 -08002778 int64_t tmp;
Jingning Han2cdc1272015-10-09 09:57:42 -07002779 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
2780 PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
2781 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
2782 const scan_order *const scan_order =
2783 get_scan(tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
2784
Jingning Han71c15602015-10-13 12:40:39 -07002785 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
2786 int bh = 4 * num_4x4_blocks_wide_lookup[txm_bsize];
2787 int src_stride = p->src.stride;
2788 uint8_t *src = &p->src.buf[4 * blk_row * src_stride + 4 * blk_col];
2789 uint8_t *dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
Peter de Rivaz22850492015-12-08 15:58:21 +00002790#if CONFIG_VP9_HIGHBITDEPTH
2791 DECLARE_ALIGNED(16, uint16_t, rec_buffer_alloc_16[32 * 32]);
2792 uint8_t *rec_buffer;
2793#else
Jingning Han71c15602015-10-13 12:40:39 -07002794 DECLARE_ALIGNED(16, uint8_t, rec_buffer[32 * 32]);
Geza Lore3c4b56c2016-02-16 09:54:29 +00002795#endif // CONFIG_VP9_HIGHBITDEPTH
Geza Loreabd00502016-02-12 16:04:35 +00002796 const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
2797 const int16_t *diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
Jingning Han71c15602015-10-13 12:40:39 -07002798
2799 int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
2800 int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
2801
2802 if (xd->mb_to_bottom_edge < 0)
2803 max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
2804 if (xd->mb_to_right_edge < 0)
2805 max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
2806
Angie Chiang88cae8b2015-11-25 13:07:13 -08002807 vp10_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
2808 VP10_XFORM_QUANT_B);
Jingning Han2cdc1272015-10-09 09:57:42 -07002809
Geza Lore3c4b56c2016-02-16 09:54:29 +00002810 // TODO(any): Use dist_block to compute distortion
Peter de Rivaz22850492015-12-08 15:58:21 +00002811#if CONFIG_VP9_HIGHBITDEPTH
2812 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2813 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer_alloc_16);
2814 vpx_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, 32,
2815 NULL, 0, NULL, 0, bh, bh, xd->bd);
2816 } else {
2817 rec_buffer = (uint8_t *)rec_buffer_alloc_16;
2818 vpx_convolve_copy(dst, pd->dst.stride, rec_buffer, 32,
2819 NULL, 0, NULL, 0, bh, bh);
2820 }
2821#else
Jingning Han71c15602015-10-13 12:40:39 -07002822 vpx_convolve_copy(dst, pd->dst.stride, rec_buffer, 32,
2823 NULL, 0, NULL, 0, bh, bh);
Geza Lore3c4b56c2016-02-16 09:54:29 +00002824#endif // CONFIG_VP9_HIGHBITDEPTH
Jingning Han71c15602015-10-13 12:40:39 -07002825
2826 if (blk_row + (bh >> 2) > max_blocks_high ||
2827 blk_col + (bh >> 2) > max_blocks_wide) {
2828 int idx, idy;
Jingning Han71c15602015-10-13 12:40:39 -07002829 int blocks_height = VPXMIN(bh >> 2, max_blocks_high - blk_row);
2830 int blocks_width = VPXMIN(bh >> 2, max_blocks_wide - blk_col);
Geza Lore3c4b56c2016-02-16 09:54:29 +00002831 tmp = 0;
Jingning Han71c15602015-10-13 12:40:39 -07002832 for (idy = 0; idy < blocks_height; idy += 2) {
2833 for (idx = 0; idx < blocks_width; idx += 2) {
Geza Loreabd00502016-02-12 16:04:35 +00002834 const int16_t *d = diff + 4 * idy * diff_stride + 4 * idx;
Geza Lore3c4b56c2016-02-16 09:54:29 +00002835 tmp += vpx_sum_squares_2d_i16(d, diff_stride, 8);
Jingning Han71c15602015-10-13 12:40:39 -07002836 }
2837 }
2838 } else {
Geza Lore3c4b56c2016-02-16 09:54:29 +00002839 tmp = vpx_sum_squares_2d_i16(diff, diff_stride, bh);
Jingning Han71c15602015-10-13 12:40:39 -07002840 }
2841
Geza Lore3c4b56c2016-02-16 09:54:29 +00002842#if CONFIG_VP9_HIGHBITDEPTH
Debargha Mukherjee389efb22016-02-24 11:25:20 -08002843 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
2844 tmp = ROUNDZ_POWER_OF_TWO(tmp, (xd->bd - 8) * 2);
Geza Lore3c4b56c2016-02-16 09:54:29 +00002845#endif // CONFIG_VP9_HIGHBITDEPTH
Yaowu Xu5c613ea2016-03-01 09:17:17 -08002846 *bsse += tmp * 16;
Jingning Han71c15602015-10-13 12:40:39 -07002847
2848 if (p->eobs[block] > 0) {
Geza Lore432e8752016-01-22 13:57:28 +00002849 const int lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
2850#if CONFIG_VP9_HIGHBITDEPTH
2851 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2852 const int bd = xd->bd;
2853 switch (tx_size) {
2854 case TX_32X32:
2855 vp10_highbd_inv_txfm_add_32x32(dqcoeff, rec_buffer, 32,
2856 p->eobs[block], bd, tx_type);
2857 break;
2858 case TX_16X16:
2859 vp10_highbd_inv_txfm_add_16x16(dqcoeff, rec_buffer, 32,
2860 p->eobs[block], bd, tx_type);
2861 break;
2862 case TX_8X8:
2863 vp10_highbd_inv_txfm_add_8x8(dqcoeff, rec_buffer, 32,
2864 p->eobs[block], bd, tx_type);
2865 break;
2866 case TX_4X4:
2867 vp10_highbd_inv_txfm_add_4x4(dqcoeff, rec_buffer, 32,
2868 p->eobs[block], bd, tx_type, lossless);
2869 break;
2870 default:
2871 assert(0 && "Invalid transform size");
2872 break;
2873 }
2874 } else {
2875#else
2876 {
2877#endif // CONFIG_VP9_HIGHBITDEPTH
2878 switch (tx_size) {
2879 case TX_32X32:
2880 vp10_inv_txfm_add_32x32(dqcoeff, rec_buffer, 32, p->eobs[block],
2881 tx_type);
2882 break;
2883 case TX_16X16:
2884 vp10_inv_txfm_add_16x16(dqcoeff, rec_buffer, 32, p->eobs[block],
2885 tx_type);
2886 break;
2887 case TX_8X8:
2888 vp10_inv_txfm_add_8x8(dqcoeff, rec_buffer, 32, p->eobs[block],
Jingning Han71c15602015-10-13 12:40:39 -07002889 tx_type);
Geza Lore432e8752016-01-22 13:57:28 +00002890 break;
2891 case TX_4X4:
2892 vp10_inv_txfm_add_4x4(dqcoeff, rec_buffer, 32, p->eobs[block],
2893 tx_type, lossless);
2894 break;
2895 default:
2896 assert(0 && "Invalid transform size");
2897 break;
2898 }
Jingning Han71c15602015-10-13 12:40:39 -07002899 }
2900
2901 if ((bh >> 2) + blk_col > max_blocks_wide ||
2902 (bh >> 2) + blk_row > max_blocks_high) {
2903 int idx, idy;
Geza Lore3c4b56c2016-02-16 09:54:29 +00002904 unsigned int this_dist;
Jingning Han71c15602015-10-13 12:40:39 -07002905 int blocks_height = VPXMIN(bh >> 2, max_blocks_high - blk_row);
2906 int blocks_width = VPXMIN(bh >> 2, max_blocks_wide - blk_col);
Geza Lore3c4b56c2016-02-16 09:54:29 +00002907 tmp = 0;
Jingning Han71c15602015-10-13 12:40:39 -07002908 for (idy = 0; idy < blocks_height; idy += 2) {
2909 for (idx = 0; idx < blocks_width; idx += 2) {
2910 cpi->fn_ptr[BLOCK_8X8].vf(src + 4 * idy * src_stride + 4 * idx,
2911 src_stride,
2912 rec_buffer + 4 * idy * 32 + 4 * idx,
Geza Lore3c4b56c2016-02-16 09:54:29 +00002913 32, &this_dist);
2914 tmp += this_dist;
Jingning Han71c15602015-10-13 12:40:39 -07002915 }
2916 }
2917 } else {
Yaowu Xu5c613ea2016-03-01 09:17:17 -08002918 uint32_t this_dist;
2919 cpi->fn_ptr[txm_bsize].vf(src, src_stride, rec_buffer, 32, &this_dist);
2920 tmp = this_dist;
Jingning Han71c15602015-10-13 12:40:39 -07002921 }
2922 }
Yaowu Xu5c613ea2016-03-01 09:17:17 -08002923 *dist += tmp * 16;
Jingning Han2cdc1272015-10-09 09:57:42 -07002924 *rate += cost_coeffs(x, plane, block, coeff_ctx, tx_size,
2925 scan_order->scan, scan_order->neighbors, 0);
2926 *skip &= (p->eobs[block] == 0);
2927}
2928
2929static void select_tx_block(const VP10_COMP *cpi, MACROBLOCK *x,
2930 int blk_row, int blk_col, int plane, int block,
2931 TX_SIZE tx_size, BLOCK_SIZE plane_bsize,
Jingning Han2cdc1272015-10-09 09:57:42 -07002932 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
Jingning Han3edad6e2015-10-14 09:38:17 -07002933 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
Jingning Han2cdc1272015-10-09 09:57:42 -07002934 int *rate, int64_t *dist,
Jingning Han1e48f742015-10-13 11:59:49 -07002935 int64_t *bsse, int *skip,
2936 int64_t ref_best_rd, int *is_cost_valid) {
Jingning Han2cdc1272015-10-09 09:57:42 -07002937 MACROBLOCKD *const xd = &x->e_mbd;
2938 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2939 struct macroblock_plane *const p = &x->plane[plane];
2940 struct macroblockd_plane *const pd = &xd->plane[plane];
2941 int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
2942 (blk_col >> (1 - pd->subsampling_x));
2943 int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
2944 int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
2945 int64_t this_rd = INT64_MAX;
Jingning Han2cdc1272015-10-09 09:57:42 -07002946 ENTROPY_CONTEXT *pta = ta + blk_col;
2947 ENTROPY_CONTEXT *ptl = tl + blk_row;
Jingning Han3a279612015-10-12 19:20:58 -07002948 ENTROPY_CONTEXT stxa = 0, stxl = 0;
Jingning Han2cdc1272015-10-09 09:57:42 -07002949 int coeff_ctx, i;
Jingning Han3edad6e2015-10-14 09:38:17 -07002950 int ctx = txfm_partition_context(tx_above + (blk_col >> 1),
2951 tx_left + (blk_row >> 1), tx_size);
2952
Jingning Han3a279612015-10-12 19:20:58 -07002953 int64_t sum_dist = 0, sum_bsse = 0;
2954 int64_t sum_rd = INT64_MAX;
Jingning Han3edad6e2015-10-14 09:38:17 -07002955 int sum_rate = vp10_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Jingning Han3a279612015-10-12 19:20:58 -07002956 int all_skip = 1;
Jingning Han1e48f742015-10-13 11:59:49 -07002957 int tmp_eob = 0;
Jingning Hanbfeac5e2015-10-15 23:11:30 -07002958 int zero_blk_rate;
Jingning Han1e48f742015-10-13 11:59:49 -07002959
2960 if (ref_best_rd < 0) {
2961 *is_cost_valid = 0;
2962 return;
2963 }
Jingning Han2cdc1272015-10-09 09:57:42 -07002964
2965 switch (tx_size) {
2966 case TX_4X4:
Jingning Han3a279612015-10-12 19:20:58 -07002967 stxa = pta[0];
2968 stxl = ptl[0];
Jingning Han2cdc1272015-10-09 09:57:42 -07002969 break;
2970 case TX_8X8:
Jingning Han3a279612015-10-12 19:20:58 -07002971 stxa = !!*(const uint16_t *)&pta[0];
2972 stxl = !!*(const uint16_t *)&ptl[0];
Jingning Han2cdc1272015-10-09 09:57:42 -07002973 break;
2974 case TX_16X16:
Jingning Han3a279612015-10-12 19:20:58 -07002975 stxa = !!*(const uint32_t *)&pta[0];
2976 stxl = !!*(const uint32_t *)&ptl[0];
Jingning Han2cdc1272015-10-09 09:57:42 -07002977 break;
2978 case TX_32X32:
Jingning Han3a279612015-10-12 19:20:58 -07002979 stxa = !!*(const uint64_t *)&pta[0];
2980 stxl = !!*(const uint64_t *)&ptl[0];
Jingning Han2cdc1272015-10-09 09:57:42 -07002981 break;
2982 default:
2983 assert(0 && "Invalid transform size.");
2984 break;
2985 }
Jingning Han3a279612015-10-12 19:20:58 -07002986 coeff_ctx = combine_entropy_contexts(stxa, stxl);
Jingning Han2cdc1272015-10-09 09:57:42 -07002987
2988 if (xd->mb_to_bottom_edge < 0)
2989 max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
2990 if (xd->mb_to_right_edge < 0)
2991 max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
2992
2993 *rate = 0;
2994 *dist = 0;
2995 *bsse = 0;
2996 *skip = 1;
2997
2998 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
2999 return;
3000
Jingning Hanbfeac5e2015-10-15 23:11:30 -07003001 zero_blk_rate =
3002 x->token_costs[tx_size][pd->plane_type][1][0][0][coeff_ctx][EOB_TOKEN];
3003
Jingning Han1e48f742015-10-13 11:59:49 -07003004 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
3005 mbmi->inter_tx_size[tx_idx] = tx_size;
Jingning Han4c6c82a2016-02-09 17:51:49 -08003006 vp10_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
3007 plane_bsize, coeff_ctx, rate, dist, bsse, skip);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07003008
Jingning Han47c7fd92015-10-30 13:00:48 -07003009 if ((RDCOST(x->rdmult, x->rddiv, *rate, *dist) >=
3010 RDCOST(x->rdmult, x->rddiv, zero_blk_rate, *bsse) || *skip == 1) &&
Jingning Hanbfeac5e2015-10-15 23:11:30 -07003011 !xd->lossless[mbmi->segment_id]) {
3012 *rate = zero_blk_rate;
3013 *dist = *bsse;
3014 *skip = 1;
3015 x->blk_skip[plane][blk_row * max_blocks_wide + blk_col] = 1;
3016 p->eobs[block] = 0;
3017 } else {
3018 x->blk_skip[plane][blk_row * max_blocks_wide + blk_col] = 0;
3019 *skip = 0;
3020 }
3021
Jingning Han1e48f742015-10-13 11:59:49 -07003022 if (tx_size > TX_4X4)
Jingning Han3edad6e2015-10-14 09:38:17 -07003023 *rate += vp10_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
Jingning Han1e48f742015-10-13 11:59:49 -07003024 this_rd = RDCOST(x->rdmult, x->rddiv, *rate, *dist);
3025 tmp_eob = p->eobs[block];
3026 }
3027
Jingning Han2cdc1272015-10-09 09:57:42 -07003028 if (tx_size > TX_4X4) {
3029 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
Jingning Han3a279612015-10-12 19:20:58 -07003030 int bsl = b_height_log2_lookup[bsize];
Jingning Han2cdc1272015-10-09 09:57:42 -07003031 int sub_step = 1 << (2 * (tx_size - 1));
3032 int i;
Jingning Han3a279612015-10-12 19:20:58 -07003033 int this_rate;
3034 int64_t this_dist;
3035 int64_t this_bsse;
3036 int this_skip;
Jingning Han1e48f742015-10-13 11:59:49 -07003037 int this_cost_valid = 1;
3038 int64_t tmp_rd = 0;
Jingning Han3a279612015-10-12 19:20:58 -07003039
3040 --bsl;
Jingning Han236623c2015-10-26 19:39:30 -07003041 for (i = 0; i < 4 && this_cost_valid; ++i) {
Jingning Han3a279612015-10-12 19:20:58 -07003042 int offsetr = (i >> 1) << bsl;
3043 int offsetc = (i & 0x01) << bsl;
Jingning Han2cdc1272015-10-09 09:57:42 -07003044 select_tx_block(cpi, x, blk_row + offsetr, blk_col + offsetc,
3045 plane, block + i * sub_step, tx_size - 1,
Jingning Han3edad6e2015-10-14 09:38:17 -07003046 plane_bsize, ta, tl, tx_above, tx_left,
3047 &this_rate, &this_dist,
Jingning Han1e48f742015-10-13 11:59:49 -07003048 &this_bsse, &this_skip,
3049 ref_best_rd - tmp_rd, &this_cost_valid);
Jingning Han2cdc1272015-10-09 09:57:42 -07003050 sum_rate += this_rate;
3051 sum_dist += this_dist;
3052 sum_bsse += this_bsse;
3053 all_skip &= this_skip;
Peter de Rivaz2f943132016-01-05 15:35:43 +00003054 tmp_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
Jingning Han1e48f742015-10-13 11:59:49 -07003055 if (this_rd < tmp_rd)
3056 break;
Jingning Han2cdc1272015-10-09 09:57:42 -07003057 }
Jingning Han1e48f742015-10-13 11:59:49 -07003058 if (this_cost_valid)
3059 sum_rd = tmp_rd;
Jingning Han3a279612015-10-12 19:20:58 -07003060 }
3061
3062 if (this_rd < sum_rd) {
Jingning Han79fe7242015-10-23 14:27:21 -07003063 int idx, idy;
Jingning Han3a279612015-10-12 19:20:58 -07003064 for (i = 0; i < (1 << tx_size); ++i)
Jingning Han1e48f742015-10-13 11:59:49 -07003065 pta[i] = ptl[i] = !(tmp_eob == 0);
Jingning Han3edad6e2015-10-14 09:38:17 -07003066 txfm_partition_update(tx_above + (blk_col >> 1),
3067 tx_left + (blk_row >> 1), tx_size);
Jingning Han1e48f742015-10-13 11:59:49 -07003068 mbmi->inter_tx_size[tx_idx] = tx_size;
Jingning Han79fe7242015-10-23 14:27:21 -07003069
3070 for (idy = 0; idy < (1 << tx_size) / 2; ++idy)
3071 for (idx = 0; idx < (1 << tx_size) / 2; ++idx)
3072 mbmi->inter_tx_size[tx_idx + (idy << 3) + idx] = tx_size;
Jingning Han3a279612015-10-12 19:20:58 -07003073 mbmi->tx_size = tx_size;
Jingning Han236623c2015-10-26 19:39:30 -07003074 if (this_rd == INT64_MAX)
3075 *is_cost_valid = 0;
Jingning Hanbfeac5e2015-10-15 23:11:30 -07003076 x->blk_skip[plane][blk_row * max_blocks_wide + blk_col] = *skip;
Jingning Han3a279612015-10-12 19:20:58 -07003077 } else {
3078 *rate = sum_rate;
3079 *dist = sum_dist;
3080 *bsse = sum_bsse;
3081 *skip = all_skip;
Jingning Han236623c2015-10-26 19:39:30 -07003082 if (sum_rd == INT64_MAX)
3083 *is_cost_valid = 0;
Jingning Han2cdc1272015-10-09 09:57:42 -07003084 }
3085}
3086
3087static void inter_block_yrd(const VP10_COMP *cpi, MACROBLOCK *x,
3088 int *rate, int64_t *distortion, int *skippable,
3089 int64_t *sse, BLOCK_SIZE bsize,
3090 int64_t ref_best_rd) {
3091 MACROBLOCKD *const xd = &x->e_mbd;
3092 int is_cost_valid = 1;
Jingning Han1e48f742015-10-13 11:59:49 -07003093 int64_t this_rd = 0;
Jingning Han2cdc1272015-10-09 09:57:42 -07003094
3095 if (ref_best_rd < 0)
3096 is_cost_valid = 0;
3097
3098 *rate = 0;
3099 *distortion = 0;
3100 *sse = 0;
3101 *skippable = 1;
3102
3103 if (is_cost_valid) {
3104 const struct macroblockd_plane *const pd = &xd->plane[0];
3105 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
3106 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
3107 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
3108 BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[plane_bsize]];
3109 int bh = num_4x4_blocks_wide_lookup[txb_size];
3110 int idx, idy;
3111 int block = 0;
3112 int step = 1 << (max_txsize_lookup[plane_bsize] * 2);
3113 ENTROPY_CONTEXT ctxa[16], ctxl[16];
Jingning Han3edad6e2015-10-14 09:38:17 -07003114 TXFM_CONTEXT tx_above[8], tx_left[8];
Jingning Han2cdc1272015-10-09 09:57:42 -07003115
3116 int pnrate = 0, pnskip = 1;
3117 int64_t pndist = 0, pnsse = 0;
3118
3119 vp10_get_entropy_contexts(bsize, TX_4X4, pd, ctxa, ctxl);
Jingning Han3edad6e2015-10-14 09:38:17 -07003120 memcpy(tx_above, xd->above_txfm_context,
3121 sizeof(TXFM_CONTEXT) * (mi_width >> 1));
3122 memcpy(tx_left, xd->left_txfm_context,
3123 sizeof(TXFM_CONTEXT) * (mi_height >> 1));
Jingning Han2cdc1272015-10-09 09:57:42 -07003124
3125 for (idy = 0; idy < mi_height; idy += bh) {
3126 for (idx = 0; idx < mi_width; idx += bh) {
3127 select_tx_block(cpi, x, idy, idx, 0, block,
Jingning Han3a279612015-10-12 19:20:58 -07003128 max_txsize_lookup[plane_bsize], plane_bsize,
Jingning Han3edad6e2015-10-14 09:38:17 -07003129 ctxa, ctxl, tx_above, tx_left,
3130 &pnrate, &pndist, &pnsse, &pnskip,
Jingning Han1e48f742015-10-13 11:59:49 -07003131 ref_best_rd - this_rd, &is_cost_valid);
Jingning Han2cdc1272015-10-09 09:57:42 -07003132 *rate += pnrate;
3133 *distortion += pndist;
3134 *sse += pnsse;
3135 *skippable &= pnskip;
Jingning Han1e48f742015-10-13 11:59:49 -07003136 this_rd += VPXMIN(RDCOST(x->rdmult, x->rddiv, pnrate, pndist),
3137 RDCOST(x->rdmult, x->rddiv, 0, pnsse));
Jingning Han2cdc1272015-10-09 09:57:42 -07003138 block += step;
3139 }
3140 }
3141 }
3142
3143 this_rd = VPXMIN(RDCOST(x->rdmult, x->rddiv, *rate, *distortion),
3144 RDCOST(x->rdmult, x->rddiv, 0, *sse));
3145 if (this_rd > ref_best_rd)
3146 is_cost_valid = 0;
3147
3148 if (!is_cost_valid) {
3149 // reset cost value
3150 *rate = INT_MAX;
3151 *distortion = INT64_MAX;
3152 *sse = INT64_MAX;
3153 *skippable = 0;
3154 }
3155}
3156
Jingning Han4b594d32015-11-02 12:05:47 -08003157static void select_tx_type_yrd(const VP10_COMP *cpi, MACROBLOCK *x,
3158 int *rate, int64_t *distortion, int *skippable,
3159 int64_t *sse, BLOCK_SIZE bsize,
3160 int64_t ref_best_rd) {
3161 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
3162 const VP10_COMMON *const cm = &cpi->common;
3163 MACROBLOCKD *const xd = &x->e_mbd;
3164 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3165 int64_t rd = INT64_MAX;
3166 int64_t best_rd = INT64_MAX;
3167 TX_TYPE tx_type, best_tx_type = DCT_DCT;
Jingning Han4b594d32015-11-02 12:05:47 -08003168 const int is_inter = is_inter_block(mbmi);
3169 vpx_prob skip_prob = vp10_get_skip_prob(cm, xd);
3170 int s0 = vp10_cost_bit(skip_prob, 0);
3171 int s1 = vp10_cost_bit(skip_prob, 1);
Jingning Han696ee002015-11-03 08:56:47 -08003172 TX_SIZE best_tx_size[64];
Jingning Han493d0232015-11-03 12:59:24 -08003173 TX_SIZE best_tx = TX_SIZES;
3174 uint8_t best_blk_skip[256];
3175 const int n4 = 1 << (num_pels_log2_lookup[bsize] - 4);
Jingning Han696ee002015-11-03 08:56:47 -08003176 int idx, idy;
Sarah Parker2ca7d422016-03-01 10:12:13 -08003177 int prune = 0;
Julia Robson9fe188e2016-01-21 17:14:29 +00003178#if CONFIG_EXT_TX
3179 int ext_tx_set = get_ext_tx_set(max_tx_size, bsize, is_inter);
Sarah Parker2ca7d422016-03-01 10:12:13 -08003180#endif // CONFIG_EXT_TX
3181
3182 if (is_inter && cpi->sf.tx_type_search > 0)
3183 prune = prune_tx_types(cpi, bsize, x, xd);
Jingning Han4b594d32015-11-02 12:05:47 -08003184
3185 *distortion = INT64_MAX;
3186 *rate = INT_MAX;
3187 *skippable = 0;
3188 *sse = INT64_MAX;
3189
3190 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
3191 int this_rate = 0;
3192 int this_skip = 1;
3193 int64_t this_dist = 0;
3194 int64_t this_sse = 0;
Julia Robson9fe188e2016-01-21 17:14:29 +00003195#if CONFIG_EXT_TX
Jingning Han4b594d32015-11-02 12:05:47 -08003196 if (is_inter) {
3197 if (!ext_tx_used_inter[ext_tx_set][tx_type])
3198 continue;
Sarah Parker2ca7d422016-03-01 10:12:13 -08003199 if (cpi->sf.tx_type_search > 0) {
3200 if (!do_tx_type_search(tx_type, prune))
3201 continue;
3202 } else if (ext_tx_set == 1 &&
3203 tx_type >= DST_ADST && tx_type < IDTX &&
3204 best_tx_type == DCT_DCT) {
3205 tx_type = IDTX - 1;
3206 continue;
3207 }
Jingning Han4b594d32015-11-02 12:05:47 -08003208 } else {
hui sud894d342015-11-18 11:24:26 -08003209 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
Yaowu Xu0367f322016-01-11 10:27:35 -08003210 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode])
hui sud894d342015-11-18 11:24:26 -08003211 continue;
3212 }
Jingning Han4b594d32015-11-02 12:05:47 -08003213 if (!ext_tx_used_intra[ext_tx_set][tx_type])
3214 continue;
Sarah Parker2ca7d422016-03-01 10:12:13 -08003215 if (ext_tx_set == 1 &&
3216 tx_type >= DST_ADST && tx_type < IDTX &&
3217 best_tx_type == DCT_DCT) {
3218 tx_type = IDTX - 1;
3219 break;
3220 }
Jingning Han4b594d32015-11-02 12:05:47 -08003221 }
3222
3223 mbmi->tx_type = tx_type;
3224
Jingning Han4b594d32015-11-02 12:05:47 -08003225 inter_block_yrd(cpi, x, &this_rate, &this_dist, &this_skip, &this_sse,
3226 bsize, ref_best_rd);
3227
3228 if (get_ext_tx_types(max_tx_size, bsize, is_inter) > 1 &&
3229 !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
3230 this_rate != INT_MAX) {
3231 if (is_inter) {
3232 if (ext_tx_set > 0)
3233 this_rate += cpi->inter_tx_type_costs[ext_tx_set]
Jingning Han696ee002015-11-03 08:56:47 -08003234 [max_tx_size][mbmi->tx_type];
Jingning Han4b594d32015-11-02 12:05:47 -08003235 } else {
hui sud894d342015-11-18 11:24:26 -08003236 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Jingning Han696ee002015-11-03 08:56:47 -08003237 this_rate += cpi->intra_tx_type_costs[ext_tx_set][max_tx_size]
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08003238 [mbmi->mode][mbmi->tx_type];
Jingning Han4b594d32015-11-02 12:05:47 -08003239 }
3240 }
Julia Robson9fe188e2016-01-21 17:14:29 +00003241#else // CONFIG_EXT_TX
Jingning Han5c772f32016-02-10 11:33:37 -08003242 if (max_tx_size >= TX_32X32 && tx_type != DCT_DCT)
Julia Robson9fe188e2016-01-21 17:14:29 +00003243 continue;
Jingning Han5c772f32016-02-10 11:33:37 -08003244
Julia Robson9fe188e2016-01-21 17:14:29 +00003245 mbmi->tx_type = tx_type;
3246
3247 inter_block_yrd(cpi, x, &this_rate, &this_dist, &this_skip, &this_sse,
3248 bsize, ref_best_rd);
3249
3250 if (max_tx_size < TX_32X32 &&
3251 !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
3252 this_rate != INT_MAX) {
Sarah Parker2ca7d422016-03-01 10:12:13 -08003253 if (is_inter) {
Julia Robson9fe188e2016-01-21 17:14:29 +00003254 this_rate += cpi->inter_tx_type_costs[max_tx_size][mbmi->tx_type];
Sarah Parker2ca7d422016-03-01 10:12:13 -08003255 if (cpi->sf.tx_type_search > 0 && !do_tx_type_search(tx_type, prune))
3256 continue;
3257 } else {
Julia Robson9fe188e2016-01-21 17:14:29 +00003258 this_rate += cpi->intra_tx_type_costs[max_tx_size]
3259 [intra_mode_to_tx_type_context[mbmi->mode]]
3260 [mbmi->tx_type];
Sarah Parker2ca7d422016-03-01 10:12:13 -08003261 }
Julia Robson9fe188e2016-01-21 17:14:29 +00003262 }
3263#endif // CONFIG_EXT_TX
Jingning Han4b594d32015-11-02 12:05:47 -08003264
3265 if (this_rate == INT_MAX)
3266 continue;
3267
3268 if (this_skip)
3269 rd = RDCOST(x->rdmult, x->rddiv, s1, this_sse);
3270 else
3271 rd = RDCOST(x->rdmult, x->rddiv, this_rate + s0, this_dist);
3272
3273 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] && !this_skip)
3274 rd = VPXMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, this_sse));
3275
Jingning Han5c772f32016-02-10 11:33:37 -08003276 if (rd < (is_inter && best_tx_type == DCT_DCT ? ext_tx_th : 1) * best_rd) {
Jingning Han4b594d32015-11-02 12:05:47 -08003277 best_rd = rd;
3278 *distortion = this_dist;
3279 *rate = this_rate;
3280 *skippable = this_skip;
3281 *sse = this_sse;
3282 best_tx_type = mbmi->tx_type;
Jingning Han493d0232015-11-03 12:59:24 -08003283 best_tx = mbmi->tx_size;
3284 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
Jingning Han696ee002015-11-03 08:56:47 -08003285 for (idy = 0; idy < xd->n8_h; ++idy)
3286 for (idx = 0; idx < xd->n8_w; ++idx)
3287 best_tx_size[idy * 8 + idx] = mbmi->inter_tx_size[idy * 8 + idx];
Jingning Han4b594d32015-11-02 12:05:47 -08003288 }
3289 }
3290
3291 mbmi->tx_type = best_tx_type;
Jingning Han696ee002015-11-03 08:56:47 -08003292 for (idy = 0; idy < xd->n8_h; ++idy)
3293 for (idx = 0; idx < xd->n8_w; ++idx)
3294 mbmi->inter_tx_size[idy * 8 + idx] = best_tx_size[idy * 8 + idx];
Jingning Han493d0232015-11-03 12:59:24 -08003295 mbmi->tx_size = best_tx;
3296 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
Jingning Han4b594d32015-11-02 12:05:47 -08003297}
Jingning Han4b594d32015-11-02 12:05:47 -08003298
Jingning Hana8dad552015-10-08 16:46:10 -07003299static void tx_block_rd(const VP10_COMP *cpi, MACROBLOCK *x,
3300 int blk_row, int blk_col, int plane, int block,
3301 TX_SIZE tx_size, BLOCK_SIZE plane_bsize,
3302 ENTROPY_CONTEXT *above_ctx, ENTROPY_CONTEXT *left_ctx,
3303 int *rate, int64_t *dist, int64_t *bsse, int *skip) {
3304 MACROBLOCKD *const xd = &x->e_mbd;
3305 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Jingning Han2cdc1272015-10-09 09:57:42 -07003306 struct macroblock_plane *const p = &x->plane[plane];
Jingning Hana8dad552015-10-08 16:46:10 -07003307 struct macroblockd_plane *const pd = &xd->plane[plane];
Jingning Han2cdc1272015-10-09 09:57:42 -07003308 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
Jingning Hana8dad552015-10-08 16:46:10 -07003309 int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
3310 (blk_col >> (1 - pd->subsampling_x));
3311 TX_SIZE plane_tx_size = plane ?
Jingning Han2cdc1272015-10-09 09:57:42 -07003312 get_uv_tx_size_impl(mbmi->inter_tx_size[tx_idx], bsize,
3313 0, 0) :
Jingning Hana8dad552015-10-08 16:46:10 -07003314 mbmi->inter_tx_size[tx_idx];
3315
3316 int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
3317 int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
3318
3319 if (xd->mb_to_bottom_edge < 0)
3320 max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
3321 if (xd->mb_to_right_edge < 0)
3322 max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
3323
3324 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
3325 return;
3326
3327 if (tx_size == plane_tx_size) {
Jingning Han2cdc1272015-10-09 09:57:42 -07003328 int coeff_ctx, i;
Jingning Hana8dad552015-10-08 16:46:10 -07003329 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
Jingning Han2cdc1272015-10-09 09:57:42 -07003330 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
Jingning Hana8dad552015-10-08 16:46:10 -07003331 switch (tx_size) {
3332 case TX_4X4:
3333 break;
3334 case TX_8X8:
3335 ta[0] = !!*(const uint16_t *)&ta[0];
3336 tl[0] = !!*(const uint16_t *)&tl[0];
3337 break;
3338 case TX_16X16:
3339 ta[0] = !!*(const uint32_t *)&ta[0];
3340 tl[0] = !!*(const uint32_t *)&tl[0];
3341 break;
3342 case TX_32X32:
3343 ta[0] = !!*(const uint64_t *)&ta[0];
3344 tl[0] = !!*(const uint64_t *)&tl[0];
3345 break;
3346 default:
3347 assert(0 && "Invalid transform size.");
3348 break;
3349 }
Jingning Han2cdc1272015-10-09 09:57:42 -07003350 coeff_ctx = combine_entropy_contexts(ta[0], tl[0]);
Jingning Han4c6c82a2016-02-09 17:51:49 -08003351 vp10_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
3352 plane_bsize, coeff_ctx, rate, dist, bsse, skip);
Jingning Hana8dad552015-10-08 16:46:10 -07003353 for (i = 0; i < (1 << tx_size); ++i) {
Jingning Han2cdc1272015-10-09 09:57:42 -07003354 ta[i] = !(p->eobs[block] == 0);
3355 tl[i] = !(p->eobs[block] == 0);
Jingning Hana8dad552015-10-08 16:46:10 -07003356 }
Jingning Hana8dad552015-10-08 16:46:10 -07003357 } else {
Jingning Hana8dad552015-10-08 16:46:10 -07003358 int bsl = b_width_log2_lookup[bsize];
3359 int step = 1 << (2 * (tx_size - 1));
3360 int i;
3361
3362 assert(bsl > 0);
3363 --bsl;
3364
3365 for (i = 0; i < 4; ++i) {
3366 int offsetr = (i >> 1) << bsl;
3367 int offsetc = (i & 0x01) << bsl;
3368 tx_block_rd(cpi, x, blk_row + offsetr, blk_col + offsetc, plane,
3369 block + i * step, tx_size - 1, plane_bsize,
3370 above_ctx, left_ctx, rate, dist, bsse, skip);
3371 }
3372 }
3373}
3374
3375// Return value 0: early termination triggered, no valid rd cost available;
3376// 1: rd cost values are valid.
3377static int inter_block_uvrd(const VP10_COMP *cpi, MACROBLOCK *x,
3378 int *rate, int64_t *distortion, int *skippable,
3379 int64_t *sse, BLOCK_SIZE bsize,
3380 int64_t ref_best_rd) {
3381 MACROBLOCKD *const xd = &x->e_mbd;
3382 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3383 int plane;
3384 int is_cost_valid = 1;
3385 int64_t this_rd;
3386
3387 if (ref_best_rd < 0)
3388 is_cost_valid = 0;
3389
3390 if (is_inter_block(mbmi) && is_cost_valid) {
3391 int plane;
3392 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
3393 vp10_subtract_plane(x, bsize, plane);
3394 }
3395
3396 *rate = 0;
3397 *distortion = 0;
3398 *sse = 0;
3399 *skippable = 1;
3400
3401 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
3402 const struct macroblockd_plane *const pd = &xd->plane[plane];
3403 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
3404 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
3405 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
3406 BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[plane_bsize]];
3407 int bh = num_4x4_blocks_wide_lookup[txb_size];
3408 int idx, idy;
3409 int block = 0;
3410 int step = 1 << (max_txsize_lookup[plane_bsize] * 2);
3411 int pnrate = 0, pnskip = 1;
3412 int64_t pndist = 0, pnsse = 0;
3413 ENTROPY_CONTEXT ta[16], tl[16];
3414
3415 vp10_get_entropy_contexts(bsize, TX_4X4, pd, ta, tl);
3416
3417 for (idy = 0; idy < mi_height; idy += bh) {
3418 for (idx = 0; idx < mi_width; idx += bh) {
3419 tx_block_rd(cpi, x, idy, idx, plane, block,
3420 max_txsize_lookup[plane_bsize], plane_bsize, ta, tl,
3421 &pnrate, &pndist, &pnsse, &pnskip);
3422 block += step;
3423 }
3424 }
3425
3426 if (pnrate == INT_MAX) {
3427 is_cost_valid = 0;
3428 break;
3429 }
3430
3431 *rate += pnrate;
3432 *distortion += pndist;
3433 *sse += pnsse;
3434 *skippable &= pnskip;
3435
3436 this_rd = VPXMIN(RDCOST(x->rdmult, x->rddiv, *rate, *distortion),
3437 RDCOST(x->rdmult, x->rddiv, 0, *sse));
3438
3439 if (this_rd > ref_best_rd) {
3440 is_cost_valid = 0;
3441 break;
3442 }
3443 }
3444
3445 if (!is_cost_valid) {
3446 // reset cost value
3447 *rate = INT_MAX;
3448 *distortion = INT64_MAX;
3449 *sse = INT64_MAX;
3450 *skippable = 0;
3451 }
3452
3453 return is_cost_valid;
3454}
3455#endif
3456
Jingning Han3ee6db62015-08-05 19:00:31 -07003457// Return value 0: early termination triggered, no valid rd cost available;
3458// 1: rd cost values are valid.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003459static int super_block_uvrd(const VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003460 int *rate, int64_t *distortion, int *skippable,
3461 int64_t *sse, BLOCK_SIZE bsize,
3462 int64_t ref_best_rd) {
3463 MACROBLOCKD *const xd = &x->e_mbd;
3464 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3465 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
3466 int plane;
3467 int pnrate = 0, pnskip = 1;
3468 int64_t pndist = 0, pnsse = 0;
3469 int is_cost_valid = 1;
3470
3471 if (ref_best_rd < 0)
3472 is_cost_valid = 0;
3473
3474 if (is_inter_block(mbmi) && is_cost_valid) {
3475 int plane;
3476 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
3477 vp10_subtract_plane(x, bsize, plane);
3478 }
3479
3480 *rate = 0;
3481 *distortion = 0;
3482 *sse = 0;
3483 *skippable = 1;
3484
3485 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
Jingning Han71c15602015-10-13 12:40:39 -07003486 txfm_rd_in_plane(x,
Jingning Han71c15602015-10-13 12:40:39 -07003487 cpi,
Jingning Han71c15602015-10-13 12:40:39 -07003488 &pnrate, &pndist, &pnskip, &pnsse,
Jingning Han3ee6db62015-08-05 19:00:31 -07003489 ref_best_rd, plane, bsize, uv_tx_size,
3490 cpi->sf.use_fast_coef_costing);
3491 if (pnrate == INT_MAX) {
3492 is_cost_valid = 0;
3493 break;
3494 }
3495 *rate += pnrate;
3496 *distortion += pndist;
3497 *sse += pnsse;
3498 *skippable &= pnskip;
hui su30d2d972016-03-17 11:20:59 -07003499 if (RDCOST(x->rdmult, x->rddiv, *rate, *distortion) > ref_best_rd &&
3500 RDCOST(x->rdmult, x->rddiv, 0, *sse) > ref_best_rd) {
3501 is_cost_valid = 0;
3502 break;
3503 }
Jingning Han3ee6db62015-08-05 19:00:31 -07003504 }
3505
3506 if (!is_cost_valid) {
3507 // reset cost value
3508 *rate = INT_MAX;
3509 *distortion = INT64_MAX;
3510 *sse = INT64_MAX;
3511 *skippable = 0;
3512 }
3513
3514 return is_cost_valid;
3515}
3516
hui su78b0bd02016-02-23 15:22:25 -08003517static void rd_pick_palette_intra_sbuv(VP10_COMP *cpi, MACROBLOCK *x,
3518 PICK_MODE_CONTEXT *ctx, int dc_mode_cost,
3519 PALETTE_MODE_INFO *palette_mode_info,
3520 uint8_t *best_palette_color_map,
3521 PREDICTION_MODE *mode_selected,
3522 int64_t *best_rd, int *rate,
3523 int *rate_tokenonly,
3524 int64_t *distortion, int *skippable) {
3525 MACROBLOCKD *const xd = &x->e_mbd;
3526 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3527 const BLOCK_SIZE bsize = mbmi->sb_type;
3528 const int rows = (4 * num_4x4_blocks_high_lookup[bsize]) >>
3529 (xd->plane[1].subsampling_y);
3530 const int cols = (4 * num_4x4_blocks_wide_lookup[bsize]) >>
3531 (xd->plane[1].subsampling_x);
3532 int this_rate, this_rate_tokenonly, s;
3533 int64_t this_distortion, this_rd;
3534 int colors_u, colors_v, colors;
3535 const int src_stride = x->plane[1].src.stride;
3536 const uint8_t *const src_u = x->plane[1].src.buf;
3537 const uint8_t *const src_v = x->plane[2].src.buf;
3538
3539#if CONFIG_EXT_INTRA
3540 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
3541#endif // CONFIG_EXT_INTRA
3542
3543#if CONFIG_VP9_HIGHBITDEPTH
3544 if (cpi->common.use_highbitdepth) {
3545 colors_u = vp10_count_colors_highbd(src_u, src_stride, rows, cols,
3546 cpi->common.bit_depth);
3547 colors_v = vp10_count_colors_highbd(src_v, src_stride, rows, cols,
3548 cpi->common.bit_depth);
3549 } else {
3550#endif // CONFIG_VP9_HIGHBITDEPTH
3551 colors_u = vp10_count_colors(src_u, src_stride, rows, cols);
3552 colors_v = vp10_count_colors(src_v, src_stride, rows, cols);
3553#if CONFIG_VP9_HIGHBITDEPTH
3554 }
3555#endif // CONFIG_VP9_HIGHBITDEPTH
3556
3557 colors = colors_u > colors_v ? colors_u : colors_v;
3558 if (colors > 1 && colors <= 64) {
3559 int r, c, n, i, j;
3560 const int max_itr = 50;
3561 int color_ctx, color_idx = 0;
3562 int color_order[PALETTE_MAX_SIZE];
3563 int64_t this_sse;
3564 double lb_u, ub_u, val_u;
3565 double lb_v, ub_v, val_v;
3566 double *const data = x->palette_buffer->kmeans_data_buf;
3567 uint8_t *const indices = x->palette_buffer->kmeans_indices_buf;
3568 uint8_t *const pre_indices = x->palette_buffer->kmeans_pre_indices_buf;
3569 double centroids[2 * PALETTE_MAX_SIZE];
3570 uint8_t *const color_map = xd->plane[1].color_index_map;
3571 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
3572
3573#if CONFIG_VP9_HIGHBITDEPTH
3574 uint16_t *src_u16 = CONVERT_TO_SHORTPTR(src_u);
3575 uint16_t *src_v16 = CONVERT_TO_SHORTPTR(src_v);
3576 if (cpi->common.use_highbitdepth) {
3577 lb_u = src_u16[0];
3578 ub_u = src_u16[0];
3579 lb_v = src_v16[0];
3580 ub_v = src_v16[0];
3581 } else {
3582#endif // CONFIG_VP9_HIGHBITDEPTH
3583 lb_u = src_u[0];
3584 ub_u = src_u[0];
3585 lb_v = src_v[0];
3586 ub_v = src_v[0];
3587#if CONFIG_VP9_HIGHBITDEPTH
3588 }
3589#endif // CONFIG_VP9_HIGHBITDEPTH
3590
3591 mbmi->uv_mode = DC_PRED;
3592#if CONFIG_EXT_INTRA
3593 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
3594#endif // CONFIG_EXT_INTRA
3595 for (r = 0; r < rows; ++r) {
3596 for (c = 0; c < cols; ++c) {
3597#if CONFIG_VP9_HIGHBITDEPTH
3598 if (cpi->common.use_highbitdepth) {
3599 val_u = src_u16[r * src_stride + c];
3600 val_v = src_v16[r * src_stride + c];
3601 data[(r * cols + c) * 2 ] = val_u;
3602 data[(r * cols + c) * 2 + 1] = val_v;
3603 } else {
3604#endif // CONFIG_VP9_HIGHBITDEPTH
3605 val_u = src_u[r * src_stride + c];
3606 val_v = src_v[r * src_stride + c];
3607 data[(r * cols + c) * 2 ] = val_u;
3608 data[(r * cols + c) * 2 + 1] = val_v;
3609#if CONFIG_VP9_HIGHBITDEPTH
3610 }
3611#endif // CONFIG_VP9_HIGHBITDEPTH
3612 if (val_u < lb_u)
3613 lb_u = val_u;
3614 else if (val_u > ub_u)
3615 ub_u = val_u;
3616 if (val_v < lb_v)
3617 lb_v = val_v;
3618 else if (val_v > ub_v)
3619 ub_v = val_v;
3620 }
3621 }
3622
3623 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors;
3624 n >= 2; --n) {
3625 for (i = 0; i < n; ++i) {
3626 centroids[i * 2] = lb_u + (2 * i + 1) * (ub_u - lb_u) / n / 2;
3627 centroids[i * 2 + 1] =
3628 lb_v + (2 * i + 1) * (ub_v - lb_v) / n / 2;;
3629 }
3630 r = vp10_k_means(data, centroids, indices, pre_indices, rows * cols, n,
3631 2, max_itr);
3632 pmi->palette_size[1] = n;
3633 for (i = 1; i < 3; ++i) {
3634 for (j = 0; j < n; ++j) {
3635#if CONFIG_VP9_HIGHBITDEPTH
3636 if (cpi->common.use_highbitdepth)
3637 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
3638 clip_pixel_highbd(round(centroids[j * 2 + i - 1]),
3639 cpi->common.bit_depth);
3640 else
3641#endif // CONFIG_VP9_HIGHBITDEPTH
3642 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
3643 clip_pixel(round(centroids[j * 2 + i - 1]));
3644 }
3645 }
3646 for (r = 0; r < rows; ++r)
3647 for (c = 0; c < cols; ++c)
3648 color_map[r * cols + c] = indices[r * cols + c];
3649
3650 super_block_uvrd(cpi, x, &this_rate_tokenonly,
3651 &this_distortion, &s, &this_sse, bsize, *best_rd);
3652 if (this_rate_tokenonly == INT_MAX)
3653 continue;
3654 this_rate = this_rate_tokenonly + dc_mode_cost +
3655 2 * cpi->common.bit_depth * n * vp10_cost_bit(128, 0) +
3656 cpi->palette_uv_size_cost[bsize - BLOCK_8X8][n - 2] +
3657 write_uniform_cost(n, color_map[0]) +
3658 vp10_cost_bit(vp10_default_palette_uv_mode_prob
3659 [pmi->palette_size[0] > 0], 1);
3660
3661 for (i = 0; i < rows; ++i) {
3662 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
3663 color_ctx = vp10_get_palette_color_context(color_map, cols, i, j, n,
3664 color_order);
3665 for (r = 0; r < n; ++r)
3666 if (color_map[i * cols + j] == color_order[r]) {
3667 color_idx = r;
3668 break;
3669 }
3670 assert(color_idx >= 0 && color_idx < n);
3671 this_rate +=
3672 cpi->palette_uv_color_cost[n - 2][color_ctx][color_idx];
3673 }
3674 }
3675
3676 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3677 if (this_rd < *best_rd) {
3678 *best_rd = this_rd;
3679 *palette_mode_info = *pmi;
3680 memcpy(best_palette_color_map, xd->plane[1].color_index_map,
3681 rows * cols * sizeof(best_palette_color_map[0]));
3682 *mode_selected = DC_PRED;
3683 *rate = this_rate;
3684 *distortion = this_distortion;
3685 *rate_tokenonly = this_rate_tokenonly;
3686 *skippable = s;
3687 if (!x->select_tx_size)
3688 swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE);
3689 }
3690 }
3691 }
3692}
3693
hui sube3559b2015-10-07 09:29:02 -07003694#if CONFIG_EXT_INTRA
3695// Return 1 if an ext intra mode is selected; return 0 otherwise.
3696static int rd_pick_ext_intra_sbuv(VP10_COMP *cpi, MACROBLOCK *x,
3697 PICK_MODE_CONTEXT *ctx,
3698 int *rate, int *rate_tokenonly,
3699 int64_t *distortion, int *skippable,
3700 BLOCK_SIZE bsize, int64_t *best_rd) {
3701 MACROBLOCKD *const xd = &x->e_mbd;
3702 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
3703 int ext_intra_selected_flag = 0;
3704 int this_rate_tokenonly, this_rate, s;
hui su4aa50c12015-11-10 12:09:59 -08003705 int64_t this_distortion, this_sse, this_rd;
hui sube3559b2015-10-07 09:29:02 -07003706 EXT_INTRA_MODE mode;
hui sube3559b2015-10-07 09:29:02 -07003707 EXT_INTRA_MODE_INFO ext_intra_mode_info;
3708
3709 vp10_zero(ext_intra_mode_info);
3710 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 1;
3711 mbmi->uv_mode = DC_PRED;
hui su78b0bd02016-02-23 15:22:25 -08003712 mbmi->palette_mode_info.palette_size[1] = 0;
hui sube3559b2015-10-07 09:29:02 -07003713
hui su4aa50c12015-11-10 12:09:59 -08003714 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
3715 mbmi->ext_intra_mode_info.ext_intra_mode[1] = mode;
3716 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3717 &this_distortion, &s, &this_sse, bsize, *best_rd))
3718 continue;
hui sube3559b2015-10-07 09:29:02 -07003719
hui su4aa50c12015-11-10 12:09:59 -08003720 this_rate = this_rate_tokenonly +
3721 vp10_cost_bit(cpi->common.fc->ext_intra_probs[1], 1) +
3722 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
3723 write_uniform_cost(FILTER_INTRA_MODES, mode);
3724 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3725 if (this_rd < *best_rd) {
3726 *best_rd = this_rd;
3727 *rate = this_rate;
3728 *rate_tokenonly = this_rate_tokenonly;
3729 *distortion = this_distortion;
3730 *skippable = s;
3731 ext_intra_mode_info = mbmi->ext_intra_mode_info;
3732 ext_intra_selected_flag = 1;
3733 if (!x->select_tx_size)
3734 swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE);
hui sube3559b2015-10-07 09:29:02 -07003735 }
3736 }
3737
hui sube3559b2015-10-07 09:29:02 -07003738
3739 if (ext_intra_selected_flag) {
3740 mbmi->uv_mode = DC_PRED;
3741 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
3742 ext_intra_mode_info.use_ext_intra_mode[1];
3743 mbmi->ext_intra_mode_info.ext_intra_mode[1] =
3744 ext_intra_mode_info.ext_intra_mode[1];
hui sube3559b2015-10-07 09:29:02 -07003745 return 1;
3746 } else {
3747 return 0;
3748 }
3749}
hui su4aa50c12015-11-10 12:09:59 -08003750
hui su5a7c8d82016-02-08 10:39:17 -08003751static void pick_intra_angle_routine_sbuv(VP10_COMP *cpi, MACROBLOCK *x,
3752 int *rate, int *rate_tokenonly,
3753 int64_t *distortion, int *skippable,
3754 int *best_angle_delta,
3755 BLOCK_SIZE bsize, int rate_overhead,
3756 int64_t *best_rd) {
3757 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
3758 int this_rate_tokenonly, this_rate, s;
3759 int64_t this_distortion, this_sse, this_rd;
3760
3761 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3762 &this_distortion, &s, &this_sse, bsize, *best_rd))
3763 return;
3764
3765 this_rate = this_rate_tokenonly + rate_overhead;
3766 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3767 if (this_rd < *best_rd) {
3768 *best_rd = this_rd;
3769 *best_angle_delta = mbmi->angle_delta[1];
3770 *rate = this_rate;
3771 *rate_tokenonly = this_rate_tokenonly;
3772 *distortion = this_distortion;
3773 *skippable = s;
3774 }
3775}
3776
hui su4aa50c12015-11-10 12:09:59 -08003777static int rd_pick_intra_angle_sbuv(VP10_COMP *cpi, MACROBLOCK *x,
3778 PICK_MODE_CONTEXT *ctx,
3779 int *rate, int *rate_tokenonly,
3780 int64_t *distortion, int *skippable,
3781 BLOCK_SIZE bsize, int rate_overhead,
3782 int64_t best_rd) {
3783 MACROBLOCKD *const xd = &x->e_mbd;
3784 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
3785 int this_rate_tokenonly, this_rate, s;
3786 int64_t this_distortion, this_sse, this_rd;
3787 int angle_delta, best_angle_delta = 0;
3788 const double rd_adjust = 1.2;
3789
3790 (void)ctx;
3791 *rate_tokenonly = INT_MAX;
3792 if (ANGLE_FAST_SEARCH) {
3793 int deltas_level1[3] = {0, -2, 2};
3794 int deltas_level2[3][2] = {
3795 {-1, 1}, {-3, -1}, {1, 3},
3796 };
3797 const int level1 = 3, level2 = 2;
3798 int i, j, best_i = -1;
3799
3800 for (i = 0; i < level1; ++i) {
Yaowu Xu28eb7842016-03-07 16:23:26 -08003801 int64_t tmp_best_rd;
hui su4aa50c12015-11-10 12:09:59 -08003802 mbmi->angle_delta[1] = deltas_level1[i];
Yaowu Xu28eb7842016-03-07 16:23:26 -08003803 tmp_best_rd = (i == 0 && best_rd < INT64_MAX) ?
3804 (int64_t)(best_rd * rd_adjust) : best_rd;
3805 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion,
3806 &s, &this_sse, bsize, tmp_best_rd)) {
hui su4aa50c12015-11-10 12:09:59 -08003807 if (i == 0)
3808 break;
3809 else
3810 continue;
3811 }
3812 this_rate = this_rate_tokenonly + rate_overhead;
3813 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3814 if (i == 0 && best_rd < INT64_MAX && this_rd > best_rd * rd_adjust)
3815 break;
3816 if (this_rd < best_rd) {
3817 best_i = i;
3818 best_rd = this_rd;
3819 best_angle_delta = mbmi->angle_delta[1];
3820 *rate = this_rate;
3821 *rate_tokenonly = this_rate_tokenonly;
3822 *distortion = this_distortion;
3823 *skippable = s;
3824 }
3825 }
3826
3827 if (best_i >= 0) {
3828 for (j = 0; j < level2; ++j) {
3829 mbmi->angle_delta[1] = deltas_level2[best_i][j];
hui su5a7c8d82016-02-08 10:39:17 -08003830 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly,
3831 distortion, skippable,
3832 &best_angle_delta, bsize,
3833 rate_overhead, &best_rd);
hui su4aa50c12015-11-10 12:09:59 -08003834 }
3835 }
3836 } else {
3837 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
3838 ++angle_delta) {
3839 mbmi->angle_delta[1] = angle_delta;
hui su5a7c8d82016-02-08 10:39:17 -08003840 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly,
3841 distortion, skippable,
3842 &best_angle_delta, bsize,
3843 rate_overhead, &best_rd);
hui su4aa50c12015-11-10 12:09:59 -08003844 }
3845 }
3846
3847 mbmi->angle_delta[1] = best_angle_delta;
3848 if (*rate_tokenonly != INT_MAX)
3849 super_block_uvrd(cpi, x, &this_rate_tokenonly,
3850 &this_distortion, &s, &this_sse, bsize, INT_MAX);
3851 return *rate_tokenonly != INT_MAX;
3852}
hui sube3559b2015-10-07 09:29:02 -07003853#endif // CONFIG_EXT_INTRA
3854
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003855static int64_t rd_pick_intra_sbuv_mode(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003856 PICK_MODE_CONTEXT *ctx,
3857 int *rate, int *rate_tokenonly,
3858 int64_t *distortion, int *skippable,
3859 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
3860 MACROBLOCKD *xd = &x->e_mbd;
hui sube3559b2015-10-07 09:29:02 -07003861 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Jingning Han3ee6db62015-08-05 19:00:31 -07003862 PREDICTION_MODE mode;
3863 PREDICTION_MODE mode_selected = DC_PRED;
3864 int64_t best_rd = INT64_MAX, this_rd;
3865 int this_rate_tokenonly, this_rate, s;
3866 int64_t this_distortion, this_sse;
hui su78b0bd02016-02-23 15:22:25 -08003867 const int rows = (4 * num_4x4_blocks_high_lookup[bsize]) >>
3868 (xd->plane[1].subsampling_y);
3869 const int cols = (4 * num_4x4_blocks_wide_lookup[bsize]) >>
3870 (xd->plane[1].subsampling_x);
3871 PALETTE_MODE_INFO palette_mode_info;
3872 PALETTE_MODE_INFO *const pmi = &xd->mi[0]->mbmi.palette_mode_info;
3873 uint8_t *best_palette_color_map = NULL;
hui sube3559b2015-10-07 09:29:02 -07003874#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08003875 int is_directional_mode, rate_overhead, best_angle_delta = 0;
hui sube3559b2015-10-07 09:29:02 -07003876 EXT_INTRA_MODE_INFO ext_intra_mode_info;
Jingning Han3ee6db62015-08-05 19:00:31 -07003877
hui sube3559b2015-10-07 09:29:02 -07003878 ext_intra_mode_info.use_ext_intra_mode[1] = 0;
3879 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
3880#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07003881 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
hui su78b0bd02016-02-23 15:22:25 -08003882 palette_mode_info.palette_size[1] = 0;
3883 pmi->palette_size[1] = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07003884 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
3885 if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode)))
3886 continue;
3887
hui sube3559b2015-10-07 09:29:02 -07003888 mbmi->uv_mode = mode;
hui su4aa50c12015-11-10 12:09:59 -08003889#if CONFIG_EXT_INTRA
3890 is_directional_mode = (mode != DC_PRED && mode != TM_PRED);
3891 rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
3892 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
3893 mbmi->angle_delta[1] = 0;
3894 if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode) {
3895 if (!rd_pick_intra_angle_sbuv(cpi, x, ctx, &this_rate,
3896 &this_rate_tokenonly, &this_distortion, &s,
3897 bsize, rate_overhead, best_rd))
3898 continue;
3899 } else {
3900 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3901 &this_distortion, &s, &this_sse, bsize, best_rd))
3902 continue;
3903 }
3904 this_rate = this_rate_tokenonly +
3905 cpi->intra_uv_mode_cost[mbmi->mode][mode];
3906 if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode)
3907 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
3908 MAX_ANGLE_DELTAS +
3909 mbmi->angle_delta[1]);
hui su8102aeb2016-03-11 10:23:51 -08003910 if (mode == DC_PRED)
hui su4aa50c12015-11-10 12:09:59 -08003911 this_rate += vp10_cost_bit(cpi->common.fc->ext_intra_probs[1], 0);
3912#else
Jingning Han3ee6db62015-08-05 19:00:31 -07003913 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3914 &this_distortion, &s, &this_sse, bsize, best_rd))
3915 continue;
hui su6ab6ac42015-11-06 13:56:51 -08003916 this_rate = this_rate_tokenonly +
hui su78b0bd02016-02-23 15:22:25 -08003917 cpi->intra_uv_mode_cost[mbmi->mode][mode];
hui sube3559b2015-10-07 09:29:02 -07003918#endif // CONFIG_EXT_INTRA
hui su78b0bd02016-02-23 15:22:25 -08003919 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8 &&
3920 mode == DC_PRED)
3921 this_rate += vp10_cost_bit(vp10_default_palette_uv_mode_prob
3922 [pmi->palette_size[0] > 0], 0);
hui su4aa50c12015-11-10 12:09:59 -08003923
Jingning Han3ee6db62015-08-05 19:00:31 -07003924 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3925
3926 if (this_rd < best_rd) {
3927 mode_selected = mode;
hui su4aa50c12015-11-10 12:09:59 -08003928#if CONFIG_EXT_INTRA
3929 best_angle_delta = mbmi->angle_delta[1];
3930#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07003931 best_rd = this_rd;
3932 *rate = this_rate;
3933 *rate_tokenonly = this_rate_tokenonly;
3934 *distortion = this_distortion;
3935 *skippable = s;
3936 if (!x->select_tx_size)
3937 swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE);
3938 }
3939 }
3940
hui su78b0bd02016-02-23 15:22:25 -08003941 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8) {
3942 best_palette_color_map = x->palette_buffer->best_palette_color_map;
3943 rd_pick_palette_intra_sbuv(cpi, x, ctx,
3944 cpi->intra_uv_mode_cost[mbmi->mode][DC_PRED],
3945 &palette_mode_info, best_palette_color_map,
3946 &mode_selected, &best_rd, rate, rate_tokenonly,
3947 distortion, skippable);
3948 }
3949
hui sube3559b2015-10-07 09:29:02 -07003950#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08003951 if (mbmi->sb_type >= BLOCK_8X8 && ALLOW_FILTER_INTRA_MODES) {
hui sube3559b2015-10-07 09:29:02 -07003952 if (rd_pick_ext_intra_sbuv(cpi, x, ctx, rate, rate_tokenonly, distortion,
3953 skippable, bsize, &best_rd)) {
3954 mode_selected = mbmi->uv_mode;
3955 ext_intra_mode_info = mbmi->ext_intra_mode_info;
3956 }
3957 }
3958
3959 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
3960 ext_intra_mode_info.use_ext_intra_mode[1];
hui su78b0bd02016-02-23 15:22:25 -08003961 if (ext_intra_mode_info.use_ext_intra_mode[1]) {
hui sube3559b2015-10-07 09:29:02 -07003962 mbmi->ext_intra_mode_info.ext_intra_mode[1] =
3963 ext_intra_mode_info.ext_intra_mode[1];
hui su78b0bd02016-02-23 15:22:25 -08003964 palette_mode_info.palette_size[1] = 0;
3965 }
hui su4aa50c12015-11-10 12:09:59 -08003966 mbmi->angle_delta[1] = best_angle_delta;
hui sube3559b2015-10-07 09:29:02 -07003967#endif // CONFIG_EXT_INTRA
3968 mbmi->uv_mode = mode_selected;
hui su78b0bd02016-02-23 15:22:25 -08003969 pmi->palette_size[1] = palette_mode_info.palette_size[1];
3970 if (palette_mode_info.palette_size[1] > 0) {
3971 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
3972 palette_mode_info.palette_colors + PALETTE_MAX_SIZE,
3973 2 * PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
3974 memcpy(xd->plane[1].color_index_map, best_palette_color_map,
3975 rows * cols * sizeof(best_palette_color_map[0]));
3976 }
3977
Jingning Han3ee6db62015-08-05 19:00:31 -07003978 return best_rd;
3979}
3980
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003981static int64_t rd_sbuv_dcpred(const VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003982 int *rate, int *rate_tokenonly,
3983 int64_t *distortion, int *skippable,
3984 BLOCK_SIZE bsize) {
Jingning Han3ee6db62015-08-05 19:00:31 -07003985 int64_t unused;
3986
3987 x->e_mbd.mi[0]->mbmi.uv_mode = DC_PRED;
3988 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
3989 super_block_uvrd(cpi, x, rate_tokenonly, distortion,
3990 skippable, &unused, bsize, INT64_MAX);
hui su6ab6ac42015-11-06 13:56:51 -08003991 *rate = *rate_tokenonly +
3992 cpi->intra_uv_mode_cost[x->e_mbd.mi[0]->mbmi.mode][DC_PRED];
Jingning Han3ee6db62015-08-05 19:00:31 -07003993 return RDCOST(x->rdmult, x->rddiv, *rate, *distortion);
3994}
3995
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003996static void choose_intra_uv_mode(VP10_COMP *cpi, MACROBLOCK *const x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003997 PICK_MODE_CONTEXT *ctx,
3998 BLOCK_SIZE bsize, TX_SIZE max_tx_size,
3999 int *rate_uv, int *rate_uv_tokenonly,
4000 int64_t *dist_uv, int *skip_uv,
4001 PREDICTION_MODE *mode_uv) {
4002 // Use an estimated rd for uv_intra based on DC_PRED if the
4003 // appropriate speed flag is set.
4004 if (cpi->sf.use_uv_intra_rd_estimate) {
4005 rd_sbuv_dcpred(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv,
4006 skip_uv, bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize);
4007 // Else do a proper rd search for each possible transform size that may
4008 // be considered in the main rd loop.
4009 } else {
4010 rd_pick_intra_sbuv_mode(cpi, x, ctx,
4011 rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4012 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
4013 }
4014 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
4015}
4016
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004017static int cost_mv_ref(const VP10_COMP *cpi, PREDICTION_MODE mode,
Yue Chen1ac85872016-01-07 15:13:52 -08004018#if CONFIG_REF_MV && CONFIG_EXT_INTER
4019 int is_compound,
4020#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004021 int16_t mode_context) {
Jingning Han1dc18072015-12-02 10:59:01 -08004022#if CONFIG_REF_MV
4023 int mode_cost = 0;
Yue Chen968bbc72016-01-19 16:45:45 -08004024#if CONFIG_EXT_INTER
4025 int16_t mode_ctx = is_compound ? mode_context :
4026 (mode_context & NEWMV_CTX_MASK);
4027#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004028 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
Yue Chen968bbc72016-01-19 16:45:45 -08004029#endif // CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004030 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
Jingning Han1dc18072015-12-02 10:59:01 -08004031
4032 assert(is_inter_mode(mode));
4033
Yue Chen1ac85872016-01-07 15:13:52 -08004034#if CONFIG_EXT_INTER
Yue Chen968bbc72016-01-19 16:45:45 -08004035 if (is_compound) {
4036 return cpi->inter_compound_mode_cost[mode_context]
4037 [INTER_COMPOUND_OFFSET(mode)];
4038 } else {
4039 if (mode == NEWMV || mode == NEWFROMNEARMV) {
Yue Chen1ac85872016-01-07 15:13:52 -08004040#else
Jingning Han1dc18072015-12-02 10:59:01 -08004041 if (mode == NEWMV) {
Yue Chen1ac85872016-01-07 15:13:52 -08004042#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08004043 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
Yue Chen1ac85872016-01-07 15:13:52 -08004044#if CONFIG_EXT_INTER
4045 if (!is_compound)
4046 mode_cost += cpi->new2mv_mode_cost[mode == NEWFROMNEARMV];
4047#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08004048 return mode_cost;
4049 } else {
4050 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
4051 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004052
4053 if (is_all_zero_mv)
4054 return mode_cost;
4055
Jingning Han1dc18072015-12-02 10:59:01 -08004056 if (mode == ZEROMV) {
4057 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
4058 return mode_cost;
4059 } else {
4060 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004061 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
Jingning Han387a10e2015-12-09 09:07:39 -08004062
4063 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET))
4064 mode_ctx = 6;
4065 if (mode_context & (1 << SKIP_NEARMV_OFFSET))
4066 mode_ctx = 7;
4067 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET))
4068 mode_ctx = 8;
4069
Jingning Han1dc18072015-12-02 10:59:01 -08004070 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
4071 return mode_cost;
4072 }
4073 }
Yue Chen968bbc72016-01-19 16:45:45 -08004074#if CONFIG_EXT_INTER
4075 }
4076#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08004077#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004078 assert(is_inter_mode(mode));
Yue Chen968bbc72016-01-19 16:45:45 -08004079#if CONFIG_EXT_INTER
4080 if (is_inter_compound_mode(mode)) {
4081 return cpi->inter_compound_mode_cost[mode_context]
4082 [INTER_COMPOUND_OFFSET(mode)];
4083 } else {
4084#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004085 return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
Yue Chen968bbc72016-01-19 16:45:45 -08004086#if CONFIG_EXT_INTER
4087 }
4088#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08004089#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07004090}
4091
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004092static int set_and_cost_bmi_mvs(VP10_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd,
Jingning Han3ee6db62015-08-05 19:00:31 -07004093 int i,
4094 PREDICTION_MODE mode, int_mv this_mv[2],
4095 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
4096 int_mv seg_mvs[MAX_REF_FRAMES],
Yue Chen1ac85872016-01-07 15:13:52 -08004097#if CONFIG_EXT_INTER
4098 int_mv compound_seg_newmvs[2],
4099#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004100 int_mv *best_ref_mv[2], const int *mvjcost,
4101 int *mvcost[2]) {
4102 MODE_INFO *const mic = xd->mi[0];
4103 const MB_MODE_INFO *const mbmi = &mic->mbmi;
4104 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4105 int thismvcost = 0;
4106 int idx, idy;
4107 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
4108 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
4109 const int is_compound = has_second_ref(mbmi);
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004110 int mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
Jingning Han3ee6db62015-08-05 19:00:31 -07004111
4112 switch (mode) {
4113 case NEWMV:
Yue Chen1ac85872016-01-07 15:13:52 -08004114#if CONFIG_EXT_INTER
4115 case NEWFROMNEARMV:
Yue Chen1ac85872016-01-07 15:13:52 -08004116#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004117 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08004118#if CONFIG_EXT_INTER
4119 if (!cpi->common.allow_high_precision_mv ||
4120 !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
4121 lower_mv_precision(&this_mv[0].as_mv, 0);
4122#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004123 thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4124 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yue Chen968bbc72016-01-19 16:45:45 -08004125#if !CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004126 if (is_compound) {
4127 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
4128 thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4129 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
4130 }
Yue Chen968bbc72016-01-19 16:45:45 -08004131#endif // !CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004132 break;
4133 case NEARMV:
4134 case NEARESTMV:
4135 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4136 if (is_compound)
4137 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4138 break;
4139 case ZEROMV:
4140 this_mv[0].as_int = 0;
4141 if (is_compound)
4142 this_mv[1].as_int = 0;
4143 break;
Yue Chen968bbc72016-01-19 16:45:45 -08004144#if CONFIG_EXT_INTER
4145 case NEW_NEWMV:
4146 if (compound_seg_newmvs[0].as_int == INVALID_MV ||
4147 compound_seg_newmvs[1].as_int == INVALID_MV) {
4148 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
4149 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
4150 } else {
4151 this_mv[0].as_int = compound_seg_newmvs[0].as_int;
4152 this_mv[1].as_int = compound_seg_newmvs[1].as_int;
4153 }
4154 if (!cpi->common.allow_high_precision_mv ||
4155 !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
4156 lower_mv_precision(&this_mv[0].as_mv, 0);
4157 if (!cpi->common.allow_high_precision_mv ||
4158 !vp10_use_mv_hp(&best_ref_mv[1]->as_mv))
4159 lower_mv_precision(&this_mv[1].as_mv, 0);
4160 thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv,
4161 &best_ref_mv[0]->as_mv,
4162 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
4163 thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv,
4164 &best_ref_mv[1]->as_mv,
4165 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
4166 break;
4167 case NEW_NEARMV:
4168 case NEW_NEARESTMV:
4169 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
4170 if (!cpi->common.allow_high_precision_mv ||
4171 !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
4172 lower_mv_precision(&this_mv[0].as_mv, 0);
4173 thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4174 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
4175 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4176 break;
4177 case NEAR_NEWMV:
4178 case NEAREST_NEWMV:
4179 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4180 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
4181 if (!cpi->common.allow_high_precision_mv ||
4182 !vp10_use_mv_hp(&best_ref_mv[1]->as_mv))
4183 lower_mv_precision(&this_mv[1].as_mv, 0);
4184 thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4185 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
4186 break;
4187 case NEAREST_NEARMV:
4188 case NEAR_NEARESTMV:
4189 case NEAREST_NEARESTMV:
4190 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4191 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4192 break;
4193 case ZERO_ZEROMV:
4194 this_mv[0].as_int = 0;
4195 this_mv[1].as_int = 0;
4196 break;
4197#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004198 default:
4199 break;
4200 }
4201
4202 mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
4203 if (is_compound)
4204 mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
4205
4206 mic->bmi[i].as_mode = mode;
4207
Jingning Han876c8b02016-02-17 16:10:38 -08004208#if CONFIG_REF_MV
4209 if (mode == NEWMV) {
4210 mic->bmi[i].pred_mv[0].as_int =
4211 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_int;
4212 if (is_compound)
4213 mic->bmi[i].pred_mv[1].as_int =
4214 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_int;
4215 } else {
4216 mic->bmi[i].pred_mv[0].as_int = this_mv[0].as_int;
4217 if (is_compound)
4218 mic->bmi[i].pred_mv[1].as_int = this_mv[1].as_int;
4219 }
4220#endif
4221
Jingning Han3ee6db62015-08-05 19:00:31 -07004222 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
4223 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
4224 memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
4225
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004226#if CONFIG_REF_MV
Yue Chen968bbc72016-01-19 16:45:45 -08004227#if CONFIG_EXT_INTER
4228 if (is_compound)
4229 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
4230 else
4231#endif // CONFIG_EXT_INTER
Jingning Han387a10e2015-12-09 09:07:39 -08004232 mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
4233 mbmi->ref_frame, mbmi->sb_type, i);
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004234#endif
Yue Chen1ac85872016-01-07 15:13:52 -08004235#if CONFIG_REF_MV && CONFIG_EXT_INTER
4236 return cost_mv_ref(cpi, mode, is_compound, mode_ctx) + thismvcost;
4237#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004238 return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
Yue Chen1ac85872016-01-07 15:13:52 -08004239#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004240}
4241
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004242static int64_t encode_inter_mb_segment(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07004243 MACROBLOCK *x,
4244 int64_t best_yrd,
4245 int i,
4246 int *labelyrate,
4247 int64_t *distortion, int64_t *sse,
4248 ENTROPY_CONTEXT *ta,
4249 ENTROPY_CONTEXT *tl,
Yaowu Xu7c514e22015-09-28 15:55:46 -07004250 int ir, int ic,
Jingning Han3ee6db62015-08-05 19:00:31 -07004251 int mi_row, int mi_col) {
4252 int k;
4253 MACROBLOCKD *xd = &x->e_mbd;
4254 struct macroblockd_plane *const pd = &xd->plane[0];
4255 struct macroblock_plane *const p = &x->plane[0];
4256 MODE_INFO *const mi = xd->mi[0];
4257 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
4258 const int width = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
4259 const int height = 4 * num_4x4_blocks_high_lookup[plane_bsize];
4260 int idx, idy;
Yaowu Xu7c514e22015-09-28 15:55:46 -07004261 void (*fwd_txm4x4)(const int16_t *input, tran_low_t *output, int stride);
Jingning Han3ee6db62015-08-05 19:00:31 -07004262
4263 const uint8_t *const src =
4264 &p->src.buf[vp10_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
4265 uint8_t *const dst = &pd->dst.buf[vp10_raster_block_offset(BLOCK_8X8, i,
4266 pd->dst.stride)];
4267 int64_t thisdistortion = 0, thissse = 0;
Yaowu Xu7c514e22015-09-28 15:55:46 -07004268 int thisrate = 0;
hui sub3cc3a02015-08-24 14:37:54 -07004269 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, i, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07004270 const scan_order *so = get_scan(TX_4X4, tx_type, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07004271
Yaowu Xu7c514e22015-09-28 15:55:46 -07004272 vp10_build_inter_predictor_sub8x8(xd, 0, i, ir, ic, mi_row, mi_col);
4273
Jingning Han3ee6db62015-08-05 19:00:31 -07004274#if CONFIG_VP9_HIGHBITDEPTH
4275 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04004276 fwd_txm4x4 = xd->lossless[mi->mbmi.segment_id] ? vp10_highbd_fwht4x4
4277 : vpx_highbd_fdct4x4;
Jingning Han3ee6db62015-08-05 19:00:31 -07004278 } else {
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04004279 fwd_txm4x4 = xd->lossless[mi->mbmi.segment_id] ? vp10_fwht4x4 : vpx_fdct4x4;
Jingning Han3ee6db62015-08-05 19:00:31 -07004280 }
4281#else
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04004282 fwd_txm4x4 = xd->lossless[mi->mbmi.segment_id] ? vp10_fwht4x4 : vpx_fdct4x4;
Jingning Han3ee6db62015-08-05 19:00:31 -07004283#endif // CONFIG_VP9_HIGHBITDEPTH
Jingning Han3ee6db62015-08-05 19:00:31 -07004284
4285#if CONFIG_VP9_HIGHBITDEPTH
4286 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
4287 vpx_highbd_subtract_block(
4288 height, width, vp10_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
4289 8, src, p->src.stride, dst, pd->dst.stride, xd->bd);
4290 } else {
4291 vpx_subtract_block(
4292 height, width, vp10_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
4293 8, src, p->src.stride, dst, pd->dst.stride);
4294 }
4295#else
4296 vpx_subtract_block(height, width,
4297 vp10_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
4298 8, src, p->src.stride, dst, pd->dst.stride);
4299#endif // CONFIG_VP9_HIGHBITDEPTH
4300
4301 k = i;
4302 for (idy = 0; idy < height / 4; ++idy) {
4303 for (idx = 0; idx < width / 4; ++idx) {
Yue Chenef8f7c12016-03-04 09:48:57 -08004304 int64_t dist, ssz, rd, rd1, rd2;
Jingning Han3ee6db62015-08-05 19:00:31 -07004305 tran_low_t* coeff;
Jingning Han2cdc1272015-10-09 09:57:42 -07004306#if CONFIG_VAR_TX
4307 int coeff_ctx;
4308#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07004309 k += (idy * 2 + idx);
Jingning Han2cdc1272015-10-09 09:57:42 -07004310#if CONFIG_VAR_TX
4311 coeff_ctx = combine_entropy_contexts(*(ta + (k & 1)),
4312 *(tl + (k >> 1)));
4313#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07004314 coeff = BLOCK_OFFSET(p->coeff, k);
Yaowu Xu7c514e22015-09-28 15:55:46 -07004315 fwd_txm4x4(vp10_raster_block_offset_int16(BLOCK_8X8, k, p->src_diff),
4316 coeff, 8);
Jingning Han3ee6db62015-08-05 19:00:31 -07004317 vp10_regular_quantize_b_4x4(x, 0, k, so->scan, so->iscan);
Yue Chenef8f7c12016-03-04 09:48:57 -08004318 dist_block(cpi, x, 0, k, idy + (i >> 1), idx + (i & 0x1), TX_4X4,
4319 &dist, &ssz);
4320 thisdistortion += dist;
Jingning Han3ee6db62015-08-05 19:00:31 -07004321 thissse += ssz;
Jingning Han2cdc1272015-10-09 09:57:42 -07004322#if CONFIG_VAR_TX
4323 thisrate += cost_coeffs(x, 0, k, coeff_ctx,
4324 TX_4X4,
Jingning Han3ee6db62015-08-05 19:00:31 -07004325 so->scan, so->neighbors,
4326 cpi->sf.use_fast_coef_costing);
Jingning Han2cdc1272015-10-09 09:57:42 -07004327 *(ta + (k & 1)) = !(p->eobs[k] == 0);
4328 *(tl + (k >> 1)) = !(p->eobs[k] == 0);
4329#else
4330 thisrate += cost_coeffs(x, 0, k, ta + (k & 1), tl + (k >> 1),
4331 TX_4X4,
4332 so->scan, so->neighbors,
4333 cpi->sf.use_fast_coef_costing);
4334#endif
Yue Chenef8f7c12016-03-04 09:48:57 -08004335 rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion);
4336 rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse);
James Zern5e16d392015-08-17 18:19:22 -07004337 rd = VPXMIN(rd1, rd2);
Jingning Han3ee6db62015-08-05 19:00:31 -07004338 if (rd >= best_yrd)
4339 return INT64_MAX;
4340 }
4341 }
4342
Yue Chenef8f7c12016-03-04 09:48:57 -08004343 *distortion = thisdistortion;
Jingning Han3ee6db62015-08-05 19:00:31 -07004344 *labelyrate = thisrate;
Yue Chenef8f7c12016-03-04 09:48:57 -08004345 *sse = thissse;
Jingning Han3ee6db62015-08-05 19:00:31 -07004346
4347 return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
4348}
4349
4350typedef struct {
4351 int eobs;
4352 int brate;
4353 int byrate;
4354 int64_t bdist;
4355 int64_t bsse;
4356 int64_t brdcost;
4357 int_mv mvs[2];
Yue Chen1ac85872016-01-07 15:13:52 -08004358#if CONFIG_EXT_INTER
4359 int_mv ref_mv[2];
4360#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004361 ENTROPY_CONTEXT ta[2];
4362 ENTROPY_CONTEXT tl[2];
4363} SEG_RDSTAT;
4364
4365typedef struct {
4366 int_mv *ref_mv[2];
4367 int_mv mvp;
4368
4369 int64_t segment_rd;
4370 int r;
4371 int64_t d;
4372 int64_t sse;
4373 int segment_yrate;
4374 PREDICTION_MODE modes[4];
Yue Chen968bbc72016-01-19 16:45:45 -08004375#if CONFIG_EXT_INTER
4376 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
4377#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004378 SEG_RDSTAT rdstat[4][INTER_MODES];
Yue Chen968bbc72016-01-19 16:45:45 -08004379#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004380 int mvthresh;
4381} BEST_SEG_INFO;
4382
4383static INLINE int mv_check_bounds(const MACROBLOCK *x, const MV *mv) {
4384 return (mv->row >> 3) < x->mv_row_min ||
4385 (mv->row >> 3) > x->mv_row_max ||
4386 (mv->col >> 3) < x->mv_col_min ||
4387 (mv->col >> 3) > x->mv_col_max;
4388}
4389
4390static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
4391 MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
4392 struct macroblock_plane *const p = &x->plane[0];
4393 struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
4394
4395 p->src.buf = &p->src.buf[vp10_raster_block_offset(BLOCK_8X8, i,
4396 p->src.stride)];
4397 assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
4398 pd->pre[0].buf = &pd->pre[0].buf[vp10_raster_block_offset(BLOCK_8X8, i,
4399 pd->pre[0].stride)];
4400 if (has_second_ref(mbmi))
4401 pd->pre[1].buf = &pd->pre[1].buf[vp10_raster_block_offset(BLOCK_8X8, i,
4402 pd->pre[1].stride)];
4403}
4404
4405static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
4406 struct buf_2d orig_pre[2]) {
4407 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
4408 x->plane[0].src = orig_src;
4409 x->e_mbd.plane[0].pre[0] = orig_pre[0];
4410 if (has_second_ref(mbmi))
4411 x->e_mbd.plane[0].pre[1] = orig_pre[1];
4412}
4413
Jingning Han3ee6db62015-08-05 19:00:31 -07004414// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
4415// TODO(aconverse): Find out if this is still productive then clean up or remove
4416static int check_best_zero_mv(
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004417 const VP10_COMP *cpi, const int16_t mode_context[MAX_REF_FRAMES],
Yue Chen968bbc72016-01-19 16:45:45 -08004418#if CONFIG_REF_MV && CONFIG_EXT_INTER
4419 const int16_t compound_mode_context[MAX_REF_FRAMES],
4420#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004421 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES], int this_mode,
Jingning Han387a10e2015-12-09 09:07:39 -08004422 const MV_REFERENCE_FRAME ref_frames[2],
4423 const BLOCK_SIZE bsize, int block) {
Geza Lore7ded0382016-02-22 10:55:32 +00004424
4425#if !CONFIG_EXT_INTER
4426 assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
4427#endif
4428
Jingning Han3ee6db62015-08-05 19:00:31 -07004429 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
4430 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
Geza Lore7ded0382016-02-22 10:55:32 +00004431 (ref_frames[1] <= INTRA_FRAME ||
Jingning Han3ee6db62015-08-05 19:00:31 -07004432 frame_mv[this_mode][ref_frames[1]].as_int == 0)) {
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004433#if CONFIG_REF_MV
Jingning Han387a10e2015-12-09 09:07:39 -08004434 int16_t rfc = vp10_mode_context_analyzer(mode_context,
4435 ref_frames, bsize, block);
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004436#else
4437 int16_t rfc = mode_context[ref_frames[0]];
4438#endif
Yue Chen1ac85872016-01-07 15:13:52 -08004439#if CONFIG_REF_MV && CONFIG_EXT_INTER
4440 int c1 = cost_mv_ref(cpi, NEARMV, ref_frames[1] > INTRA_FRAME, rfc);
4441 int c2 = cost_mv_ref(cpi, NEARESTMV, ref_frames[1] > INTRA_FRAME, rfc);
4442 int c3 = cost_mv_ref(cpi, ZEROMV, ref_frames[1] > INTRA_FRAME, rfc);
4443#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004444 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
4445 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
4446 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
Yue Chen1ac85872016-01-07 15:13:52 -08004447#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004448
Jingning Han387a10e2015-12-09 09:07:39 -08004449#if !CONFIG_REF_MV
4450 (void)bsize;
4451 (void)block;
4452#endif
4453
Jingning Han3ee6db62015-08-05 19:00:31 -07004454 if (this_mode == NEARMV) {
4455 if (c1 > c3) return 0;
4456 } else if (this_mode == NEARESTMV) {
4457 if (c2 > c3) return 0;
4458 } else {
4459 assert(this_mode == ZEROMV);
Geza Lore7ded0382016-02-22 10:55:32 +00004460 if (ref_frames[1] <= INTRA_FRAME) {
Jingning Han3ee6db62015-08-05 19:00:31 -07004461 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
4462 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
4463 return 0;
4464 } else {
4465 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
4466 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
4467 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
4468 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
4469 return 0;
4470 }
4471 }
4472 }
Yue Chen968bbc72016-01-19 16:45:45 -08004473#if CONFIG_EXT_INTER
4474 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
4475 this_mode == NEAR_NEARESTMV || this_mode == ZERO_ZEROMV) &&
4476 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
4477 frame_mv[this_mode][ref_frames[1]].as_int == 0) {
4478#if CONFIG_REF_MV
4479 int16_t rfc = compound_mode_context[ref_frames[0]];
4480 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, 1, rfc);
4481 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, 1, rfc);
4482 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, 1, rfc);
4483 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, 1, rfc);
4484#else
4485 int16_t rfc = mode_context[ref_frames[0]];
4486 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
4487 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
4488 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
4489 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
4490#endif
4491
4492 if (this_mode == NEAREST_NEARMV) {
4493 if (c1 > c3) return 0;
4494 } else if (this_mode == NEAREST_NEARESTMV) {
4495 if (c2 > c3) return 0;
4496 } else if (this_mode == NEAR_NEARESTMV) {
4497 if (c4 > c3) return 0;
4498 } else {
4499 assert(this_mode == ZERO_ZEROMV);
Geza Lore7ded0382016-02-22 10:55:32 +00004500 if ((c3 >= c2 &&
4501 frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
4502 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
4503 (c3 >= c1 &&
4504 frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
4505 frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
4506 (c3 >= c4 &&
4507 frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
4508 frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
4509 return 0;
Yue Chen968bbc72016-01-19 16:45:45 -08004510 }
4511 }
4512#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004513 return 1;
4514}
4515
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004516static void joint_motion_search(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07004517 BLOCK_SIZE bsize,
4518 int_mv *frame_mv,
4519 int mi_row, int mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08004520#if CONFIG_EXT_INTER
4521 int_mv* ref_mv_sub8x8[2],
4522#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07004523 int_mv single_newmv[MAX_REF_FRAMES],
Yunqing Wang342a3682016-02-16 14:33:18 -08004524 int *rate_mv,
4525 const int block) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07004526 const VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07004527 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
4528 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
4529 MACROBLOCKD *xd = &x->e_mbd;
4530 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4531 const int refs[2] = {mbmi->ref_frame[0],
4532 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]};
4533 int_mv ref_mv[2];
4534 int ite, ref;
Angie Chiang10ad97b2016-02-01 12:49:15 -08004535 const INTERP_FILTER interp_filter = mbmi->interp_filter;
Jingning Han3ee6db62015-08-05 19:00:31 -07004536 struct scale_factors sf;
4537
4538 // Do joint motion search in compound mode to get more accurate mv.
4539 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
4540 int last_besterr[2] = {INT_MAX, INT_MAX};
4541 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
4542 vp10_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
4543 vp10_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
4544 };
4545
4546 // Prediction buffer from second frame.
4547#if CONFIG_VP9_HIGHBITDEPTH
4548 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[64 * 64]);
4549 uint8_t *second_pred;
4550#else
4551 DECLARE_ALIGNED(16, uint8_t, second_pred[64 * 64]);
4552#endif // CONFIG_VP9_HIGHBITDEPTH
4553
4554 for (ref = 0; ref < 2; ++ref) {
Yue Chen1ac85872016-01-07 15:13:52 -08004555#if CONFIG_EXT_INTER
4556 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
4557 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
4558 else
4559#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004560 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
4561
4562 if (scaled_ref_frame[ref]) {
4563 int i;
4564 // Swap out the reference frame for a version that's been scaled to
4565 // match the resolution of the current frame, allowing the existing
4566 // motion search code to be used without additional modifications.
4567 for (i = 0; i < MAX_MB_PLANE; i++)
4568 backup_yv12[ref][i] = xd->plane[i].pre[ref];
4569 vp10_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
4570 NULL);
4571 }
4572
4573 frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
4574 }
4575
4576 // Since we have scaled the reference frames to match the size of the current
4577 // frame we must use a unit scaling factor during mode selection.
4578#if CONFIG_VP9_HIGHBITDEPTH
4579 vp10_setup_scale_factors_for_frame(&sf, cm->width, cm->height,
Debargha Mukherjee85514c42015-10-30 09:19:36 -07004580 cm->width, cm->height,
4581 cm->use_highbitdepth);
Jingning Han3ee6db62015-08-05 19:00:31 -07004582#else
4583 vp10_setup_scale_factors_for_frame(&sf, cm->width, cm->height,
Debargha Mukherjee85514c42015-10-30 09:19:36 -07004584 cm->width, cm->height);
Jingning Han3ee6db62015-08-05 19:00:31 -07004585#endif // CONFIG_VP9_HIGHBITDEPTH
4586
4587 // Allow joint search multiple times iteratively for each reference frame
4588 // and break out of the search loop if it couldn't find a better mv.
4589 for (ite = 0; ite < 4; ite++) {
4590 struct buf_2d ref_yv12[2];
4591 int bestsme = INT_MAX;
4592 int sadpb = x->sadperbit16;
4593 MV tmp_mv;
4594 int search_range = 3;
4595
4596 int tmp_col_min = x->mv_col_min;
4597 int tmp_col_max = x->mv_col_max;
4598 int tmp_row_min = x->mv_row_min;
4599 int tmp_row_max = x->mv_row_max;
4600 int id = ite % 2; // Even iterations search in the first reference frame,
4601 // odd iterations search in the second. The predictor
4602 // found for the 'other' reference frame is factored in.
4603
4604 // Initialized here because of compiler problem in Visual Studio.
4605 ref_yv12[0] = xd->plane[0].pre[0];
4606 ref_yv12[1] = xd->plane[0].pre[1];
4607
4608 // Get the prediction block from the 'other' reference frame.
4609#if CONFIG_VP9_HIGHBITDEPTH
4610 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
4611 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
4612 vp10_highbd_build_inter_predictor(ref_yv12[!id].buf,
4613 ref_yv12[!id].stride,
4614 second_pred, pw,
4615 &frame_mv[refs[!id]].as_mv,
4616 &sf, pw, ph, 0,
Angie Chiang10ad97b2016-02-01 12:49:15 -08004617 interp_filter, MV_PRECISION_Q3,
Jingning Han3ee6db62015-08-05 19:00:31 -07004618 mi_col * MI_SIZE, mi_row * MI_SIZE,
4619 xd->bd);
4620 } else {
4621 second_pred = (uint8_t *)second_pred_alloc_16;
4622 vp10_build_inter_predictor(ref_yv12[!id].buf,
4623 ref_yv12[!id].stride,
4624 second_pred, pw,
4625 &frame_mv[refs[!id]].as_mv,
4626 &sf, pw, ph, 0,
Angie Chiang10ad97b2016-02-01 12:49:15 -08004627 interp_filter, MV_PRECISION_Q3,
Jingning Han3ee6db62015-08-05 19:00:31 -07004628 mi_col * MI_SIZE, mi_row * MI_SIZE);
4629 }
4630#else
4631 vp10_build_inter_predictor(ref_yv12[!id].buf,
4632 ref_yv12[!id].stride,
4633 second_pred, pw,
4634 &frame_mv[refs[!id]].as_mv,
4635 &sf, pw, ph, 0,
Angie Chiang10ad97b2016-02-01 12:49:15 -08004636 interp_filter, MV_PRECISION_Q3,
Jingning Han3ee6db62015-08-05 19:00:31 -07004637 mi_col * MI_SIZE, mi_row * MI_SIZE);
4638#endif // CONFIG_VP9_HIGHBITDEPTH
4639
4640 // Do compound motion search on the current reference frame.
4641 if (id)
4642 xd->plane[0].pre[0] = ref_yv12[id];
4643 vp10_set_mv_search_range(x, &ref_mv[id].as_mv);
4644
4645 // Use the mv result from the single mode as mv predictor.
4646 tmp_mv = frame_mv[refs[id]].as_mv;
4647
4648 tmp_mv.col >>= 3;
4649 tmp_mv.row >>= 3;
4650
Jingning Han03c01bc2016-02-19 10:41:04 -08004651#if CONFIG_REF_MV
4652 vp10_set_mvcost(x, refs[id]);
4653#endif
4654
Jingning Han3ee6db62015-08-05 19:00:31 -07004655 // Small-range full-pixel motion search.
4656 bestsme = vp10_refining_search_8p_c(x, &tmp_mv, sadpb,
4657 search_range,
4658 &cpi->fn_ptr[bsize],
4659 &ref_mv[id].as_mv, second_pred);
4660 if (bestsme < INT_MAX)
4661 bestsme = vp10_get_mvpred_av_var(x, &tmp_mv, &ref_mv[id].as_mv,
4662 second_pred, &cpi->fn_ptr[bsize], 1);
4663
4664 x->mv_col_min = tmp_col_min;
4665 x->mv_col_max = tmp_col_max;
4666 x->mv_row_min = tmp_row_min;
4667 x->mv_row_max = tmp_row_max;
4668
4669 if (bestsme < INT_MAX) {
4670 int dis; /* TODO: use dis in distortion calculation later. */
4671 unsigned int sse;
Yunqing Wange6e2d882016-03-10 11:07:50 -08004672 if (cpi->sf.use_upsampled_references) {
4673 // Use up-sampled reference frames.
4674 struct macroblockd_plane *const pd = &xd->plane[0];
4675 struct buf_2d backup_pred = pd->pre[0];
4676 const YV12_BUFFER_CONFIG *upsampled_ref =
4677 get_upsampled_ref(cpi, refs[id]);
Yunqing Wang342a3682016-02-16 14:33:18 -08004678
Yunqing Wange6e2d882016-03-10 11:07:50 -08004679 // Set pred for Y plane
4680 setup_pred_plane(&pd->pre[0], upsampled_ref->y_buffer,
4681 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3),
4682 NULL, pd->subsampling_x, pd->subsampling_y);
Yunqing Wang342a3682016-02-16 14:33:18 -08004683
Yunqing Wange6e2d882016-03-10 11:07:50 -08004684 // If bsize < BLOCK_8X8, adjust pred pointer for this block
4685 if (bsize < BLOCK_8X8)
4686 pd->pre[0].buf =
4687 &pd->pre[0].buf[(vp10_raster_block_offset(BLOCK_8X8, block,
4688 pd->pre[0].stride)) << 3];
Yunqing Wang342a3682016-02-16 14:33:18 -08004689
Yunqing Wange6e2d882016-03-10 11:07:50 -08004690 bestsme = cpi->find_fractional_mv_step(
4691 x, &tmp_mv,
4692 &ref_mv[id].as_mv,
4693 cpi->common.allow_high_precision_mv,
4694 x->errorperbit,
4695 &cpi->fn_ptr[bsize],
4696 0, cpi->sf.mv.subpel_iters_per_step,
4697 NULL,
4698 x->nmvjointcost, x->mvcost,
4699 &dis, &sse, second_pred,
4700 pw, ph, 1);
Yunqing Wang342a3682016-02-16 14:33:18 -08004701
Yunqing Wange6e2d882016-03-10 11:07:50 -08004702 // Restore the reference frames.
4703 pd->pre[0] = backup_pred;
4704 } else {
4705 (void) block;
4706 bestsme = cpi->find_fractional_mv_step(
4707 x, &tmp_mv,
4708 &ref_mv[id].as_mv,
4709 cpi->common.allow_high_precision_mv,
4710 x->errorperbit,
4711 &cpi->fn_ptr[bsize],
4712 0, cpi->sf.mv.subpel_iters_per_step,
4713 NULL,
4714 x->nmvjointcost, x->mvcost,
4715 &dis, &sse, second_pred,
4716 pw, ph, 0);
4717 }
Jingning Han3ee6db62015-08-05 19:00:31 -07004718 }
4719
4720 // Restore the pointer to the first (possibly scaled) prediction buffer.
4721 if (id)
4722 xd->plane[0].pre[0] = ref_yv12[0];
4723
4724 if (bestsme < last_besterr[id]) {
4725 frame_mv[refs[id]].as_mv = tmp_mv;
4726 last_besterr[id] = bestsme;
4727 } else {
4728 break;
4729 }
4730 }
4731
4732 *rate_mv = 0;
4733
4734 for (ref = 0; ref < 2; ++ref) {
4735 if (scaled_ref_frame[ref]) {
4736 // Restore the prediction frame pointers to their unscaled versions.
4737 int i;
4738 for (i = 0; i < MAX_MB_PLANE; i++)
4739 xd->plane[i].pre[ref] = backup_yv12[ref][i];
4740 }
4741
Yue Chen1ac85872016-01-07 15:13:52 -08004742#if CONFIG_EXT_INTER
4743 if (bsize >= BLOCK_8X8)
4744#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004745 *rate_mv += vp10_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08004746 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
4747 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yue Chen1ac85872016-01-07 15:13:52 -08004748#if CONFIG_EXT_INTER
4749 else
4750 *rate_mv += vp10_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
4751 &ref_mv_sub8x8[ref]->as_mv,
4752 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
4753#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004754 }
4755}
4756
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004757static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07004758 int_mv *best_ref_mv,
4759 int_mv *second_best_ref_mv,
4760 int64_t best_rd, int *returntotrate,
4761 int *returnyrate,
4762 int64_t *returndistortion,
4763 int *skippable, int64_t *psse,
4764 int mvthresh,
Yue Chen1ac85872016-01-07 15:13:52 -08004765#if CONFIG_EXT_INTER
4766 int_mv seg_mvs[4][2][MAX_REF_FRAMES],
4767 int_mv compound_seg_newmvs[4][2],
4768#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004769 int_mv seg_mvs[4][MAX_REF_FRAMES],
Yue Chen1ac85872016-01-07 15:13:52 -08004770#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004771 BEST_SEG_INFO *bsi_buf, int filter_idx,
4772 int mi_row, int mi_col) {
4773 int i;
4774 BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
4775 MACROBLOCKD *xd = &x->e_mbd;
4776 MODE_INFO *mi = xd->mi[0];
4777 MB_MODE_INFO *mbmi = &mi->mbmi;
4778 int mode_idx;
4779 int k, br = 0, idx, idy;
4780 int64_t bd = 0, block_sse = 0;
4781 PREDICTION_MODE this_mode;
Yaowu Xufc7cbd12015-08-13 09:36:53 -07004782 VP10_COMMON *cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07004783 struct macroblock_plane *const p = &x->plane[0];
4784 struct macroblockd_plane *const pd = &xd->plane[0];
4785 const int label_count = 4;
4786 int64_t this_segment_rd = 0;
4787 int label_mv_thresh;
4788 int segmentyrate = 0;
4789 const BLOCK_SIZE bsize = mbmi->sb_type;
4790 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
4791 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
4792 ENTROPY_CONTEXT t_above[2], t_left[2];
4793 int subpelmv = 1, have_ref = 0;
4794 const int has_second_rf = has_second_ref(mbmi);
4795 const int inter_mode_mask = cpi->sf.inter_mode_mask[bsize];
4796 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4797
4798 vp10_zero(*bsi);
4799
4800 bsi->segment_rd = best_rd;
4801 bsi->ref_mv[0] = best_ref_mv;
4802 bsi->ref_mv[1] = second_best_ref_mv;
4803 bsi->mvp.as_int = best_ref_mv->as_int;
4804 bsi->mvthresh = mvthresh;
4805
4806 for (i = 0; i < 4; i++)
4807 bsi->modes[i] = ZEROMV;
4808
4809 memcpy(t_above, pd->above_context, sizeof(t_above));
4810 memcpy(t_left, pd->left_context, sizeof(t_left));
4811
4812 // 64 makes this threshold really big effectively
4813 // making it so that we very rarely check mvs on
4814 // segments. setting this to 1 would make mv thresh
4815 // roughly equal to what it is for macroblocks
4816 label_mv_thresh = 1 * bsi->mvthresh / label_count;
4817
4818 // Segmentation method overheads
4819 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
4820 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
4821 // TODO(jingning,rbultje): rewrite the rate-distortion optimization
4822 // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
4823 int_mv mode_mv[MB_MODE_COUNT][2];
4824 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
4825 PREDICTION_MODE mode_selected = ZEROMV;
4826 int64_t best_rd = INT64_MAX;
4827 const int i = idy * 2 + idx;
4828 int ref;
Yue Chen1ac85872016-01-07 15:13:52 -08004829#if CONFIG_EXT_INTER
4830 int mv_idx;
4831 int_mv ref_mvs_sub8x8[2][2];
4832#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004833
4834 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
4835 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
Yue Chen1ac85872016-01-07 15:13:52 -08004836#if CONFIG_EXT_INTER
4837 int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
4838 vp10_update_mv_context(cm, xd, mi, frame, mv_ref_list, i,
4839 mi_row, mi_col, NULL);
4840#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004841 frame_mv[ZEROMV][frame].as_int = 0;
4842 vp10_append_sub8x8_mvs_for_idx(cm, xd, i, ref, mi_row, mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08004843#if CONFIG_EXT_INTER
4844 mv_ref_list,
4845#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004846 &frame_mv[NEARESTMV][frame],
Jingning Han40cedd62015-11-25 13:42:59 -08004847 &frame_mv[NEARMV][frame]);
Yue Chen1ac85872016-01-07 15:13:52 -08004848#if CONFIG_EXT_INTER
4849 mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
4850 mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
4851 vp10_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
4852 &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
Yue Chen968bbc72016-01-19 16:45:45 -08004853
4854 if (has_second_rf) {
4855 frame_mv[ZERO_ZEROMV][frame].as_int = 0;
4856 frame_mv[NEAREST_NEARESTMV][frame].as_int =
4857 frame_mv[NEARESTMV][frame].as_int;
4858
4859 if (ref == 0) {
4860 frame_mv[NEAREST_NEARMV][frame].as_int =
4861 frame_mv[NEARESTMV][frame].as_int;
4862 frame_mv[NEAR_NEARESTMV][frame].as_int =
4863 frame_mv[NEARMV][frame].as_int;
4864 frame_mv[NEAREST_NEWMV][frame].as_int =
4865 frame_mv[NEARESTMV][frame].as_int;
4866 frame_mv[NEAR_NEWMV][frame].as_int =
4867 frame_mv[NEARMV][frame].as_int;
4868 } else if (ref == 1) {
4869 frame_mv[NEAREST_NEARMV][frame].as_int =
4870 frame_mv[NEARMV][frame].as_int;
4871 frame_mv[NEAR_NEARESTMV][frame].as_int =
4872 frame_mv[NEARESTMV][frame].as_int;
4873 frame_mv[NEW_NEARESTMV][frame].as_int =
4874 frame_mv[NEARESTMV][frame].as_int;
4875 frame_mv[NEW_NEARMV][frame].as_int =
4876 frame_mv[NEARMV][frame].as_int;
4877 }
4878 }
Yue Chen1ac85872016-01-07 15:13:52 -08004879#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004880 }
4881
4882 // search for the best motion vector on this segment
Yue Chen1ac85872016-01-07 15:13:52 -08004883#if CONFIG_EXT_INTER
Yue Chen968bbc72016-01-19 16:45:45 -08004884 for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
4885 this_mode <= (has_second_rf ? NEW_NEWMV : NEWFROMNEARMV);
4886 ++this_mode) {
Yue Chen1ac85872016-01-07 15:13:52 -08004887#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004888 for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
Yue Chen1ac85872016-01-07 15:13:52 -08004889#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004890 const struct buf_2d orig_src = x->plane[0].src;
4891 struct buf_2d orig_pre[2];
4892
4893 mode_idx = INTER_OFFSET(this_mode);
Yue Chen1ac85872016-01-07 15:13:52 -08004894#if CONFIG_EXT_INTER
4895 mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
Yue Chen968bbc72016-01-19 16:45:45 -08004896
Yue Chen1ac85872016-01-07 15:13:52 -08004897 for (ref = 0; ref < 1 + has_second_rf; ++ref)
4898 bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[mv_idx][ref].as_int;
4899#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004900 bsi->rdstat[i][mode_idx].brdcost = INT64_MAX;
4901 if (!(inter_mode_mask & (1 << this_mode)))
4902 continue;
4903
Yue Chen968bbc72016-01-19 16:45:45 -08004904 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
4905#if CONFIG_REF_MV && CONFIG_EXT_INTER
4906 mbmi_ext->compound_mode_context,
4907#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4908 frame_mv,
Jingning Han387a10e2015-12-09 09:07:39 -08004909 this_mode, mbmi->ref_frame, bsize, i))
Jingning Han3ee6db62015-08-05 19:00:31 -07004910 continue;
4911
4912 memcpy(orig_pre, pd->pre, sizeof(orig_pre));
4913 memcpy(bsi->rdstat[i][mode_idx].ta, t_above,
4914 sizeof(bsi->rdstat[i][mode_idx].ta));
4915 memcpy(bsi->rdstat[i][mode_idx].tl, t_left,
4916 sizeof(bsi->rdstat[i][mode_idx].tl));
4917
4918 // motion search for newmv (single predictor case only)
Yue Chen1ac85872016-01-07 15:13:52 -08004919 if (!has_second_rf &&
4920#if CONFIG_EXT_INTER
4921 have_newmv_in_inter_mode(this_mode) &&
4922 seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV
4923#else
4924 this_mode == NEWMV &&
4925 seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV
4926#endif // CONFIG_EXT_INTER
4927 ) {
4928#if CONFIG_EXT_INTER
4929 MV *const new_mv = &mode_mv[this_mode][0].as_mv;
4930#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004931 MV *const new_mv = &mode_mv[NEWMV][0].as_mv;
Yue Chen1ac85872016-01-07 15:13:52 -08004932#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004933 int step_param = 0;
paulwilkins4e692bb2015-12-08 15:48:24 +00004934 int bestsme = INT_MAX;
Jingning Han3ee6db62015-08-05 19:00:31 -07004935 int sadpb = x->sadperbit4;
4936 MV mvp_full;
4937 int max_mv;
4938 int cost_list[5];
4939
4940 /* Is the best so far sufficiently good that we cant justify doing
4941 * and new motion search. */
4942 if (best_rd < label_mv_thresh)
4943 break;
4944
4945 if (cpi->oxcf.mode != BEST) {
Yue Chen1ac85872016-01-07 15:13:52 -08004946#if CONFIG_EXT_INTER
4947 bsi->mvp.as_int = bsi->ref_mv[0]->as_int;
4948#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004949 // use previous block's result as next block's MV predictor.
4950 if (i > 0) {
4951 bsi->mvp.as_int = mi->bmi[i - 1].as_mv[0].as_int;
4952 if (i == 2)
4953 bsi->mvp.as_int = mi->bmi[i - 2].as_mv[0].as_int;
4954 }
Yue Chen1ac85872016-01-07 15:13:52 -08004955#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004956 }
4957 if (i == 0)
4958 max_mv = x->max_mv_context[mbmi->ref_frame[0]];
4959 else
James Zern5e16d392015-08-17 18:19:22 -07004960 max_mv =
4961 VPXMAX(abs(bsi->mvp.as_mv.row), abs(bsi->mvp.as_mv.col)) >> 3;
Jingning Han3ee6db62015-08-05 19:00:31 -07004962
4963 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
4964 // Take wtd average of the step_params based on the last frame's
4965 // max mv magnitude and the best ref mvs of the current block for
4966 // the given reference.
4967 step_param = (vp10_init_search_range(max_mv) +
4968 cpi->mv_step_param) / 2;
4969 } else {
4970 step_param = cpi->mv_step_param;
4971 }
4972
4973 mvp_full.row = bsi->mvp.as_mv.row >> 3;
4974 mvp_full.col = bsi->mvp.as_mv.col >> 3;
4975
4976 if (cpi->sf.adaptive_motion_search) {
4977 mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
4978 mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
James Zern5e16d392015-08-17 18:19:22 -07004979 step_param = VPXMAX(step_param, 8);
Jingning Han3ee6db62015-08-05 19:00:31 -07004980 }
4981
4982 // adjust src pointer for this block
4983 mi_buf_shift(x, i);
4984
4985 vp10_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
4986
Jingning Han03c01bc2016-02-19 10:41:04 -08004987#if CONFIG_REF_MV
4988 vp10_set_mvcost(x, mbmi->ref_frame[0]);
4989#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07004990 bestsme = vp10_full_pixel_search(
4991 cpi, x, bsize, &mvp_full, step_param, sadpb,
4992 cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
4993 &bsi->ref_mv[0]->as_mv, new_mv,
4994 INT_MAX, 1);
4995
Jingning Han3ee6db62015-08-05 19:00:31 -07004996 if (bestsme < INT_MAX) {
4997 int distortion;
Yunqing Wange6e2d882016-03-10 11:07:50 -08004998 if (cpi->sf.use_upsampled_references) {
4999 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
5000 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
5001 // Use up-sampled reference frames.
5002 struct macroblockd_plane *const pd = &xd->plane[0];
5003 struct buf_2d backup_pred = pd->pre[0];
5004 const YV12_BUFFER_CONFIG *upsampled_ref =
5005 get_upsampled_ref(cpi, mbmi->ref_frame[0]);
Yunqing Wang342a3682016-02-16 14:33:18 -08005006
Yunqing Wange6e2d882016-03-10 11:07:50 -08005007 // Set pred for Y plane
5008 setup_pred_plane(&pd->pre[0], upsampled_ref->y_buffer,
5009 upsampled_ref->y_stride,
5010 (mi_row << 3), (mi_col << 3),
5011 NULL, pd->subsampling_x, pd->subsampling_y);
Yunqing Wang342a3682016-02-16 14:33:18 -08005012
Yunqing Wange6e2d882016-03-10 11:07:50 -08005013 // adjust pred pointer for this block
5014 pd->pre[0].buf =
5015 &pd->pre[0].buf[(vp10_raster_block_offset(BLOCK_8X8, i,
5016 pd->pre[0].stride)) << 3];
Yunqing Wang342a3682016-02-16 14:33:18 -08005017
Yunqing Wange6e2d882016-03-10 11:07:50 -08005018 cpi->find_fractional_mv_step(
5019 x,
5020 new_mv,
5021 &bsi->ref_mv[0]->as_mv,
5022 cm->allow_high_precision_mv,
5023 x->errorperbit, &cpi->fn_ptr[bsize],
5024 cpi->sf.mv.subpel_force_stop,
5025 cpi->sf.mv.subpel_iters_per_step,
5026 cond_cost_list(cpi, cost_list),
5027 x->nmvjointcost, x->mvcost,
5028 &distortion,
5029 &x->pred_sse[mbmi->ref_frame[0]],
5030 NULL, pw, ph, 1);
Yunqing Wang342a3682016-02-16 14:33:18 -08005031
Yunqing Wange6e2d882016-03-10 11:07:50 -08005032 // Restore the reference frames.
5033 pd->pre[0] = backup_pred;
5034 } else {
5035 cpi->find_fractional_mv_step(
5036 x,
5037 new_mv,
5038 &bsi->ref_mv[0]->as_mv,
5039 cm->allow_high_precision_mv,
5040 x->errorperbit, &cpi->fn_ptr[bsize],
5041 cpi->sf.mv.subpel_force_stop,
5042 cpi->sf.mv.subpel_iters_per_step,
5043 cond_cost_list(cpi, cost_list),
5044 x->nmvjointcost, x->mvcost,
5045 &distortion,
5046 &x->pred_sse[mbmi->ref_frame[0]],
5047 NULL, 0, 0, 0);
5048 }
Jingning Han3ee6db62015-08-05 19:00:31 -07005049
5050 // save motion search result for use in compound prediction
Yue Chen1ac85872016-01-07 15:13:52 -08005051#if CONFIG_EXT_INTER
5052 seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_mv = *new_mv;
5053#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005054 seg_mvs[i][mbmi->ref_frame[0]].as_mv = *new_mv;
Yue Chen1ac85872016-01-07 15:13:52 -08005055#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005056 }
5057
5058 if (cpi->sf.adaptive_motion_search)
5059 x->pred_mv[mbmi->ref_frame[0]] = *new_mv;
5060
5061 // restore src pointers
5062 mi_buf_restore(x, orig_src, orig_pre);
5063 }
5064
5065 if (has_second_rf) {
Yue Chen1ac85872016-01-07 15:13:52 -08005066#if CONFIG_EXT_INTER
5067 if (seg_mvs[i][mv_idx][mbmi->ref_frame[1]].as_int == INVALID_MV ||
5068 seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
5069#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005070 if (seg_mvs[i][mbmi->ref_frame[1]].as_int == INVALID_MV ||
5071 seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yue Chen1ac85872016-01-07 15:13:52 -08005072#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005073 continue;
5074 }
5075
Yue Chen968bbc72016-01-19 16:45:45 -08005076 if (has_second_rf &&
5077#if CONFIG_EXT_INTER
5078 this_mode == NEW_NEWMV &&
5079#else
5080 this_mode == NEWMV &&
5081#endif // CONFIG_EXT_INTER
Debargha Mukherjeebab29122016-02-26 00:18:03 -08005082 mbmi->interp_filter == EIGHTTAP_REGULAR) {
Jingning Han3ee6db62015-08-05 19:00:31 -07005083 // adjust src pointers
5084 mi_buf_shift(x, i);
5085 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
5086 int rate_mv;
5087 joint_motion_search(cpi, x, bsize, frame_mv[this_mode],
Yue Chen1ac85872016-01-07 15:13:52 -08005088 mi_row, mi_col,
5089#if CONFIG_EXT_INTER
5090 bsi->ref_mv,
5091 seg_mvs[i][mv_idx],
5092#else
5093 seg_mvs[i],
5094#endif // CONFIG_EXT_INTER
Yunqing Wang342a3682016-02-16 14:33:18 -08005095 &rate_mv, i);
Yue Chen1ac85872016-01-07 15:13:52 -08005096#if CONFIG_EXT_INTER
5097 compound_seg_newmvs[i][0].as_int =
5098 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
5099 compound_seg_newmvs[i][1].as_int =
5100 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
5101#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005102 seg_mvs[i][mbmi->ref_frame[0]].as_int =
5103 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
5104 seg_mvs[i][mbmi->ref_frame[1]].as_int =
5105 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08005106#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005107 }
5108 // restore src pointers
5109 mi_buf_restore(x, orig_src, orig_pre);
5110 }
5111
5112 bsi->rdstat[i][mode_idx].brate =
5113 set_and_cost_bmi_mvs(cpi, x, xd, i, this_mode, mode_mv[this_mode],
Yue Chen1ac85872016-01-07 15:13:52 -08005114 frame_mv,
5115#if CONFIG_EXT_INTER
5116 seg_mvs[i][mv_idx],
5117 compound_seg_newmvs[i],
5118#else
5119 seg_mvs[i],
5120#endif // CONFIG_EXT_INTER
5121 bsi->ref_mv,
Jingning Han3ee6db62015-08-05 19:00:31 -07005122 x->nmvjointcost, x->mvcost);
5123
5124 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5125 bsi->rdstat[i][mode_idx].mvs[ref].as_int =
5126 mode_mv[this_mode][ref].as_int;
5127 if (num_4x4_blocks_wide > 1)
5128 bsi->rdstat[i + 1][mode_idx].mvs[ref].as_int =
5129 mode_mv[this_mode][ref].as_int;
5130 if (num_4x4_blocks_high > 1)
5131 bsi->rdstat[i + 2][mode_idx].mvs[ref].as_int =
5132 mode_mv[this_mode][ref].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08005133#if CONFIG_EXT_INTER
5134 bsi->rdstat[i][mode_idx].ref_mv[ref].as_int =
5135 bsi->ref_mv[ref]->as_int;
5136 if (num_4x4_blocks_wide > 1)
5137 bsi->rdstat[i + 1][mode_idx].ref_mv[ref].as_int =
5138 bsi->ref_mv[ref]->as_int;
5139 if (num_4x4_blocks_high > 1)
5140 bsi->rdstat[i + 2][mode_idx].ref_mv[ref].as_int =
5141 bsi->ref_mv[ref]->as_int;
5142#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005143 }
5144
5145 // Trap vectors that reach beyond the UMV borders
5146 if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
5147 (has_second_rf &&
5148 mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
5149 continue;
5150
5151 if (filter_idx > 0) {
5152 BEST_SEG_INFO *ref_bsi = bsi_buf;
5153 subpelmv = 0;
5154 have_ref = 1;
5155
5156 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5157 subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
Yue Chen1ac85872016-01-07 15:13:52 -08005158#if CONFIG_EXT_INTER
5159 if (have_newmv_in_inter_mode(this_mode))
5160 have_ref &= (
5161 (mode_mv[this_mode][ref].as_int ==
5162 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int) &&
5163 (bsi->ref_mv[ref]->as_int ==
5164 ref_bsi->rdstat[i][mode_idx].ref_mv[ref].as_int));
5165 else
5166#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005167 have_ref &= mode_mv[this_mode][ref].as_int ==
5168 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
5169 }
5170
5171 if (filter_idx > 1 && !subpelmv && !have_ref) {
5172 ref_bsi = bsi_buf + 1;
5173 have_ref = 1;
5174 for (ref = 0; ref < 1 + has_second_rf; ++ref)
Yue Chen1ac85872016-01-07 15:13:52 -08005175#if CONFIG_EXT_INTER
5176 if (have_newmv_in_inter_mode(this_mode))
5177 have_ref &= (
5178 (mode_mv[this_mode][ref].as_int ==
5179 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int) &&
5180 (bsi->ref_mv[ref]->as_int ==
5181 ref_bsi->rdstat[i][mode_idx].ref_mv[ref].as_int));
5182 else
5183#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005184 have_ref &= mode_mv[this_mode][ref].as_int ==
5185 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
5186 }
5187
5188 if (!subpelmv && have_ref &&
5189 ref_bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) {
5190 memcpy(&bsi->rdstat[i][mode_idx], &ref_bsi->rdstat[i][mode_idx],
5191 sizeof(SEG_RDSTAT));
5192 if (num_4x4_blocks_wide > 1)
5193 bsi->rdstat[i + 1][mode_idx].eobs =
5194 ref_bsi->rdstat[i + 1][mode_idx].eobs;
5195 if (num_4x4_blocks_high > 1)
5196 bsi->rdstat[i + 2][mode_idx].eobs =
5197 ref_bsi->rdstat[i + 2][mode_idx].eobs;
5198
5199 if (bsi->rdstat[i][mode_idx].brdcost < best_rd) {
5200 mode_selected = this_mode;
5201 best_rd = bsi->rdstat[i][mode_idx].brdcost;
5202 }
5203 continue;
5204 }
5205 }
5206
5207 bsi->rdstat[i][mode_idx].brdcost =
5208 encode_inter_mb_segment(cpi, x,
5209 bsi->segment_rd - this_segment_rd, i,
5210 &bsi->rdstat[i][mode_idx].byrate,
5211 &bsi->rdstat[i][mode_idx].bdist,
5212 &bsi->rdstat[i][mode_idx].bsse,
5213 bsi->rdstat[i][mode_idx].ta,
5214 bsi->rdstat[i][mode_idx].tl,
Yaowu Xu7c514e22015-09-28 15:55:46 -07005215 idy, idx,
Jingning Han3ee6db62015-08-05 19:00:31 -07005216 mi_row, mi_col);
5217 if (bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) {
5218 bsi->rdstat[i][mode_idx].brdcost += RDCOST(x->rdmult, x->rddiv,
5219 bsi->rdstat[i][mode_idx].brate, 0);
5220 bsi->rdstat[i][mode_idx].brate += bsi->rdstat[i][mode_idx].byrate;
5221 bsi->rdstat[i][mode_idx].eobs = p->eobs[i];
5222 if (num_4x4_blocks_wide > 1)
5223 bsi->rdstat[i + 1][mode_idx].eobs = p->eobs[i + 1];
5224 if (num_4x4_blocks_high > 1)
5225 bsi->rdstat[i + 2][mode_idx].eobs = p->eobs[i + 2];
5226 }
5227
5228 if (bsi->rdstat[i][mode_idx].brdcost < best_rd) {
5229 mode_selected = this_mode;
5230 best_rd = bsi->rdstat[i][mode_idx].brdcost;
5231 }
5232 } /*for each 4x4 mode*/
5233
5234 if (best_rd == INT64_MAX) {
5235 int iy, midx;
5236 for (iy = i + 1; iy < 4; ++iy)
Yue Chen968bbc72016-01-19 16:45:45 -08005237#if CONFIG_EXT_INTER
5238 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
5239#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005240 for (midx = 0; midx < INTER_MODES; ++midx)
Yue Chen968bbc72016-01-19 16:45:45 -08005241#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005242 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
5243 bsi->segment_rd = INT64_MAX;
5244 return INT64_MAX;
5245 }
5246
5247 mode_idx = INTER_OFFSET(mode_selected);
5248 memcpy(t_above, bsi->rdstat[i][mode_idx].ta, sizeof(t_above));
5249 memcpy(t_left, bsi->rdstat[i][mode_idx].tl, sizeof(t_left));
5250
Yue Chen1ac85872016-01-07 15:13:52 -08005251#if CONFIG_EXT_INTER
5252 mv_idx = (mode_selected == NEWFROMNEARMV) ? 1 : 0;
5253 bsi->ref_mv[0]->as_int = bsi->rdstat[i][mode_idx].ref_mv[0].as_int;
5254 if (has_second_rf)
5255 bsi->ref_mv[1]->as_int = bsi->rdstat[i][mode_idx].ref_mv[1].as_int;
5256#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005257 set_and_cost_bmi_mvs(cpi, x, xd, i, mode_selected, mode_mv[mode_selected],
Yue Chen1ac85872016-01-07 15:13:52 -08005258 frame_mv,
5259#if CONFIG_EXT_INTER
5260 seg_mvs[i][mv_idx],
5261 compound_seg_newmvs[i],
5262#else
5263 seg_mvs[i],
5264#endif // CONFIG_EXT_INTER
5265 bsi->ref_mv, x->nmvjointcost, x->mvcost);
Jingning Han3ee6db62015-08-05 19:00:31 -07005266
5267 br += bsi->rdstat[i][mode_idx].brate;
5268 bd += bsi->rdstat[i][mode_idx].bdist;
5269 block_sse += bsi->rdstat[i][mode_idx].bsse;
5270 segmentyrate += bsi->rdstat[i][mode_idx].byrate;
5271 this_segment_rd += bsi->rdstat[i][mode_idx].brdcost;
5272
5273 if (this_segment_rd > bsi->segment_rd) {
5274 int iy, midx;
5275 for (iy = i + 1; iy < 4; ++iy)
Yue Chen968bbc72016-01-19 16:45:45 -08005276#if CONFIG_EXT_INTER
5277 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
5278#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005279 for (midx = 0; midx < INTER_MODES; ++midx)
Yue Chen968bbc72016-01-19 16:45:45 -08005280#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005281 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
5282 bsi->segment_rd = INT64_MAX;
5283 return INT64_MAX;
5284 }
5285 }
5286 } /* for each label */
5287
5288 bsi->r = br;
5289 bsi->d = bd;
5290 bsi->segment_yrate = segmentyrate;
5291 bsi->segment_rd = this_segment_rd;
5292 bsi->sse = block_sse;
5293
5294 // update the coding decisions
5295 for (k = 0; k < 4; ++k)
5296 bsi->modes[k] = mi->bmi[k].as_mode;
5297
5298 if (bsi->segment_rd > best_rd)
5299 return INT64_MAX;
5300 /* set it to the best */
5301 for (i = 0; i < 4; i++) {
5302 mode_idx = INTER_OFFSET(bsi->modes[i]);
5303 mi->bmi[i].as_mv[0].as_int = bsi->rdstat[i][mode_idx].mvs[0].as_int;
5304 if (has_second_ref(mbmi))
5305 mi->bmi[i].as_mv[1].as_int = bsi->rdstat[i][mode_idx].mvs[1].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08005306#if CONFIG_EXT_INTER
5307 mi->bmi[i].ref_mv[0].as_int = bsi->rdstat[i][mode_idx].ref_mv[0].as_int;
5308 if (has_second_rf)
5309 mi->bmi[i].ref_mv[1].as_int = bsi->rdstat[i][mode_idx].ref_mv[1].as_int;
5310#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005311 x->plane[0].eobs[i] = bsi->rdstat[i][mode_idx].eobs;
5312 mi->bmi[i].as_mode = bsi->modes[i];
5313 }
5314
5315 /*
5316 * used to set mbmi->mv.as_int
5317 */
5318 *returntotrate = bsi->r;
5319 *returndistortion = bsi->d;
5320 *returnyrate = bsi->segment_yrate;
5321 *skippable = vp10_is_skippable_in_plane(x, BLOCK_8X8, 0);
5322 *psse = bsi->sse;
5323 mbmi->mode = bsi->modes[3];
5324
5325 return bsi->segment_rd;
5326}
5327
Yaowu Xufc7cbd12015-08-13 09:36:53 -07005328static void estimate_ref_frame_costs(const VP10_COMMON *cm,
Jingning Han3ee6db62015-08-05 19:00:31 -07005329 const MACROBLOCKD *xd,
5330 int segment_id,
5331 unsigned int *ref_costs_single,
5332 unsigned int *ref_costs_comp,
5333 vpx_prob *comp_mode_p) {
5334 int seg_ref_active = segfeature_active(&cm->seg, segment_id,
5335 SEG_LVL_REF_FRAME);
5336 if (seg_ref_active) {
5337 memset(ref_costs_single, 0, MAX_REF_FRAMES * sizeof(*ref_costs_single));
5338 memset(ref_costs_comp, 0, MAX_REF_FRAMES * sizeof(*ref_costs_comp));
5339 *comp_mode_p = 128;
5340 } else {
5341 vpx_prob intra_inter_p = vp10_get_intra_inter_prob(cm, xd);
5342 vpx_prob comp_inter_p = 128;
5343
5344 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
5345 comp_inter_p = vp10_get_reference_mode_prob(cm, xd);
5346 *comp_mode_p = comp_inter_p;
5347 } else {
5348 *comp_mode_p = 128;
5349 }
5350
5351 ref_costs_single[INTRA_FRAME] = vp10_cost_bit(intra_inter_p, 0);
5352
5353 if (cm->reference_mode != COMPOUND_REFERENCE) {
5354 vpx_prob ref_single_p1 = vp10_get_pred_prob_single_ref_p1(cm, xd);
5355 vpx_prob ref_single_p2 = vp10_get_pred_prob_single_ref_p2(cm, xd);
Zoe Liu3ec16012015-11-12 02:12:17 -08005356#if CONFIG_EXT_REFS
5357 vpx_prob ref_single_p3 = vp10_get_pred_prob_single_ref_p3(cm, xd);
5358 vpx_prob ref_single_p4 = vp10_get_pred_prob_single_ref_p4(cm, xd);
5359 vpx_prob ref_single_p5 = vp10_get_pred_prob_single_ref_p5(cm, xd);
5360#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07005361 unsigned int base_cost = vp10_cost_bit(intra_inter_p, 1);
5362
Zoe Liu3ec16012015-11-12 02:12:17 -08005363 ref_costs_single[LAST_FRAME] =
5364#if CONFIG_EXT_REFS
5365 ref_costs_single[LAST2_FRAME] =
5366 ref_costs_single[LAST3_FRAME] =
5367 ref_costs_single[LAST4_FRAME] =
5368#endif // CONFIG_EXT_REFS
5369 ref_costs_single[GOLDEN_FRAME] =
Jingning Han3ee6db62015-08-05 19:00:31 -07005370 ref_costs_single[ALTREF_FRAME] = base_cost;
Zoe Liu3ec16012015-11-12 02:12:17 -08005371
5372#if CONFIG_EXT_REFS
5373 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p1, 0);
5374 ref_costs_single[LAST2_FRAME] += vp10_cost_bit(ref_single_p1, 0);
5375 ref_costs_single[LAST3_FRAME] += vp10_cost_bit(ref_single_p1, 0);
5376 ref_costs_single[LAST4_FRAME] += vp10_cost_bit(ref_single_p1, 0);
5377 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p1, 1);
5378 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p1, 1);
5379
5380 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p3, 0);
5381 ref_costs_single[LAST2_FRAME] += vp10_cost_bit(ref_single_p3, 0);
5382 ref_costs_single[LAST3_FRAME] += vp10_cost_bit(ref_single_p3, 1);
5383 ref_costs_single[LAST4_FRAME] += vp10_cost_bit(ref_single_p3, 1);
5384 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p2, 0);
5385 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p2, 1);
5386
5387 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p4, 0);
5388 ref_costs_single[LAST2_FRAME] += vp10_cost_bit(ref_single_p4, 1);
5389 ref_costs_single[LAST3_FRAME] += vp10_cost_bit(ref_single_p5, 0);
5390 ref_costs_single[LAST4_FRAME] += vp10_cost_bit(ref_single_p5, 1);
5391#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005392 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p1, 0);
5393 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p1, 1);
5394 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p1, 1);
5395 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p2, 0);
5396 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p2, 1);
Zoe Liu3ec16012015-11-12 02:12:17 -08005397#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07005398 } else {
5399 ref_costs_single[LAST_FRAME] = 512;
Zoe Liu3ec16012015-11-12 02:12:17 -08005400#if CONFIG_EXT_REFS
5401 ref_costs_single[LAST2_FRAME] = 512;
5402 ref_costs_single[LAST3_FRAME] = 512;
5403 ref_costs_single[LAST4_FRAME] = 512;
5404#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07005405 ref_costs_single[GOLDEN_FRAME] = 512;
5406 ref_costs_single[ALTREF_FRAME] = 512;
5407 }
Zoe Liu3ec16012015-11-12 02:12:17 -08005408
Jingning Han3ee6db62015-08-05 19:00:31 -07005409 if (cm->reference_mode != SINGLE_REFERENCE) {
5410 vpx_prob ref_comp_p = vp10_get_pred_prob_comp_ref_p(cm, xd);
Zoe Liu3ec16012015-11-12 02:12:17 -08005411#if CONFIG_EXT_REFS
5412 vpx_prob ref_comp_p1 = vp10_get_pred_prob_comp_ref_p1(cm, xd);
5413 vpx_prob ref_comp_p2 = vp10_get_pred_prob_comp_ref_p2(cm, xd);
5414 vpx_prob ref_comp_p3 = vp10_get_pred_prob_comp_ref_p3(cm, xd);
5415#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07005416 unsigned int base_cost = vp10_cost_bit(intra_inter_p, 1);
5417
Zoe Liu3ec16012015-11-12 02:12:17 -08005418 ref_costs_comp[LAST_FRAME] =
5419#if CONFIG_EXT_REFS
5420 ref_costs_comp[LAST2_FRAME] =
5421 ref_costs_comp[LAST3_FRAME] =
5422 ref_costs_comp[LAST4_FRAME] =
5423#endif // CONFIG_EXT_REFS
5424 ref_costs_comp[GOLDEN_FRAME] = base_cost;
5425
5426#if CONFIG_EXT_REFS
5427 ref_costs_comp[LAST_FRAME] += vp10_cost_bit(ref_comp_p, 0);
5428 ref_costs_comp[LAST2_FRAME] += vp10_cost_bit(ref_comp_p, 0);
5429 ref_costs_comp[LAST3_FRAME] += vp10_cost_bit(ref_comp_p, 1);
5430 ref_costs_comp[LAST4_FRAME] += vp10_cost_bit(ref_comp_p, 1);
5431 ref_costs_comp[GOLDEN_FRAME] += vp10_cost_bit(ref_comp_p, 1);
5432
5433 ref_costs_comp[LAST_FRAME] += vp10_cost_bit(ref_comp_p1, 1);
5434 ref_costs_comp[LAST2_FRAME] += vp10_cost_bit(ref_comp_p1, 0);
5435 ref_costs_comp[LAST3_FRAME] += vp10_cost_bit(ref_comp_p2, 0);
5436 ref_costs_comp[LAST4_FRAME] += vp10_cost_bit(ref_comp_p2, 0);
5437 ref_costs_comp[GOLDEN_FRAME] += vp10_cost_bit(ref_comp_p2, 1);
5438
5439 ref_costs_comp[LAST3_FRAME] += vp10_cost_bit(ref_comp_p3, 1);
5440 ref_costs_comp[LAST4_FRAME] += vp10_cost_bit(ref_comp_p3, 0);
5441#else
5442 ref_costs_comp[LAST_FRAME] += vp10_cost_bit(ref_comp_p, 0);
5443 ref_costs_comp[GOLDEN_FRAME] += vp10_cost_bit(ref_comp_p, 1);
5444#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07005445 } else {
5446 ref_costs_comp[LAST_FRAME] = 512;
Zoe Liu3ec16012015-11-12 02:12:17 -08005447#if CONFIG_EXT_REFS
5448 ref_costs_comp[LAST2_FRAME] = 512;
5449 ref_costs_comp[LAST3_FRAME] = 512;
5450 ref_costs_comp[LAST4_FRAME] = 512;
5451#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07005452 ref_costs_comp[GOLDEN_FRAME] = 512;
5453 }
5454 }
5455}
5456
5457static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
5458 int mode_index,
5459 int64_t comp_pred_diff[REFERENCE_MODES],
5460 int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS],
5461 int skippable) {
5462 MACROBLOCKD *const xd = &x->e_mbd;
5463
5464 // Take a snapshot of the coding context so it can be
5465 // restored if we decide to encode this way
5466 ctx->skip = x->skip;
5467 ctx->skippable = skippable;
5468 ctx->best_mode_index = mode_index;
5469 ctx->mic = *xd->mi[0];
5470 ctx->mbmi_ext = *x->mbmi_ext;
5471 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
5472 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
5473 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
5474
5475 memcpy(ctx->best_filter_diff, best_filter_diff,
5476 sizeof(*best_filter_diff) * SWITCHABLE_FILTER_CONTEXTS);
5477}
5478
Zoe Liu3ec16012015-11-12 02:12:17 -08005479static void setup_buffer_inter(
5480 VP10_COMP *cpi, MACROBLOCK *x,
5481 MV_REFERENCE_FRAME ref_frame,
5482 BLOCK_SIZE block_size,
5483 int mi_row, int mi_col,
5484 int_mv frame_nearest_mv[MAX_REF_FRAMES],
5485 int_mv frame_near_mv[MAX_REF_FRAMES],
5486 struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE]) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07005487 const VP10_COMMON *cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07005488 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
5489 MACROBLOCKD *const xd = &x->e_mbd;
5490 MODE_INFO *const mi = xd->mi[0];
5491 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
5492 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
5493 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
5494
5495 assert(yv12 != NULL);
5496
5497 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
5498 // use the UV scaling factors.
5499 vp10_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
5500
5501 // Gets an initial list of candidate vectors from neighbours and orders them
Jingning Hane5c57c52015-11-23 15:05:18 -08005502 vp10_find_mv_refs(cm, xd, mi, ref_frame,
5503#if CONFIG_REF_MV
5504 &mbmi_ext->ref_mv_count[ref_frame],
5505 mbmi_ext->ref_mv_stack[ref_frame],
Yue Chen968bbc72016-01-19 16:45:45 -08005506#if CONFIG_EXT_INTER
5507 mbmi_ext->compound_mode_context,
5508#endif // CONFIG_EXT_INTER
Jingning Hane5c57c52015-11-23 15:05:18 -08005509#endif
5510 candidates, mi_row, mi_col,
5511 NULL, NULL, mbmi_ext->mode_context);
Jingning Han3ee6db62015-08-05 19:00:31 -07005512
5513 // Candidate refinement carried out at encoder and decoder
Ronald S. Bultje5b4805d2015-10-02 11:51:54 -04005514 vp10_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
5515 &frame_nearest_mv[ref_frame],
5516 &frame_near_mv[ref_frame]);
Jingning Han3ee6db62015-08-05 19:00:31 -07005517
5518 // Further refinement that is encode side only to test the top few candidates
5519 // in full and choose the best as the centre point for subsequent searches.
5520 // The current implementation doesn't support scaling.
5521 if (!vp10_is_scaled(sf) && block_size >= BLOCK_8X8)
5522 vp10_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride,
5523 ref_frame, block_size);
5524}
5525
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005526static void single_motion_search(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07005527 BLOCK_SIZE bsize,
5528 int mi_row, int mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08005529#if CONFIG_EXT_INTER
5530 int ref_idx,
5531 int mv_idx,
5532#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005533 int_mv *tmp_mv, int *rate_mv) {
5534 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xufc7cbd12015-08-13 09:36:53 -07005535 const VP10_COMMON *cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07005536 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5537 struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0, 0}};
5538 int bestsme = INT_MAX;
5539 int step_param;
5540 int sadpb = x->sadperbit16;
5541 MV mvp_full;
Yue Chen1ac85872016-01-07 15:13:52 -08005542#if CONFIG_EXT_INTER
5543 int ref = mbmi->ref_frame[ref_idx];
5544 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
5545#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005546 int ref = mbmi->ref_frame[0];
5547 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08005548 int ref_idx = 0;
Yue Chen1ac85872016-01-07 15:13:52 -08005549#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005550
5551 int tmp_col_min = x->mv_col_min;
5552 int tmp_col_max = x->mv_col_max;
5553 int tmp_row_min = x->mv_row_min;
5554 int tmp_row_max = x->mv_row_max;
5555 int cost_list[5];
5556
5557 const YV12_BUFFER_CONFIG *scaled_ref_frame = vp10_get_scaled_ref_frame(cpi,
5558 ref);
5559
5560 MV pred_mv[3];
5561 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
5562 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
5563 pred_mv[2] = x->pred_mv[ref];
5564
Jingning Han03c01bc2016-02-19 10:41:04 -08005565#if CONFIG_REF_MV
5566 vp10_set_mvcost(x, ref);
5567#endif
5568
Jingning Han3ee6db62015-08-05 19:00:31 -07005569 if (scaled_ref_frame) {
5570 int i;
5571 // Swap out the reference frame for a version that's been scaled to
5572 // match the resolution of the current frame, allowing the existing
5573 // motion search code to be used without additional modifications.
5574 for (i = 0; i < MAX_MB_PLANE; i++)
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08005575 backup_yv12[i] = xd->plane[i].pre[ref_idx];
Jingning Han3ee6db62015-08-05 19:00:31 -07005576
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08005577 vp10_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Jingning Han3ee6db62015-08-05 19:00:31 -07005578 }
5579
5580 vp10_set_mv_search_range(x, &ref_mv);
5581
5582 // Work out the size of the first step in the mv step search.
James Zern5e16d392015-08-17 18:19:22 -07005583 // 0 here is maximum length first step. 1 is VPXMAX >> 1 etc.
Jingning Han3ee6db62015-08-05 19:00:31 -07005584 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
5585 // Take wtd average of the step_params based on the last frame's
5586 // max mv magnitude and that based on the best ref mvs of the current
5587 // block for the given reference.
5588 step_param = (vp10_init_search_range(x->max_mv_context[ref]) +
5589 cpi->mv_step_param) / 2;
5590 } else {
5591 step_param = cpi->mv_step_param;
5592 }
5593
5594 if (cpi->sf.adaptive_motion_search && bsize < BLOCK_64X64) {
James Zern5e16d392015-08-17 18:19:22 -07005595 int boffset =
5596 2 * (b_width_log2_lookup[BLOCK_64X64] -
5597 VPXMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
5598 step_param = VPXMAX(step_param, boffset);
Jingning Han3ee6db62015-08-05 19:00:31 -07005599 }
5600
5601 if (cpi->sf.adaptive_motion_search) {
5602 int bwl = b_width_log2_lookup[bsize];
5603 int bhl = b_height_log2_lookup[bsize];
5604 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
5605
5606 if (tlevel < 5)
5607 step_param += 2;
5608
5609 // prev_mv_sad is not setup for dynamically scaled frames.
5610 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
5611 int i;
5612 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
5613 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
5614 x->pred_mv[ref].row = 0;
5615 x->pred_mv[ref].col = 0;
5616 tmp_mv->as_int = INVALID_MV;
5617
5618 if (scaled_ref_frame) {
5619 int i;
5620 for (i = 0; i < MAX_MB_PLANE; ++i)
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08005621 xd->plane[i].pre[ref_idx] = backup_yv12[i];
Jingning Han3ee6db62015-08-05 19:00:31 -07005622 }
5623 return;
5624 }
5625 }
5626 }
5627 }
5628
5629 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
5630
5631 mvp_full.col >>= 3;
5632 mvp_full.row >>= 3;
5633
5634 bestsme = vp10_full_pixel_search(cpi, x, bsize, &mvp_full, step_param, sadpb,
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08005635 cond_cost_list(cpi, cost_list),
5636 &ref_mv, &tmp_mv->as_mv, INT_MAX, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07005637
5638 x->mv_col_min = tmp_col_min;
5639 x->mv_col_max = tmp_col_max;
5640 x->mv_row_min = tmp_row_min;
5641 x->mv_row_max = tmp_row_max;
5642
5643 if (bestsme < INT_MAX) {
5644 int dis; /* TODO: use dis in distortion calculation later. */
Yunqing Wange6e2d882016-03-10 11:07:50 -08005645 if (cpi->sf.use_upsampled_references) {
5646 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
5647 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
5648 // Use up-sampled reference frames.
5649 struct macroblockd_plane *const pd = &xd->plane[0];
5650 struct buf_2d backup_pred = pd->pre[ref_idx];
5651 const YV12_BUFFER_CONFIG *upsampled_ref = get_upsampled_ref(cpi, ref);
Yunqing Wang342a3682016-02-16 14:33:18 -08005652
Yunqing Wange6e2d882016-03-10 11:07:50 -08005653 // Set pred for Y plane
5654 setup_pred_plane(&pd->pre[ref_idx], upsampled_ref->y_buffer,
5655 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3),
5656 NULL, pd->subsampling_x, pd->subsampling_y);
Yunqing Wang342a3682016-02-16 14:33:18 -08005657
Yunqing Wange6e2d882016-03-10 11:07:50 -08005658 bestsme = cpi->find_fractional_mv_step(x, &tmp_mv->as_mv, &ref_mv,
5659 cm->allow_high_precision_mv,
5660 x->errorperbit,
5661 &cpi->fn_ptr[bsize],
5662 cpi->sf.mv.subpel_force_stop,
5663 cpi->sf.mv.subpel_iters_per_step,
5664 cond_cost_list(cpi, cost_list),
5665 x->nmvjointcost, x->mvcost,
5666 &dis, &x->pred_sse[ref], NULL,
5667 pw, ph, 1);
Yunqing Wang342a3682016-02-16 14:33:18 -08005668
Yunqing Wange6e2d882016-03-10 11:07:50 -08005669 // Restore the reference frames.
5670 pd->pre[ref_idx] = backup_pred;
5671 } else {
5672 cpi->find_fractional_mv_step(x, &tmp_mv->as_mv, &ref_mv,
5673 cm->allow_high_precision_mv,
5674 x->errorperbit,
5675 &cpi->fn_ptr[bsize],
5676 cpi->sf.mv.subpel_force_stop,
5677 cpi->sf.mv.subpel_iters_per_step,
5678 cond_cost_list(cpi, cost_list),
5679 x->nmvjointcost, x->mvcost,
5680 &dis, &x->pred_sse[ref], NULL, 0, 0, 0);
5681 }
Jingning Han3ee6db62015-08-05 19:00:31 -07005682 }
5683 *rate_mv = vp10_mv_bit_cost(&tmp_mv->as_mv, &ref_mv,
5684 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5685
5686 if (cpi->sf.adaptive_motion_search)
5687 x->pred_mv[ref] = tmp_mv->as_mv;
5688
5689 if (scaled_ref_frame) {
5690 int i;
5691 for (i = 0; i < MAX_MB_PLANE; i++)
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08005692 xd->plane[i].pre[ref_idx] = backup_yv12[i];
Jingning Han3ee6db62015-08-05 19:00:31 -07005693 }
5694}
5695
Jingning Han3ee6db62015-08-05 19:00:31 -07005696static INLINE void restore_dst_buf(MACROBLOCKD *xd,
5697 uint8_t *orig_dst[MAX_MB_PLANE],
5698 int orig_dst_stride[MAX_MB_PLANE]) {
5699 int i;
5700 for (i = 0; i < MAX_MB_PLANE; i++) {
5701 xd->plane[i].dst.buf = orig_dst[i];
5702 xd->plane[i].dst.stride = orig_dst_stride[i];
5703 }
5704}
5705
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08005706#if CONFIG_EXT_INTER
5707static void do_masked_motion_search(VP10_COMP *cpi, MACROBLOCK *x,
5708 const uint8_t *mask, int mask_stride,
5709 BLOCK_SIZE bsize,
5710 int mi_row, int mi_col,
5711 int_mv *tmp_mv, int *rate_mv,
5712 int ref_idx,
5713 int mv_idx) {
5714 MACROBLOCKD *xd = &x->e_mbd;
5715 const VP10_COMMON *cm = &cpi->common;
5716 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5717 struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0, 0}};
5718 int bestsme = INT_MAX;
5719 int step_param;
5720 int sadpb = x->sadperbit16;
5721 MV mvp_full;
5722 int ref = mbmi->ref_frame[ref_idx];
5723 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
5724
5725 int tmp_col_min = x->mv_col_min;
5726 int tmp_col_max = x->mv_col_max;
5727 int tmp_row_min = x->mv_row_min;
5728 int tmp_row_max = x->mv_row_max;
5729
5730 const YV12_BUFFER_CONFIG *scaled_ref_frame =
5731 vp10_get_scaled_ref_frame(cpi, ref);
5732
5733 MV pred_mv[3];
5734 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
5735 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
5736 pred_mv[2] = x->pred_mv[ref];
5737
5738#if CONFIG_REF_MV
5739 vp10_set_mvcost(x, ref);
5740#endif
5741
5742 if (scaled_ref_frame) {
5743 int i;
5744 // Swap out the reference frame for a version that's been scaled to
5745 // match the resolution of the current frame, allowing the existing
5746 // motion search code to be used without additional modifications.
5747 for (i = 0; i < MAX_MB_PLANE; i++)
5748 backup_yv12[i] = xd->plane[i].pre[ref_idx];
5749
5750 vp10_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
5751 }
5752
5753 vp10_set_mv_search_range(x, &ref_mv);
5754
5755 // Work out the size of the first step in the mv step search.
5756 // 0 here is maximum length first step. 1 is MAX >> 1 etc.
5757 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
5758 // Take wtd average of the step_params based on the last frame's
5759 // max mv magnitude and that based on the best ref mvs of the current
5760 // block for the given reference.
5761 step_param = (vp10_init_search_range(x->max_mv_context[ref]) +
5762 cpi->mv_step_param) / 2;
5763 } else {
5764 step_param = cpi->mv_step_param;
5765 }
5766
5767 // TODO(debargha): is show_frame needed here?
5768 if (cpi->sf.adaptive_motion_search && bsize < BLOCK_LARGEST &&
5769 cm->show_frame) {
5770 int boffset = 2 * (b_width_log2_lookup[BLOCK_LARGEST] -
5771 VPXMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
5772 step_param = VPXMAX(step_param, boffset);
5773 }
5774
5775 if (cpi->sf.adaptive_motion_search) {
5776 int bwl = b_width_log2_lookup[bsize];
5777 int bhl = b_height_log2_lookup[bsize];
5778 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
5779
5780 if (tlevel < 5)
5781 step_param += 2;
5782
5783 // prev_mv_sad is not setup for dynamically scaled frames.
5784 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
5785 int i;
5786 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
5787 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
5788 x->pred_mv[ref].row = 0;
5789 x->pred_mv[ref].col = 0;
5790 tmp_mv->as_int = INVALID_MV;
5791
5792 if (scaled_ref_frame) {
5793 int i;
5794 for (i = 0; i < MAX_MB_PLANE; ++i)
5795 xd->plane[i].pre[ref_idx] = backup_yv12[i];
5796 }
5797 return;
5798 }
5799 }
5800 }
5801 }
5802
5803 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
5804
5805 mvp_full.col >>= 3;
5806 mvp_full.row >>= 3;
5807
5808 bestsme = vp10_masked_full_pixel_diamond(cpi, x, mask, mask_stride,
5809 &mvp_full, step_param, sadpb,
5810 MAX_MVSEARCH_STEPS - 1 - step_param,
5811 1, &cpi->fn_ptr[bsize],
5812 &ref_mv, &tmp_mv->as_mv, ref_idx);
5813
5814 x->mv_col_min = tmp_col_min;
5815 x->mv_col_max = tmp_col_max;
5816 x->mv_row_min = tmp_row_min;
5817 x->mv_row_max = tmp_row_max;
5818
5819 if (bestsme < INT_MAX) {
5820 int dis; /* TODO: use dis in distortion calculation later. */
5821 vp10_find_best_masked_sub_pixel_tree(x, mask, mask_stride,
5822 &tmp_mv->as_mv, &ref_mv,
5823 cm->allow_high_precision_mv,
5824 x->errorperbit,
5825 &cpi->fn_ptr[bsize],
5826 cpi->sf.mv.subpel_force_stop,
5827 cpi->sf.mv.subpel_iters_per_step,
5828 x->nmvjointcost, x->mvcost,
5829 &dis, &x->pred_sse[ref], ref_idx);
5830 }
5831 *rate_mv = vp10_mv_bit_cost(&tmp_mv->as_mv, &ref_mv,
5832 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5833
5834 if (cpi->sf.adaptive_motion_search && cm->show_frame)
5835 x->pred_mv[ref] = tmp_mv->as_mv;
5836
5837 if (scaled_ref_frame) {
5838 int i;
5839 for (i = 0; i < MAX_MB_PLANE; i++)
5840 xd->plane[i].pre[ref_idx] = backup_yv12[i];
5841 }
5842}
5843
5844static void do_masked_motion_search_indexed(VP10_COMP *cpi, MACROBLOCK *x,
5845 int wedge_index,
5846 BLOCK_SIZE bsize,
5847 int mi_row, int mi_col,
5848 int_mv *tmp_mv, int *rate_mv,
5849 int mv_idx[2],
5850 int which) {
5851 // NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both
5852 MACROBLOCKD *xd = &x->e_mbd;
5853 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5854 BLOCK_SIZE sb_type = mbmi->sb_type;
5855 int w = (4 << b_width_log2_lookup[sb_type]);
5856 int h = (4 << b_height_log2_lookup[sb_type]);
5857 const uint8_t *mask;
5858 const int mask_stride = MASK_MASTER_STRIDE;
5859 mask = vp10_get_soft_mask(wedge_index, sb_type, h, w);
5860
5861 if (which == 0 || which == 2)
5862 do_masked_motion_search(cpi, x, mask, mask_stride, bsize,
5863 mi_row, mi_col, &tmp_mv[0], &rate_mv[0],
5864 0, mv_idx[0]);
5865
5866 if (which == 1 || which == 2) {
5867 // get the negative mask
5868 mask = vp10_get_soft_mask(wedge_index ^ 1, sb_type, h, w);
5869 do_masked_motion_search(cpi, x, mask, mask_stride, bsize,
5870 mi_row, mi_col, &tmp_mv[1], &rate_mv[1],
5871 1, mv_idx[1]);
5872 }
5873}
5874#endif // CONFIG_EXT_INTER
5875
Jingning Han3ee6db62015-08-05 19:00:31 -07005876// In some situations we want to discount tha pparent cost of a new motion
5877// vector. Where there is a subtle motion field and especially where there is
5878// low spatial complexity then it can be hard to cover the cost of a new motion
5879// vector in a single block, even if that motion vector reduces distortion.
5880// However, once established that vector may be usable through the nearest and
5881// near mv modes to reduce distortion in subsequent blocks and also improve
5882// visual quality.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005883static int discount_newmv_test(const VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07005884 int this_mode,
5885 int_mv this_mv,
5886 int_mv (*mode_mv)[MAX_REF_FRAMES],
5887 int ref_frame) {
5888 return (!cpi->rc.is_src_frame_alt_ref &&
5889 (this_mode == NEWMV) &&
5890 (this_mv.as_int != 0) &&
5891 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
5892 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
5893 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
5894 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
5895}
5896
Ronald S. Bultje5b4805d2015-10-02 11:51:54 -04005897#define LEFT_TOP_MARGIN ((VP9_ENC_BORDER_IN_PIXELS - VP9_INTERP_EXTEND) << 3)
5898#define RIGHT_BOTTOM_MARGIN ((VP9_ENC_BORDER_IN_PIXELS -\
5899 VP9_INTERP_EXTEND) << 3)
5900
5901// TODO(jingning): this mv clamping function should be block size dependent.
5902static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
5903 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
5904 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
5905 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
5906 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
5907}
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08005908
Angie Chiangc0035cc2016-02-10 14:20:56 -08005909static INTERP_FILTER predict_interp_filter(const VP10_COMP *cpi,
5910 const MACROBLOCK *x,
5911 const BLOCK_SIZE bsize,
5912 const int mi_row,
5913 const int mi_col,
5914 INTERP_FILTER
5915 (*single_filter)[MAX_REF_FRAMES]
5916 ) {
Jingning Han3ee6db62015-08-05 19:00:31 -07005917 INTERP_FILTER best_filter = SWITCHABLE;
Angie Chiangc0035cc2016-02-10 14:20:56 -08005918 const VP10_COMMON *cm = &cpi->common;
5919 const MACROBLOCKD *xd = &x->e_mbd;
Jingning Han3ee6db62015-08-05 19:00:31 -07005920 int bsl = mi_width_log2_lookup[bsize];
5921 int pred_filter_search = cpi->sf.cb_pred_filter_search ?
5922 (((mi_row + mi_col) >> bsl) +
Yue Chend1cad9c2016-01-27 14:18:53 -08005923 get_chessboard_index(cm->current_video_frame)) & 0x1 : 0;
Angie Chiangc0035cc2016-02-10 14:20:56 -08005924 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5925 const int is_comp_pred = has_second_ref(mbmi);
5926 const int this_mode = mbmi->mode;
5927 int refs[2] = { mbmi->ref_frame[0],
Yue Chend1cad9c2016-01-27 14:18:53 -08005928 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Jingning Han3ee6db62015-08-05 19:00:31 -07005929 if (pred_filter_search) {
5930 INTERP_FILTER af = SWITCHABLE, lf = SWITCHABLE;
5931 if (xd->up_available)
5932 af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
5933 if (xd->left_available)
5934 lf = xd->mi[-1]->mbmi.interp_filter;
5935
Yue Chen1ac85872016-01-07 15:13:52 -08005936#if CONFIG_EXT_INTER
Yue Chen968bbc72016-01-19 16:45:45 -08005937 if ((this_mode != NEWMV && this_mode != NEWFROMNEARMV &&
5938 this_mode != NEW_NEWMV) || (af == lf))
Yue Chen1ac85872016-01-07 15:13:52 -08005939#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005940 if ((this_mode != NEWMV) || (af == lf))
Yue Chen1ac85872016-01-07 15:13:52 -08005941#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005942 best_filter = af;
5943 }
Jingning Han3ee6db62015-08-05 19:00:31 -07005944 if (is_comp_pred) {
Jingning Han3ee6db62015-08-05 19:00:31 -07005945 if (cpi->sf.adaptive_mode_search) {
Yue Chen968bbc72016-01-19 16:45:45 -08005946#if CONFIG_EXT_INTER
5947 switch (this_mode) {
5948 case NEAREST_NEARESTMV:
5949 if (single_filter[NEARESTMV][refs[0]] ==
5950 single_filter[NEARESTMV][refs[1]])
5951 best_filter = single_filter[NEARESTMV][refs[0]];
5952 break;
5953 case NEAREST_NEARMV:
5954 if (single_filter[NEARESTMV][refs[0]] ==
5955 single_filter[NEARMV][refs[1]])
5956 best_filter = single_filter[NEARESTMV][refs[0]];
5957 break;
5958 case NEAR_NEARESTMV:
5959 if (single_filter[NEARMV][refs[0]] ==
5960 single_filter[NEARESTMV][refs[1]])
5961 best_filter = single_filter[NEARMV][refs[0]];
5962 break;
5963 case ZERO_ZEROMV:
5964 if (single_filter[ZEROMV][refs[0]] ==
5965 single_filter[ZEROMV][refs[1]])
5966 best_filter = single_filter[ZEROMV][refs[0]];
5967 break;
5968 case NEW_NEWMV:
5969 if (single_filter[NEWMV][refs[0]] ==
5970 single_filter[NEWMV][refs[1]])
5971 best_filter = single_filter[NEWMV][refs[0]];
5972 break;
5973 case NEAREST_NEWMV:
5974 if (single_filter[NEARESTMV][refs[0]] ==
5975 single_filter[NEWMV][refs[1]])
5976 best_filter = single_filter[NEARESTMV][refs[0]];
5977 break;
5978 case NEAR_NEWMV:
5979 if (single_filter[NEARMV][refs[0]] ==
5980 single_filter[NEWMV][refs[1]])
5981 best_filter = single_filter[NEARMV][refs[0]];
5982 break;
5983 case NEW_NEARESTMV:
5984 if (single_filter[NEWMV][refs[0]] ==
5985 single_filter[NEARESTMV][refs[1]])
5986 best_filter = single_filter[NEWMV][refs[0]];
5987 break;
5988 case NEW_NEARMV:
5989 if (single_filter[NEWMV][refs[0]] ==
5990 single_filter[NEARMV][refs[1]])
5991 best_filter = single_filter[NEWMV][refs[0]];
5992 break;
5993 default:
5994 if (single_filter[this_mode][refs[0]] ==
5995 single_filter[this_mode][refs[1]])
5996 best_filter = single_filter[this_mode][refs[0]];
5997 break;
5998 }
5999#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006000 if (single_filter[this_mode][refs[0]] ==
6001 single_filter[this_mode][refs[1]])
6002 best_filter = single_filter[this_mode][refs[0]];
Yue Chen968bbc72016-01-19 16:45:45 -08006003#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006004 }
6005 }
Angie Chiangc0035cc2016-02-10 14:20:56 -08006006 if (cm->interp_filter != BILINEAR) {
6007 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
Debargha Mukherjeebab29122016-02-26 00:18:03 -08006008 best_filter = EIGHTTAP_REGULAR;
Angie Chiangc0035cc2016-02-10 14:20:56 -08006009 }
6010#if CONFIG_EXT_INTERP
6011 else if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE) {
Debargha Mukherjeebab29122016-02-26 00:18:03 -08006012 best_filter = EIGHTTAP_REGULAR;
Angie Chiangc0035cc2016-02-10 14:20:56 -08006013 }
6014#endif
6015 }
6016 return best_filter;
6017}
6018
6019static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
6020 BLOCK_SIZE bsize,
6021 int *rate2, int64_t *distortion,
6022 int *skippable,
6023 int *rate_y, int *rate_uv,
6024 int *disable_skip,
6025 int_mv (*mode_mv)[MAX_REF_FRAMES],
6026 int mi_row, int mi_col,
Yue Chend1cad9c2016-01-27 14:18:53 -08006027#if CONFIG_OBMC
6028 uint8_t *dst_buf1[3],
6029 int dst_stride1[3],
6030 uint8_t *dst_buf2[3],
6031 int dst_stride2[3],
6032#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08006033#if CONFIG_EXT_INTER
6034 int_mv single_newmvs[2][MAX_REF_FRAMES],
Geza Lore7ded0382016-02-22 10:55:32 +00006035 int single_newmvs_rate[2][MAX_REF_FRAMES],
6036 int *compmode_interintra_cost,
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006037 int *compmode_wedge_cost,
Angie Chiangc0035cc2016-02-10 14:20:56 -08006038#else
6039 int_mv single_newmv[MAX_REF_FRAMES],
6040#endif // CONFIG_EXT_INTER
6041 INTERP_FILTER (*single_filter)[MAX_REF_FRAMES],
6042 int (*single_skippable)[MAX_REF_FRAMES],
6043 int64_t *psse,
6044 const int64_t ref_best_rd,
6045 int64_t *mask_filter,
6046 int64_t filter_cache[]) {
6047 VP10_COMMON *cm = &cpi->common;
6048 MACROBLOCKD *xd = &x->e_mbd;
6049 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6050 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6051 const int is_comp_pred = has_second_ref(mbmi);
6052 const int this_mode = mbmi->mode;
6053 int_mv *frame_mv = mode_mv[this_mode];
6054 int i;
6055 int refs[2] = { mbmi->ref_frame[0],
6056 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
6057 int_mv cur_mv[2];
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006058 int rate_mv = 0;
Angie Chiangc0035cc2016-02-10 14:20:56 -08006059#if CONFIG_EXT_INTER
6060 int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
6061 int_mv single_newmv[MAX_REF_FRAMES];
Geza Lore7ded0382016-02-22 10:55:32 +00006062 const int * const intra_mode_cost =
6063 cpi->mbmode_cost[size_group_lookup[bsize]];
6064 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006065 const int tmp_buf_sz = CU_SIZE * CU_SIZE;
Angie Chiangc0035cc2016-02-10 14:20:56 -08006066#if CONFIG_REF_MV
6067 uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
6068#endif
6069#endif // CONFIG_EXT_INTER
6070#if CONFIG_VP9_HIGHBITDEPTH
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006071 DECLARE_ALIGNED(16, uint16_t, tmp_buf16[MAX_MB_PLANE * CU_SIZE * CU_SIZE]);
Angie Chiangc0035cc2016-02-10 14:20:56 -08006072 uint8_t *tmp_buf;
6073#else
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006074 DECLARE_ALIGNED(16, uint8_t, tmp_buf[MAX_MB_PLANE * CU_SIZE * CU_SIZE]);
Angie Chiangc0035cc2016-02-10 14:20:56 -08006075#endif // CONFIG_VP9_HIGHBITDEPTH
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006076
Yue Chend1cad9c2016-01-27 14:18:53 -08006077#if CONFIG_OBMC
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006078 int allow_obmc =
6079#if CONFIG_EXT_INTER
6080 !is_comp_interintra_pred &&
6081#endif // CONFIG_EXT_INTER
6082 is_obmc_allowed(mbmi);
Yue Chena6142622016-02-18 12:35:14 -08006083 int rate2_nocoeff, best_rate2 = INT_MAX,
6084 best_skippable, best_xskip, best_disable_skip = 0;
6085#if CONFIG_SUPERTX
6086 int best_rate_y, best_rate_uv;
6087#endif // CONFIG_SUPERTX
6088#if CONFIG_VAR_TX
6089 uint8_t best_blk_skip[3][256];
6090#endif // CONFIG_VAR_TX
6091 int64_t best_distortion = INT64_MAX;
6092 unsigned int best_pred_var = UINT_MAX;
6093 MB_MODE_INFO best_mbmi;
Yue Chend1cad9c2016-01-27 14:18:53 -08006094#endif // CONFIG_OBMC
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006095
Angie Chiangc0035cc2016-02-10 14:20:56 -08006096 int pred_exists = 0;
6097 int intpel_mv;
6098 int64_t rd, tmp_rd, best_rd = INT64_MAX;
6099 int best_needs_copy = 0;
6100 uint8_t *orig_dst[MAX_MB_PLANE];
6101 int orig_dst_stride[MAX_MB_PLANE];
6102 int rs = 0;
6103 INTERP_FILTER best_filter = SWITCHABLE;
6104 uint8_t skip_txfm[MAX_MB_PLANE << 2] = {0};
6105 int64_t bsse[MAX_MB_PLANE << 2] = {0};
6106
6107 int skip_txfm_sb = 0;
6108 int64_t skip_sse_sb = INT64_MAX;
6109 int64_t distortion_y = 0, distortion_uv = 0;
6110 int16_t mode_ctx = mbmi_ext->mode_context[refs[0]];
6111
Geza Lore7ded0382016-02-22 10:55:32 +00006112#if CONFIG_EXT_INTER
6113 *compmode_interintra_cost = 0;
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006114 mbmi->use_wedge_interintra = 0;
6115 *compmode_wedge_cost = 0;
6116 mbmi->use_wedge_interinter = 0;
Geza Lore7ded0382016-02-22 10:55:32 +00006117
6118 // is_comp_interintra_pred implies !is_comp_pred
6119 assert(!is_comp_interintra_pred || (!is_comp_pred));
6120 // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
6121 assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
6122#endif // CONFIG_EXT_INTER
6123
Yue Chend1cad9c2016-01-27 14:18:53 -08006124#if CONFIG_OBMC
6125 tmp_rd = 0;
6126#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08006127#if CONFIG_REF_MV
6128#if CONFIG_EXT_INTER
6129 if (is_comp_pred)
6130 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
6131 else
6132#endif // CONFIG_EXT_INTER
6133 mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
6134 mbmi->ref_frame, bsize, -1);
6135#endif
6136
6137#if CONFIG_VP9_HIGHBITDEPTH
6138 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6139 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf16);
6140 } else {
6141 tmp_buf = (uint8_t *)tmp_buf16;
6142 }
6143#endif // CONFIG_VP9_HIGHBITDEPTH
6144
6145 if (is_comp_pred) {
6146 if (frame_mv[refs[0]].as_int == INVALID_MV ||
6147 frame_mv[refs[1]].as_int == INVALID_MV)
6148 return INT64_MAX;
6149 }
Jingning Han3ee6db62015-08-05 19:00:31 -07006150
Yue Chen1ac85872016-01-07 15:13:52 -08006151 if (have_newmv_in_inter_mode(this_mode)) {
Jingning Han3ee6db62015-08-05 19:00:31 -07006152 if (is_comp_pred) {
Yue Chen1ac85872016-01-07 15:13:52 -08006153#if CONFIG_EXT_INTER
6154 for (i = 0; i < 2; ++i) {
6155 single_newmv[refs[i]].as_int =
Yue Chen968bbc72016-01-19 16:45:45 -08006156 single_newmvs[mv_idx][refs[i]].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08006157 }
Yue Chen968bbc72016-01-19 16:45:45 -08006158
6159 if (this_mode == NEW_NEWMV) {
6160 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
6161 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
6162
6163 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
6164 joint_motion_search(cpi, x, bsize, frame_mv,
Yunqing Wang342a3682016-02-16 14:33:18 -08006165 mi_row, mi_col, NULL, single_newmv, &rate_mv, 0);
Yue Chen968bbc72016-01-19 16:45:45 -08006166 } else {
6167 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
6168 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
6169 x->nmvjointcost, x->mvcost,
6170 MV_COST_WEIGHT);
6171 rate_mv += vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
6172 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
6173 x->nmvjointcost, x->mvcost,
6174 MV_COST_WEIGHT);
6175 }
6176 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
6177 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
6178 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
6179 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
6180 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
6181 } else {
6182 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
6183 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
6184 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
6185 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
6186 }
6187#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006188 // Initialize mv using single prediction mode result.
6189 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
6190 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
6191
6192 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
6193 joint_motion_search(cpi, x, bsize, frame_mv,
Yue Chen1ac85872016-01-07 15:13:52 -08006194 mi_row, mi_col,
Yunqing Wang342a3682016-02-16 14:33:18 -08006195 single_newmv, &rate_mv, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07006196 } else {
6197 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
6198 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
6199 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
6200 rate_mv += vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
6201 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
6202 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
6203 }
Yue Chen968bbc72016-01-19 16:45:45 -08006204#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006205 } else {
6206 int_mv tmp_mv;
Geza Lore7ded0382016-02-22 10:55:32 +00006207
Yue Chen1ac85872016-01-07 15:13:52 -08006208#if CONFIG_EXT_INTER
Geza Lore7ded0382016-02-22 10:55:32 +00006209 if (is_comp_interintra_pred) {
6210 tmp_mv = single_newmvs[mv_idx][refs[0]];
6211 rate_mv = single_newmvs_rate[mv_idx][refs[0]];
6212 } else {
6213 single_motion_search(cpi, x, bsize, mi_row, mi_col,
6214 0, mv_idx, &tmp_mv, &rate_mv);
6215 single_newmvs[mv_idx][refs[0]] = tmp_mv;
6216 single_newmvs_rate[mv_idx][refs[0]] = rate_mv;
6217 }
6218#else
6219 single_motion_search(cpi, x, bsize, mi_row, mi_col, &tmp_mv, &rate_mv);
6220 single_newmv[refs[0]] = tmp_mv;
Yue Chen1ac85872016-01-07 15:13:52 -08006221#endif // CONFIG_EXT_INTER
Geza Lore7ded0382016-02-22 10:55:32 +00006222
Jingning Han3ee6db62015-08-05 19:00:31 -07006223 if (tmp_mv.as_int == INVALID_MV)
6224 return INT64_MAX;
6225
Geza Lore7ded0382016-02-22 10:55:32 +00006226 frame_mv[refs[0]] = tmp_mv;
6227 xd->mi[0]->bmi[0].as_mv[0] = tmp_mv;
Jingning Han3ee6db62015-08-05 19:00:31 -07006228
6229 // Estimate the rate implications of a new mv but discount this
6230 // under certain circumstances where we want to help initiate a weak
6231 // motion field, where the distortion gain for a single block may not
6232 // be enough to overcome the cost of a new mv.
6233 if (discount_newmv_test(cpi, this_mode, tmp_mv, mode_mv, refs[0])) {
Geza Lore7ded0382016-02-22 10:55:32 +00006234 rate_mv = VPXMAX((rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07006235 }
6236 }
Geza Lore7ded0382016-02-22 10:55:32 +00006237 *rate2 += rate_mv;
Jingning Han3ee6db62015-08-05 19:00:31 -07006238 }
6239
6240 for (i = 0; i < is_comp_pred + 1; ++i) {
6241 cur_mv[i] = frame_mv[refs[i]];
6242 // Clip "next_nearest" so that it does not extend to far out of image
Yue Chen1ac85872016-01-07 15:13:52 -08006243#if CONFIG_EXT_INTER
6244 if (this_mode != NEWMV && this_mode != NEWFROMNEARMV)
6245#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006246 if (this_mode != NEWMV)
Yue Chen1ac85872016-01-07 15:13:52 -08006247#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006248 clamp_mv2(&cur_mv[i].as_mv, xd);
6249
6250 if (mv_check_bounds(x, &cur_mv[i].as_mv))
6251 return INT64_MAX;
6252 mbmi->mv[i].as_int = cur_mv[i].as_int;
6253 }
6254
Jingning Han33cc1bd2016-01-12 15:06:59 -08006255#if CONFIG_REF_MV
Yue Chen968bbc72016-01-19 16:45:45 -08006256#if CONFIG_EXT_INTER
6257 if (this_mode == NEAREST_NEARESTMV) {
6258#else
Jingning Han33cc1bd2016-01-12 15:06:59 -08006259 if (this_mode == NEARESTMV && is_comp_pred) {
6260 uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
Yue Chen968bbc72016-01-19 16:45:45 -08006261#endif // CONFIG_EXT_INTER
Jingning Han3944cfb2016-01-13 09:03:15 -08006262 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
Jingning Han33cc1bd2016-01-12 15:06:59 -08006263 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
6264 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
6265
6266 for (i = 0; i < 2; ++i) {
6267 lower_mv_precision(&cur_mv[i].as_mv, cm->allow_high_precision_mv);
6268 clamp_mv2(&cur_mv[i].as_mv, xd);
6269 if (mv_check_bounds(x, &cur_mv[i].as_mv))
6270 return INT64_MAX;
6271 mbmi->mv[i].as_int = cur_mv[i].as_int;
6272 }
6273 }
6274 }
6275
Yue Chen968bbc72016-01-19 16:45:45 -08006276#if CONFIG_EXT_INTER
6277 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
6278 if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
6279 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
6280
6281 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
6282 clamp_mv2(&cur_mv[0].as_mv, xd);
6283 if (mv_check_bounds(x, &cur_mv[0].as_mv))
6284 return INT64_MAX;
6285 mbmi->mv[0].as_int = cur_mv[0].as_int;
6286 }
6287
6288 if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
6289 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
6290
6291 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
6292 clamp_mv2(&cur_mv[1].as_mv, xd);
6293 if (mv_check_bounds(x, &cur_mv[1].as_mv))
6294 return INT64_MAX;
6295 mbmi->mv[1].as_int = cur_mv[1].as_int;
6296 }
6297 }
6298
6299 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
6300 if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV) {
6301 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][1].this_mv;
6302
6303 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
6304 clamp_mv2(&cur_mv[0].as_mv, xd);
6305 if (mv_check_bounds(x, &cur_mv[0].as_mv))
6306 return INT64_MAX;
6307 mbmi->mv[0].as_int = cur_mv[0].as_int;
6308 }
6309
6310 if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV) {
6311 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][1].comp_mv;
6312
6313 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
6314 clamp_mv2(&cur_mv[1].as_mv, xd);
6315 if (mv_check_bounds(x, &cur_mv[1].as_mv))
6316 return INT64_MAX;
6317 mbmi->mv[1].as_int = cur_mv[1].as_int;
6318 }
6319 }
6320#else
Jingning Han33cc1bd2016-01-12 15:06:59 -08006321 if (this_mode == NEARMV && is_comp_pred) {
6322 uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
6323 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
Jingning Han95247be2016-02-17 09:27:08 -08006324 int ref_mv_idx = mbmi->ref_mv_idx + 1;
6325 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
6326 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
Jingning Han33cc1bd2016-01-12 15:06:59 -08006327
6328 for (i = 0; i < 2; ++i) {
6329 lower_mv_precision(&cur_mv[i].as_mv, cm->allow_high_precision_mv);
6330 clamp_mv2(&cur_mv[i].as_mv, xd);
6331 if (mv_check_bounds(x, &cur_mv[i].as_mv))
6332 return INT64_MAX;
6333 mbmi->mv[i].as_int = cur_mv[i].as_int;
6334 }
6335 }
6336 }
Yue Chen968bbc72016-01-19 16:45:45 -08006337#endif // CONFIG_EXT_INTER
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006338#endif // CONFIG_REF_MV
Jingning Han33cc1bd2016-01-12 15:06:59 -08006339
Jingning Han3ee6db62015-08-05 19:00:31 -07006340 // do first prediction into the destination buffer. Do the next
6341 // prediction into a temporary buffer. Then keep track of which one
6342 // of these currently holds the best predictor, and use the other
6343 // one for future predictions. In the end, copy from tmp_buf to
6344 // dst if necessary.
6345 for (i = 0; i < MAX_MB_PLANE; i++) {
6346 orig_dst[i] = xd->plane[i].dst.buf;
6347 orig_dst_stride[i] = xd->plane[i].dst.stride;
6348 }
6349
6350 // We don't include the cost of the second reference here, because there
6351 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
6352 // words if you present them in that order, the second one is always known
6353 // if the first is known.
6354 //
6355 // Under some circumstances we discount the cost of new mv mode to encourage
6356 // initiation of a motion field.
6357 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]],
6358 mode_mv, refs[0])) {
Yue Chen1ac85872016-01-07 15:13:52 -08006359#if CONFIG_REF_MV && CONFIG_EXT_INTER
6360 *rate2 += VPXMIN(cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx),
6361 cost_mv_ref(cpi, NEARESTMV, is_comp_pred, mode_ctx));
6362#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08006363 *rate2 += VPXMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
6364 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
Yue Chen1ac85872016-01-07 15:13:52 -08006365#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006366 } else {
Yue Chen1ac85872016-01-07 15:13:52 -08006367#if CONFIG_REF_MV && CONFIG_EXT_INTER
6368 *rate2 += cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx);
6369#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08006370 *rate2 += cost_mv_ref(cpi, this_mode, mode_ctx);
Yue Chen1ac85872016-01-07 15:13:52 -08006371#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006372 }
6373
6374 if (RDCOST(x->rdmult, x->rddiv, *rate2, 0) > ref_best_rd &&
Yue Chen968bbc72016-01-19 16:45:45 -08006375#if CONFIG_EXT_INTER
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006376 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV
Yue Chen968bbc72016-01-19 16:45:45 -08006377#else
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006378 mbmi->mode != NEARESTMV
Yue Chen968bbc72016-01-19 16:45:45 -08006379#endif // CONFIG_EXT_INTER
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006380 )
Jingning Han3ee6db62015-08-05 19:00:31 -07006381 return INT64_MAX;
6382
6383 pred_exists = 0;
6384 // Are all MVs integer pel for Y and UV
6385 intpel_mv = !mv_has_subpel(&mbmi->mv[0].as_mv);
6386 if (is_comp_pred)
6387 intpel_mv &= !mv_has_subpel(&mbmi->mv[1].as_mv);
6388
6389 // Search for best switchable filter by checking the variance of
6390 // pred error irrespective of whether the filter will be used
6391 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
6392 filter_cache[i] = INT64_MAX;
6393
Angie Chiangc0035cc2016-02-10 14:20:56 -08006394 best_filter = predict_interp_filter(cpi, x, bsize, mi_row, mi_col,
6395 single_filter);
6396 if (cm->interp_filter != BILINEAR && best_filter == SWITCHABLE) {
6397 int newbest;
6398 int tmp_rate_sum = 0;
6399 int64_t tmp_dist_sum = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07006400
Angie Chiangc0035cc2016-02-10 14:20:56 -08006401 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
6402 int j;
6403 int64_t rs_rd;
6404 int tmp_skip_sb = 0;
6405 int64_t tmp_skip_sse = INT64_MAX;
Jingning Han3ee6db62015-08-05 19:00:31 -07006406
Angie Chiangc0035cc2016-02-10 14:20:56 -08006407 mbmi->interp_filter = i;
6408 rs = vp10_get_switchable_rate(cpi, xd);
6409 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07006410
Angie Chiangc0035cc2016-02-10 14:20:56 -08006411 if (i > 0 && intpel_mv && IsInterpolatingFilter(i)) {
6412 rd = RDCOST(x->rdmult, x->rddiv, tmp_rate_sum, tmp_dist_sum);
6413 filter_cache[i] = rd;
6414 filter_cache[SWITCHABLE_FILTERS] =
6415 VPXMIN(filter_cache[SWITCHABLE_FILTERS], rd + rs_rd);
6416 if (cm->interp_filter == SWITCHABLE)
6417 rd += rs_rd;
6418 *mask_filter = VPXMAX(*mask_filter, rd);
6419 } else {
6420 int rate_sum = 0;
6421 int64_t dist_sum = 0;
Yue Chenb5f8b702016-03-14 12:05:27 -07006422
Angie Chiangc0035cc2016-02-10 14:20:56 -08006423 if (i > 0 && cpi->sf.adaptive_interp_filter_search &&
6424 (cpi->sf.interp_filter_search_mask & (1 << i))) {
6425 rate_sum = INT_MAX;
6426 dist_sum = INT64_MAX;
6427 continue;
Jingning Han3ee6db62015-08-05 19:00:31 -07006428 }
6429
Angie Chiangc0035cc2016-02-10 14:20:56 -08006430 if ((cm->interp_filter == SWITCHABLE &&
6431 (!i || best_needs_copy)) ||
Geza Lore7ded0382016-02-22 10:55:32 +00006432#if CONFIG_EXT_INTER
6433 is_comp_interintra_pred ||
6434#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006435 (cm->interp_filter != SWITCHABLE &&
Angie Chiangc0035cc2016-02-10 14:20:56 -08006436 (cm->interp_filter == mbmi->interp_filter ||
6437 (i == 0 && intpel_mv && IsInterpolatingFilter(i))))) {
6438 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6439 } else {
6440 for (j = 0; j < MAX_MB_PLANE; j++) {
6441 xd->plane[j].dst.buf = tmp_buf + j * 64 * 64;
6442 xd->plane[j].dst.stride = 64;
6443 }
6444 }
6445 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
6446 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6447 &tmp_skip_sb, &tmp_skip_sse);
Jingning Han3ee6db62015-08-05 19:00:31 -07006448
Angie Chiangc0035cc2016-02-10 14:20:56 -08006449 rd = RDCOST(x->rdmult, x->rddiv, rate_sum, dist_sum);
6450 filter_cache[i] = rd;
6451 filter_cache[SWITCHABLE_FILTERS] =
6452 VPXMIN(filter_cache[SWITCHABLE_FILTERS], rd + rs_rd);
6453 if (cm->interp_filter == SWITCHABLE)
6454 rd += rs_rd;
6455 *mask_filter = VPXMAX(*mask_filter, rd);
6456
6457 if (i == 0 && intpel_mv && IsInterpolatingFilter(i)) {
6458 tmp_rate_sum = rate_sum;
6459 tmp_dist_sum = dist_sum;
Jingning Han3ee6db62015-08-05 19:00:31 -07006460 }
6461 }
Angie Chiangc0035cc2016-02-10 14:20:56 -08006462
6463 if (i == 0 && cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
6464 if (rd / 2 > ref_best_rd) {
6465 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6466 return INT64_MAX;
6467 }
6468 }
6469 newbest = i == 0 || rd < best_rd;
6470
6471 if (newbest) {
6472 best_rd = rd;
6473 best_filter = mbmi->interp_filter;
6474 if (cm->interp_filter == SWITCHABLE && i &&
6475 !(intpel_mv && IsInterpolatingFilter(i)))
6476 best_needs_copy = !best_needs_copy;
6477 }
6478
6479 if ((cm->interp_filter == SWITCHABLE && newbest) ||
6480 (cm->interp_filter != SWITCHABLE &&
6481 cm->interp_filter == mbmi->interp_filter)) {
6482 pred_exists = 1;
6483 tmp_rd = best_rd;
6484
6485 skip_txfm_sb = tmp_skip_sb;
6486 skip_sse_sb = tmp_skip_sse;
6487 memcpy(skip_txfm, x->skip_txfm, sizeof(skip_txfm));
6488 memcpy(bsse, x->bsse, sizeof(bsse));
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006489 } else {
6490 pred_exists = 0;
Angie Chiangc0035cc2016-02-10 14:20:56 -08006491 }
Jingning Han3ee6db62015-08-05 19:00:31 -07006492 }
Angie Chiangc0035cc2016-02-10 14:20:56 -08006493 restore_dst_buf(xd, orig_dst, orig_dst_stride);
Jingning Han3ee6db62015-08-05 19:00:31 -07006494 }
Debargha Mukherjee85514c42015-10-30 09:19:36 -07006495
Jingning Han3ee6db62015-08-05 19:00:31 -07006496 // Set the appropriate filter
6497 mbmi->interp_filter = cm->interp_filter != SWITCHABLE ?
6498 cm->interp_filter : best_filter;
6499 rs = cm->interp_filter == SWITCHABLE ? vp10_get_switchable_rate(cpi, xd) : 0;
Geza Lore7ded0382016-02-22 10:55:32 +00006500
6501#if CONFIG_EXT_INTER
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006502 if (is_comp_pred && get_wedge_bits(bsize)) {
6503 int wedge_index, best_wedge_index = WEDGE_NONE, rs;
6504 int rate_sum;
6505 int64_t dist_sum;
6506 int64_t best_rd_nowedge = INT64_MAX;
6507 int64_t best_rd_wedge = INT64_MAX;
6508 int wedge_types;
6509 int tmp_skip_txfm_sb;
6510 int64_t tmp_skip_sse_sb;
6511 rs = vp10_cost_bit(cm->fc->wedge_interinter_prob[bsize], 0);
6512 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
6513 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6514 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
6515 rd = RDCOST(x->rdmult, x->rddiv, rs + rate_mv + rate_sum, dist_sum);
6516 best_rd_nowedge = rd;
6517 mbmi->use_wedge_interinter = 1;
6518 rs = get_wedge_bits(bsize) * 256 +
6519 vp10_cost_bit(cm->fc->wedge_interinter_prob[bsize], 1);
6520 wedge_types = (1 << get_wedge_bits(bsize));
6521 if (have_newmv_in_inter_mode(this_mode)) {
6522 int_mv tmp_mv[2];
6523 int rate_mvs[2], tmp_rate_mv = 0;
6524 uint8_t pred0[2 * CU_SIZE * CU_SIZE * 3];
6525 uint8_t pred1[2 * CU_SIZE * CU_SIZE * 3];
6526 uint8_t *preds0[3] = {pred0,
6527 pred0 + 2 * CU_SIZE * CU_SIZE,
6528 pred0 + 4 * CU_SIZE * CU_SIZE};
6529 uint8_t *preds1[3] = {pred1,
6530 pred1 + 2 * CU_SIZE * CU_SIZE,
6531 pred1 + 4 * CU_SIZE * CU_SIZE};
6532 int strides[3] = {CU_SIZE, CU_SIZE, CU_SIZE};
6533 vp10_build_inter_predictors_for_planes_single_buf(
6534 xd, bsize, mi_row, mi_col, 0, preds0, strides);
6535 vp10_build_inter_predictors_for_planes_single_buf(
6536 xd, bsize, mi_row, mi_col, 1, preds1, strides);
6537
6538 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
6539 mbmi->interinter_wedge_index = wedge_index;
6540 vp10_build_wedge_inter_predictor_from_buf(xd, bsize, mi_row, mi_col,
6541 preds0, strides,
6542 preds1, strides);
6543 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6544 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
6545 rd = RDCOST(x->rdmult, x->rddiv, rs + rate_mv + rate_sum, dist_sum);
6546 if (rd < best_rd_wedge) {
6547 best_wedge_index = wedge_index;
6548 best_rd_wedge = rd;
6549 }
6550 }
6551 mbmi->interinter_wedge_index = best_wedge_index;
6552 if (this_mode == NEW_NEWMV) {
6553 int mv_idxs[2] = {0, 0};
6554 do_masked_motion_search_indexed(cpi, x, mbmi->interinter_wedge_index,
6555 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
6556 mv_idxs, 2);
6557 tmp_rate_mv = rate_mvs[0] + rate_mvs[1];
6558 mbmi->mv[0].as_int = tmp_mv[0].as_int;
6559 mbmi->mv[1].as_int = tmp_mv[1].as_int;
6560 } else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
6561 int mv_idxs[2] = {0, 0};
6562 do_masked_motion_search_indexed(cpi, x, mbmi->interinter_wedge_index,
6563 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
6564 mv_idxs, 0);
6565 tmp_rate_mv = rate_mvs[0];
6566 mbmi->mv[0].as_int = tmp_mv[0].as_int;
6567 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
6568 int mv_idxs[2] = {0, 0};
6569 do_masked_motion_search_indexed(cpi, x, mbmi->interinter_wedge_index,
6570 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
6571 mv_idxs, 1);
6572 tmp_rate_mv = rate_mvs[1];
6573 mbmi->mv[1].as_int = tmp_mv[1].as_int;
6574 }
6575 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
6576 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6577 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
6578 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate_mv + rate_sum, dist_sum);
6579 if (rd < best_rd_wedge) {
6580 best_rd_wedge = rd;
6581 } else {
6582 mbmi->mv[0].as_int = cur_mv[0].as_int;
6583 mbmi->mv[1].as_int = cur_mv[1].as_int;
6584 tmp_rate_mv = rate_mv;
6585 }
6586 if (best_rd_wedge < best_rd_nowedge) {
6587 mbmi->use_wedge_interinter = 1;
6588 mbmi->interinter_wedge_index = best_wedge_index;
6589 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
6590 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
6591 *rate2 += tmp_rate_mv - rate_mv;
6592 rate_mv = tmp_rate_mv;
6593 } else {
6594 mbmi->use_wedge_interinter = 0;
6595 mbmi->mv[0].as_int = cur_mv[0].as_int;
6596 mbmi->mv[1].as_int = cur_mv[1].as_int;
6597 }
6598 } else {
6599 uint8_t pred0[2 * CU_SIZE * CU_SIZE * 3];
6600 uint8_t pred1[2 * CU_SIZE * CU_SIZE * 3];
6601 uint8_t *preds0[3] = {pred0,
6602 pred0 + 2 * CU_SIZE * CU_SIZE,
6603 pred0 + 4 * CU_SIZE * CU_SIZE};
6604 uint8_t *preds1[3] = {pred1,
6605 pred1 + 2 * CU_SIZE * CU_SIZE,
6606 pred1 + 4 * CU_SIZE * CU_SIZE};
6607 int strides[3] = {CU_SIZE, CU_SIZE, CU_SIZE};
6608 vp10_build_inter_predictors_for_planes_single_buf(
6609 xd, bsize, mi_row, mi_col, 0, preds0, strides);
6610 vp10_build_inter_predictors_for_planes_single_buf(
6611 xd, bsize, mi_row, mi_col, 1, preds1, strides);
6612 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
6613 mbmi->interinter_wedge_index = wedge_index;
6614 // vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
6615 vp10_build_wedge_inter_predictor_from_buf(xd, bsize, mi_row, mi_col,
6616 preds0, strides,
6617 preds1, strides);
6618 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6619 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
6620 rd = RDCOST(x->rdmult, x->rddiv, rs + rate_mv + rate_sum, dist_sum);
6621 if (rd < best_rd_wedge) {
6622 best_wedge_index = wedge_index;
6623 best_rd_wedge = rd;
6624 }
6625 }
6626 if (best_rd_wedge < best_rd_nowedge) {
6627 mbmi->use_wedge_interinter = 1;
6628 mbmi->interinter_wedge_index = best_wedge_index;
6629 } else {
6630 mbmi->use_wedge_interinter = 0;
6631 }
6632 }
6633#if CONFIG_OBMC
6634 if (mbmi->use_wedge_interinter)
6635 allow_obmc = 0;
6636#endif // CONFIG_OBMC
6637 if (ref_best_rd < INT64_MAX &&
6638 VPXMIN(best_rd_wedge, best_rd_nowedge) / 2 > ref_best_rd)
6639 return INT64_MAX;
6640
6641 pred_exists = 0;
6642 tmp_rd = VPXMIN(best_rd_wedge, best_rd_nowedge);
6643 if (mbmi->use_wedge_interinter)
6644 *compmode_wedge_cost = get_wedge_bits(bsize) * 256 +
6645 vp10_cost_bit(cm->fc->wedge_interinter_prob[bsize], 1);
6646 else
6647 *compmode_wedge_cost =
6648 vp10_cost_bit(cm->fc->wedge_interinter_prob[bsize], 0);
6649 }
6650
Geza Lore7ded0382016-02-22 10:55:32 +00006651 if (is_comp_interintra_pred) {
6652 PREDICTION_MODE interintra_mode, best_interintra_mode = DC_PRED;
6653 int64_t best_interintra_rd = INT64_MAX;
6654 int rmode, rate_sum;
6655 int64_t dist_sum;
6656 int j;
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006657 int wedge_bits, wedge_types, wedge_index, best_wedge_index = -1;
6658 int64_t best_interintra_rd_nowedge = INT64_MAX;
6659 int64_t best_interintra_rd_wedge = INT64_MAX;
6660 int rwedge;
6661 int bw = 4 << b_width_log2_lookup[mbmi->sb_type],
6662 bh = 4 << b_height_log2_lookup[mbmi->sb_type];
6663 int_mv tmp_mv;
6664 int tmp_rate_mv = 0;
Geza Lore7ded0382016-02-22 10:55:32 +00006665 mbmi->ref_frame[1] = NONE;
6666 for (j = 0; j < MAX_MB_PLANE; j++) {
6667 xd->plane[j].dst.buf = tmp_buf + j * tmp_buf_sz;
6668 xd->plane[j].dst.stride = CU_SIZE;
6669 }
6670 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
6671 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6672 mbmi->ref_frame[1] = INTRA_FRAME;
6673
6674 for (interintra_mode = DC_PRED; interintra_mode <= TM_PRED;
6675 ++interintra_mode) {
6676 mbmi->interintra_mode = interintra_mode;
6677 mbmi->interintra_uv_mode = interintra_mode;
6678 rmode = intra_mode_cost[mbmi->interintra_mode];
6679 vp10_build_interintra_predictors(xd,
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006680 tmp_buf,
6681 tmp_buf + tmp_buf_sz,
6682 tmp_buf + 2 * tmp_buf_sz,
6683 CU_SIZE,
6684 CU_SIZE,
6685 CU_SIZE,
6686 bsize);
Geza Lore7ded0382016-02-22 10:55:32 +00006687 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6688 &skip_txfm_sb, &skip_sse_sb);
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006689 rd = RDCOST(x->rdmult, x->rddiv, rate_mv + rmode + rate_sum, dist_sum);
Geza Lore7ded0382016-02-22 10:55:32 +00006690 if (rd < best_interintra_rd) {
6691 best_interintra_rd = rd;
6692 best_interintra_mode = interintra_mode;
6693 }
6694 }
6695 mbmi->interintra_mode = best_interintra_mode;
6696 mbmi->interintra_uv_mode = best_interintra_mode;
6697 if (ref_best_rd < INT64_MAX &&
6698 best_interintra_rd / 2 > ref_best_rd) {
6699 return INT64_MAX;
6700 }
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006701 wedge_bits = get_wedge_bits(bsize);
6702 rmode = intra_mode_cost[mbmi->interintra_mode];
6703 if (wedge_bits) {
6704 vp10_build_interintra_predictors(xd,
6705 tmp_buf,
6706 tmp_buf + tmp_buf_sz,
6707 tmp_buf + 2 * tmp_buf_sz,
6708 CU_SIZE,
6709 CU_SIZE,
6710 CU_SIZE,
6711 bsize);
6712 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6713 &skip_txfm_sb, &skip_sse_sb);
6714 rwedge = vp10_cost_bit(cm->fc->wedge_interintra_prob[bsize], 0);
6715 rd = RDCOST(x->rdmult, x->rddiv,
6716 rmode + rate_mv + rwedge + rate_sum, dist_sum);
6717 best_interintra_rd_nowedge = rd;
6718
6719 mbmi->use_wedge_interintra = 1;
6720 rwedge = wedge_bits * 256 +
6721 vp10_cost_bit(cm->fc->wedge_interintra_prob[bsize], 1);
6722 wedge_types = (1 << wedge_bits);
6723 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
6724 mbmi->interintra_wedge_index = wedge_index;
6725 mbmi->interintra_uv_wedge_index = wedge_index;
6726 vp10_build_interintra_predictors(xd,
6727 tmp_buf,
6728 tmp_buf + tmp_buf_sz,
6729 tmp_buf + 2 * tmp_buf_sz,
6730 CU_SIZE,
6731 CU_SIZE,
6732 CU_SIZE,
6733 bsize);
6734 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6735 &skip_txfm_sb, &skip_sse_sb);
6736 rd = RDCOST(x->rdmult, x->rddiv,
6737 rmode + rate_mv + rwedge + rate_sum, dist_sum);
6738 if (rd < best_interintra_rd_wedge) {
6739 best_interintra_rd_wedge = rd;
6740 best_wedge_index = wedge_index;
6741 }
6742 }
6743 // Refine motion vector.
6744 if (have_newmv_in_inter_mode(this_mode)) {
6745 // get negative of mask
6746 const uint8_t* mask = vp10_get_soft_mask(
6747 best_wedge_index ^ 1, bsize, bh, bw);
6748 mbmi->interintra_wedge_index = best_wedge_index;
6749 mbmi->interintra_uv_wedge_index = best_wedge_index;
6750 do_masked_motion_search(cpi, x, mask, MASK_MASTER_STRIDE, bsize,
6751 mi_row, mi_col, &tmp_mv, &tmp_rate_mv,
6752 0, mv_idx);
6753 mbmi->mv[0].as_int = tmp_mv.as_int;
6754 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
6755 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6756 &skip_txfm_sb, &skip_sse_sb);
6757 rd = RDCOST(x->rdmult, x->rddiv,
6758 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
6759 if (rd < best_interintra_rd_wedge) {
6760 best_interintra_rd_wedge = rd;
6761 } else {
6762 tmp_mv.as_int = cur_mv[0].as_int;
6763 tmp_rate_mv = rate_mv;
6764 }
6765 } else {
6766 tmp_mv.as_int = cur_mv[0].as_int;
6767 tmp_rate_mv = rate_mv;
6768 }
6769 if (best_interintra_rd_wedge < best_interintra_rd_nowedge) {
6770 mbmi->use_wedge_interintra = 1;
6771 mbmi->interintra_wedge_index = best_wedge_index;
6772 mbmi->interintra_uv_wedge_index = best_wedge_index;
6773 best_interintra_rd = best_interintra_rd_wedge;
6774 mbmi->mv[0].as_int = tmp_mv.as_int;
6775 *rate2 += tmp_rate_mv - rate_mv;
6776 rate_mv = tmp_rate_mv;
6777 } else {
6778 mbmi->use_wedge_interintra = 0;
6779 best_interintra_rd = best_interintra_rd_nowedge;
6780 mbmi->mv[0].as_int = cur_mv[0].as_int;
6781 }
6782 }
Geza Lore7ded0382016-02-22 10:55:32 +00006783
6784 pred_exists = 0;
6785 tmp_rd = best_interintra_rd;
Geza Lore7ded0382016-02-22 10:55:32 +00006786 *compmode_interintra_cost =
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006787 vp10_cost_bit(cm->fc->interintra_prob[bsize], 1);
Geza Lore7ded0382016-02-22 10:55:32 +00006788 *compmode_interintra_cost += intra_mode_cost[mbmi->interintra_mode];
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006789 if (get_wedge_bits(bsize)) {
6790 *compmode_interintra_cost += vp10_cost_bit(
6791 cm->fc->wedge_interintra_prob[bsize], mbmi->use_wedge_interintra);
6792 if (mbmi->use_wedge_interintra) {
6793 *compmode_interintra_cost += get_wedge_bits(bsize) * 256;
6794 }
6795 }
Geza Lore7ded0382016-02-22 10:55:32 +00006796 } else if (is_interintra_allowed(mbmi)) {
6797 *compmode_interintra_cost =
6798 vp10_cost_bit(cm->fc->interintra_prob[bsize], 0);
6799 }
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006800
6801#if CONFIG_EXT_INTERP
6802 if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE) {
6803 mbmi->interp_filter = EIGHTTAP_REGULAR;
6804 pred_exists = 0;
6805 }
6806#endif // CONFIG_EXT_INTERP
Geza Lore7ded0382016-02-22 10:55:32 +00006807#endif // CONFIG_EXT_INTER
6808
Jingning Han3ee6db62015-08-05 19:00:31 -07006809 if (pred_exists) {
6810 if (best_needs_copy) {
6811 // again temporarily set the buffers to local memory to prevent a memcpy
6812 for (i = 0; i < MAX_MB_PLANE; i++) {
6813 xd->plane[i].dst.buf = tmp_buf + i * 64 * 64;
6814 xd->plane[i].dst.stride = 64;
6815 }
6816 }
Yue Chenb5f8b702016-03-14 12:05:27 -07006817 rd = tmp_rd;
Jingning Han3ee6db62015-08-05 19:00:31 -07006818 } else {
6819 int tmp_rate;
6820 int64_t tmp_dist;
Yue Chenb5f8b702016-03-14 12:05:27 -07006821
Jingning Han3ee6db62015-08-05 19:00:31 -07006822 // Handles the special case when a filter that is not in the
6823 // switchable list (ex. bilinear) is indicated at the frame level, or
6824 // skip condition holds.
6825 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
6826 model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist,
6827 &skip_txfm_sb, &skip_sse_sb);
6828 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
6829 memcpy(skip_txfm, x->skip_txfm, sizeof(skip_txfm));
6830 memcpy(bsse, x->bsse, sizeof(bsse));
6831 }
6832
6833 if (!is_comp_pred)
6834 single_filter[this_mode][refs[0]] = mbmi->interp_filter;
6835
6836 if (cpi->sf.adaptive_mode_search)
6837 if (is_comp_pred)
Yue Chen968bbc72016-01-19 16:45:45 -08006838#if CONFIG_EXT_INTER
6839 switch (this_mode) {
6840 case NEAREST_NEARESTMV:
6841 if (single_skippable[NEARESTMV][refs[0]] &&
6842 single_skippable[NEARESTMV][refs[1]])
6843 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6844 break;
6845 case ZERO_ZEROMV:
6846 if (single_skippable[ZEROMV][refs[0]] &&
6847 single_skippable[ZEROMV][refs[1]])
6848 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6849 break;
6850 case NEW_NEWMV:
6851 if (single_skippable[NEWMV][refs[0]] &&
6852 single_skippable[NEWMV][refs[1]])
6853 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6854 break;
6855 case NEAREST_NEWMV:
6856 if (single_skippable[NEARESTMV][refs[0]] &&
6857 single_skippable[NEWMV][refs[1]])
6858 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6859 break;
6860 case NEAR_NEWMV:
6861 if (single_skippable[NEARMV][refs[0]] &&
6862 single_skippable[NEWMV][refs[1]])
6863 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6864 break;
6865 case NEW_NEARESTMV:
6866 if (single_skippable[NEWMV][refs[0]] &&
6867 single_skippable[NEARESTMV][refs[1]])
6868 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6869 break;
6870 case NEW_NEARMV:
6871 if (single_skippable[NEWMV][refs[0]] &&
6872 single_skippable[NEARMV][refs[1]])
6873 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6874 break;
6875 case NEAREST_NEARMV:
6876 if (single_skippable[NEARESTMV][refs[0]] &&
6877 single_skippable[NEARMV][refs[1]])
6878 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6879 break;
6880 case NEAR_NEARESTMV:
6881 if (single_skippable[NEARMV][refs[0]] &&
6882 single_skippable[NEARESTMV][refs[1]])
6883 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6884 break;
6885 default:
6886 if (single_skippable[this_mode][refs[0]] &&
6887 single_skippable[this_mode][refs[1]])
6888 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6889 break;
6890 }
6891#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006892 if (single_skippable[this_mode][refs[0]] &&
6893 single_skippable[this_mode][refs[1]])
6894 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
Yue Chen968bbc72016-01-19 16:45:45 -08006895#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006896
6897 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
6898 // if current pred_error modeled rd is substantially more than the best
6899 // so far, do not bother doing full rd
6900 if (rd / 2 > ref_best_rd) {
6901 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6902 return INT64_MAX;
6903 }
6904 }
6905
6906 if (cm->interp_filter == SWITCHABLE)
6907 *rate2 += rs;
Yue Chend1cad9c2016-01-27 14:18:53 -08006908#if CONFIG_OBMC
Yue Chena6142622016-02-18 12:35:14 -08006909 rate2_nocoeff = *rate2;
Yue Chend1cad9c2016-01-27 14:18:53 -08006910#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006911
6912 memcpy(x->skip_txfm, skip_txfm, sizeof(skip_txfm));
6913 memcpy(x->bsse, bsse, sizeof(bsse));
6914
Yue Chena6142622016-02-18 12:35:14 -08006915
6916#if CONFIG_OBMC
6917 best_rd = INT64_MAX;
6918 for (mbmi->obmc = 0; mbmi->obmc <= allow_obmc; mbmi->obmc++) {
Yue Chenb5f8b702016-03-14 12:05:27 -07006919 int64_t tmp_rd, tmp_dist;
6920 int tmp_rate;
Yue Chena6142622016-02-18 12:35:14 -08006921
Yue Chenb5f8b702016-03-14 12:05:27 -07006922 if (mbmi->obmc) {
6923 vp10_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, 0,
6924 NULL, NULL,
6925 dst_buf1, dst_stride1,
6926 dst_buf2, dst_stride2);
6927 model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist,
6928 &skip_txfm_sb, &skip_sse_sb);
Yue Chena6142622016-02-18 12:35:14 -08006929 }
6930#if CONFIG_VP9_HIGHBITDEPTH
6931 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6932 x->pred_variance = vp10_high_get_sby_perpixel_variance(cpi,
6933 &xd->plane[0].dst, bsize, xd->bd);
6934 } else {
6935 x->pred_variance =
6936 vp10_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
6937 }
6938#else
6939 x->pred_variance =
6940 vp10_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
6941#endif // CONFIG_VP9_HIGHBITDEPTH
6942
Yue Chena6142622016-02-18 12:35:14 -08006943 x->skip = 0;
6944
6945 *rate2 = rate2_nocoeff;
6946 *distortion = 0;
6947 if (allow_obmc)
6948 *rate2 += cpi->obmc_cost[bsize][mbmi->obmc];
6949#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006950 if (!skip_txfm_sb) {
6951 int skippable_y, skippable_uv;
6952 int64_t sseuv = INT64_MAX;
6953 int64_t rdcosty = INT64_MAX;
6954
6955 // Y cost and distortion
6956 vp10_subtract_plane(x, bsize, 0);
Jingning Han2cdc1272015-10-09 09:57:42 -07006957#if CONFIG_VAR_TX
Jingning Hanf0dee772015-10-26 12:32:30 -07006958 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
Jingning Han4b594d32015-11-02 12:05:47 -08006959 select_tx_type_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
6960 bsize, ref_best_rd);
Jingning Han2cdc1272015-10-09 09:57:42 -07006961 } else {
Jingning Han0f34e352015-11-15 20:52:51 -08006962 int idx, idy;
Jingning Han2cdc1272015-10-09 09:57:42 -07006963 super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
6964 bsize, ref_best_rd);
Jingning Han0f34e352015-11-15 20:52:51 -08006965 for (idy = 0; idy < xd->n8_h; ++idy)
6966 for (idx = 0; idx < xd->n8_w; ++idx)
6967 mbmi->inter_tx_size[idy * 8 + idx] = mbmi->tx_size;
Jingning Han2cdc1272015-10-09 09:57:42 -07006968 }
6969#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006970 super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
6971 bsize, ref_best_rd);
Debargha Mukherjee9a8a6a12016-01-22 14:52:38 -08006972#endif // CONFIG_VAR_TX
Jingning Han704985e2015-10-08 12:05:03 -07006973
Jingning Han3ee6db62015-08-05 19:00:31 -07006974 if (*rate_y == INT_MAX) {
6975 *rate2 = INT_MAX;
6976 *distortion = INT64_MAX;
Yue Chena6142622016-02-18 12:35:14 -08006977#if CONFIG_OBMC
6978 continue;
6979#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006980 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6981 return INT64_MAX;
Yue Chena6142622016-02-18 12:35:14 -08006982#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006983 }
6984
6985 *rate2 += *rate_y;
6986 *distortion += distortion_y;
6987
6988 rdcosty = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
James Zern5e16d392015-08-17 18:19:22 -07006989 rdcosty = VPXMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, *psse));
Jingning Han3ee6db62015-08-05 19:00:31 -07006990
Jingning Hana8dad552015-10-08 16:46:10 -07006991#if CONFIG_VAR_TX
6992 if (!inter_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv,
6993 &sseuv, bsize, ref_best_rd - rdcosty)) {
6994#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006995 if (!super_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv,
6996 &sseuv, bsize, ref_best_rd - rdcosty)) {
Debargha Mukherjee9a8a6a12016-01-22 14:52:38 -08006997#endif // CONFIG_VAR_TX
Jingning Han3ee6db62015-08-05 19:00:31 -07006998 *rate2 = INT_MAX;
6999 *distortion = INT64_MAX;
Yue Chena6142622016-02-18 12:35:14 -08007000#if CONFIG_OBMC
7001 continue;
7002#else
Jingning Han3ee6db62015-08-05 19:00:31 -07007003 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7004 return INT64_MAX;
Yue Chena6142622016-02-18 12:35:14 -08007005#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007006 }
7007
7008 *psse += sseuv;
7009 *rate2 += *rate_uv;
7010 *distortion += distortion_uv;
7011 *skippable = skippable_y && skippable_uv;
Yue Chena6142622016-02-18 12:35:14 -08007012#if CONFIG_OBMC
7013 if (*skippable) {
7014 *rate2 -= *rate_uv + *rate_y;
7015 *rate_y = 0;
7016 *rate_uv = 0;
7017 *rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
7018 mbmi->skip = 0;
7019 // here mbmi->skip temporarily plays a role as what this_skip2 does
7020 } else if (!xd->lossless[mbmi->segment_id] &&
7021 (RDCOST(x->rdmult, x->rddiv, *rate_y + *rate_uv +
7022 vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0), *distortion) >=
7023 RDCOST(x->rdmult, x->rddiv,
7024 vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1), *psse))) {
7025 *rate2 -= *rate_uv + *rate_y;
7026 *rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
7027 *distortion = *psse;
7028 *rate_y = 0;
7029 *rate_uv = 0;
7030 mbmi->skip = 1;
7031 } else {
7032 *rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
7033 mbmi->skip = 0;
7034 }
7035 *disable_skip = 0;
7036#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007037 } else {
7038 x->skip = 1;
7039 *disable_skip = 1;
7040
7041 // The cost of skip bit needs to be added.
Yue Chena6142622016-02-18 12:35:14 -08007042#if CONFIG_OBMC
Yue Chenb5f8b702016-03-14 12:05:27 -07007043 mbmi->skip = 0;
Yue Chena6142622016-02-18 12:35:14 -08007044#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007045 *rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
7046
7047 *distortion = skip_sse_sb;
7048 }
Yue Chena6142622016-02-18 12:35:14 -08007049#if CONFIG_OBMC
7050 tmp_rd = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
7051 if (mbmi->obmc == 0 || (tmp_rd < best_rd)) {
7052 best_mbmi = *mbmi;
7053 best_rd = tmp_rd;
7054 best_rate2 = *rate2;
7055#if CONFIG_SUPERTX
7056 best_rate_y = *rate_y;
7057 best_rate_uv = *rate_uv;
7058#endif // CONFIG_SUPERTX
7059#if CONFIG_VAR_TX
7060 for (i = 0; i < MAX_MB_PLANE; ++i)
7061 memcpy(best_blk_skip[i], x->blk_skip[i],
7062 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7063#endif // CONFIG_VAR_TX
7064 best_distortion = *distortion;
7065 best_skippable = *skippable;
7066 best_xskip = x->skip;
7067 best_disable_skip = *disable_skip;
7068 best_pred_var = x->pred_variance;
7069 }
7070 }
7071
7072 if (best_rd == INT64_MAX) {
7073 *rate2 = INT_MAX;
7074 *distortion = INT64_MAX;
7075 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7076 return INT64_MAX;
7077 }
7078 *mbmi = best_mbmi;
7079 *rate2 = best_rate2;
7080#if CONFIG_SUPERTX
7081 *rate_y = best_rate_y;
7082 *rate_uv = best_rate_uv;
7083#endif // CONFIG_SUPERTX
7084#if CONFIG_VAR_TX
7085 for (i = 0; i < MAX_MB_PLANE; ++i)
7086 memcpy(x->blk_skip[i], best_blk_skip[i],
7087 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7088#endif // CONFIG_VAR_TX
7089 *distortion = best_distortion;
7090 *skippable = best_skippable;
7091 x->skip = best_xskip;
7092 *disable_skip = best_disable_skip;
7093 x->pred_variance = best_pred_var;
7094#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007095
7096 if (!is_comp_pred)
7097 single_skippable[this_mode][refs[0]] = *skippable;
7098
7099 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7100 return 0; // The rate-distortion cost will be re-calculated by caller.
7101}
7102
Yaowu Xu26a9afc2015-08-13 09:42:27 -07007103void vp10_rd_pick_intra_mode_sb(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07007104 RD_COST *rd_cost, BLOCK_SIZE bsize,
7105 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07007106 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07007107 MACROBLOCKD *const xd = &x->e_mbd;
7108 struct macroblockd_plane *const pd = xd->plane;
7109 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
7110 int y_skip = 0, uv_skip = 0;
7111 int64_t dist_y = 0, dist_uv = 0;
7112 TX_SIZE max_uv_tx_size;
Jingning Han3ee6db62015-08-05 19:00:31 -07007113 ctx->skip = 0;
7114 xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
7115 xd->mi[0]->mbmi.ref_frame[1] = NONE;
7116
7117 if (bsize >= BLOCK_8X8) {
7118 if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly,
7119 &dist_y, &y_skip, bsize,
7120 best_rd) >= best_rd) {
7121 rd_cost->rate = INT_MAX;
7122 return;
7123 }
7124 } else {
7125 y_skip = 0;
7126 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
7127 &dist_y, best_rd) >= best_rd) {
7128 rd_cost->rate = INT_MAX;
7129 return;
7130 }
7131 }
7132 max_uv_tx_size = get_uv_tx_size_impl(xd->mi[0]->mbmi.tx_size, bsize,
7133 pd[1].subsampling_x,
7134 pd[1].subsampling_y);
7135 rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv, &rate_uv_tokenonly,
James Zern5e16d392015-08-17 18:19:22 -07007136 &dist_uv, &uv_skip, VPXMAX(BLOCK_8X8, bsize),
Jingning Han3ee6db62015-08-05 19:00:31 -07007137 max_uv_tx_size);
7138
7139 if (y_skip && uv_skip) {
7140 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
7141 vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
7142 rd_cost->dist = dist_y + dist_uv;
7143 } else {
7144 rd_cost->rate = rate_y + rate_uv +
7145 vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
7146 rd_cost->dist = dist_y + dist_uv;
7147 }
7148
7149 ctx->mic = *xd->mi[0];
7150 ctx->mbmi_ext = *x->mbmi_ext;
7151 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
7152}
7153
7154// This function is designed to apply a bias or adjustment to an rd value based
7155// on the relative variance of the source and reconstruction.
7156#define LOW_VAR_THRESH 16
7157#define VLOW_ADJ_MAX 25
7158#define VHIGH_ADJ_MAX 8
Yaowu Xu26a9afc2015-08-13 09:42:27 -07007159static void rd_variance_adjustment(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07007160 MACROBLOCK *x,
7161 BLOCK_SIZE bsize,
7162 int64_t *this_rd,
7163 MV_REFERENCE_FRAME ref_frame,
Yue Chena6142622016-02-18 12:35:14 -08007164#if CONFIG_OBMC
7165 int is_pred_var_available,
7166#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007167 unsigned int source_variance) {
7168 MACROBLOCKD *const xd = &x->e_mbd;
7169 unsigned int recon_variance;
7170 unsigned int absvar_diff = 0;
7171 int64_t var_error = 0;
7172 int64_t var_factor = 0;
7173
7174 if (*this_rd == INT64_MAX)
7175 return;
7176
Yue Chena6142622016-02-18 12:35:14 -08007177#if CONFIG_OBMC
7178 if (is_pred_var_available) {
7179 recon_variance = x->pred_variance;
7180 } else {
7181#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007182#if CONFIG_VP9_HIGHBITDEPTH
7183 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
7184 recon_variance =
7185 vp10_high_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize, xd->bd);
7186 } else {
7187 recon_variance =
7188 vp10_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
7189 }
7190#else
7191 recon_variance =
7192 vp10_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
7193#endif // CONFIG_VP9_HIGHBITDEPTH
Yue Chena6142622016-02-18 12:35:14 -08007194#if CONFIG_OBMC
7195 }
7196#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007197
7198 if ((source_variance + recon_variance) > LOW_VAR_THRESH) {
7199 absvar_diff = (source_variance > recon_variance)
7200 ? (source_variance - recon_variance)
7201 : (recon_variance - source_variance);
7202
Alex Converseb1fcd172015-11-19 14:53:51 -08007203 var_error = ((int64_t)200 * source_variance * recon_variance) /
7204 (((int64_t)source_variance * source_variance) +
7205 ((int64_t)recon_variance * recon_variance));
Jingning Han3ee6db62015-08-05 19:00:31 -07007206 var_error = 100 - var_error;
7207 }
7208
7209 // Source variance above a threshold and ref frame is intra.
7210 // This case is targeted mainly at discouraging intra modes that give rise
7211 // to a predictor with a low spatial complexity compared to the source.
7212 if ((source_variance > LOW_VAR_THRESH) && (ref_frame == INTRA_FRAME) &&
7213 (source_variance > recon_variance)) {
James Zern5e16d392015-08-17 18:19:22 -07007214 var_factor = VPXMIN(absvar_diff, VPXMIN(VLOW_ADJ_MAX, var_error));
Jingning Han3ee6db62015-08-05 19:00:31 -07007215 // A second possible case of interest is where the source variance
7216 // is very low and we wish to discourage false texture or motion trails.
7217 } else if ((source_variance < (LOW_VAR_THRESH >> 1)) &&
7218 (recon_variance > source_variance)) {
James Zern5e16d392015-08-17 18:19:22 -07007219 var_factor = VPXMIN(absvar_diff, VPXMIN(VHIGH_ADJ_MAX, var_error));
Jingning Han3ee6db62015-08-05 19:00:31 -07007220 }
7221 *this_rd += (*this_rd * var_factor) / 100;
7222}
7223
7224
7225// Do we have an internal image edge (e.g. formatting bars).
Yaowu Xu26a9afc2015-08-13 09:42:27 -07007226int vp10_internal_image_edge(VP10_COMP *cpi) {
Jingning Han3ee6db62015-08-05 19:00:31 -07007227 return (cpi->oxcf.pass == 2) &&
7228 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
7229 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
7230}
7231
7232// Checks to see if a super block is on a horizontal image edge.
7233// In most cases this is the "real" edge unless there are formatting
7234// bars embedded in the stream.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07007235int vp10_active_h_edge(VP10_COMP *cpi, int mi_row, int mi_step) {
Jingning Han3ee6db62015-08-05 19:00:31 -07007236 int top_edge = 0;
7237 int bottom_edge = cpi->common.mi_rows;
7238 int is_active_h_edge = 0;
7239
7240 // For two pass account for any formatting bars detected.
7241 if (cpi->oxcf.pass == 2) {
7242 TWO_PASS *twopass = &cpi->twopass;
7243
7244 // The inactive region is specified in MBs not mi units.
7245 // The image edge is in the following MB row.
7246 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
7247
7248 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
James Zern5e16d392015-08-17 18:19:22 -07007249 bottom_edge = VPXMAX(top_edge, bottom_edge);
Jingning Han3ee6db62015-08-05 19:00:31 -07007250 }
7251
7252 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
7253 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
7254 is_active_h_edge = 1;
7255 }
7256 return is_active_h_edge;
7257}
7258
7259// Checks to see if a super block is on a vertical image edge.
7260// In most cases this is the "real" edge unless there are formatting
7261// bars embedded in the stream.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07007262int vp10_active_v_edge(VP10_COMP *cpi, int mi_col, int mi_step) {
Jingning Han3ee6db62015-08-05 19:00:31 -07007263 int left_edge = 0;
7264 int right_edge = cpi->common.mi_cols;
7265 int is_active_v_edge = 0;
7266
7267 // For two pass account for any formatting bars detected.
7268 if (cpi->oxcf.pass == 2) {
7269 TWO_PASS *twopass = &cpi->twopass;
7270
7271 // The inactive region is specified in MBs not mi units.
7272 // The image edge is in the following MB row.
7273 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
7274
7275 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
James Zern5e16d392015-08-17 18:19:22 -07007276 right_edge = VPXMAX(left_edge, right_edge);
Jingning Han3ee6db62015-08-05 19:00:31 -07007277 }
7278
7279 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
7280 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
7281 is_active_v_edge = 1;
7282 }
7283 return is_active_v_edge;
7284}
7285
7286// Checks to see if a super block is at the edge of the active image.
7287// In most cases this is the "real" edge unless there are formatting
7288// bars embedded in the stream.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07007289int vp10_active_edge_sb(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07007290 int mi_row, int mi_col) {
7291 return vp10_active_h_edge(cpi, mi_row, MI_BLOCK_SIZE) ||
7292 vp10_active_v_edge(cpi, mi_col, MI_BLOCK_SIZE);
7293}
7294
hui su78b0bd02016-02-23 15:22:25 -08007295static void restore_uv_color_map(VP10_COMP *cpi, MACROBLOCK *x) {
7296 MACROBLOCKD *const xd = &x->e_mbd;
7297 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7298 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
7299 const BLOCK_SIZE bsize = mbmi->sb_type;
7300 const int rows = (4 * num_4x4_blocks_high_lookup[bsize]) >>
7301 (xd->plane[1].subsampling_y);
7302 const int cols = (4 * num_4x4_blocks_wide_lookup[bsize]) >>
7303 (xd->plane[1].subsampling_x);
7304 int src_stride = x->plane[1].src.stride;
7305 const uint8_t *const src_u = x->plane[1].src.buf;
7306 const uint8_t *const src_v = x->plane[2].src.buf;
7307 double *const data = x->palette_buffer->kmeans_data_buf;
7308 uint8_t *const indices = x->palette_buffer->kmeans_indices_buf;
7309 double centroids[2 * PALETTE_MAX_SIZE];
7310 uint8_t *const color_map = xd->plane[1].color_index_map;
7311 int r, c;
7312#if CONFIG_VP9_HIGHBITDEPTH
7313 const uint16_t *const src_u16 = CONVERT_TO_SHORTPTR(src_u);
7314 const uint16_t *const src_v16 = CONVERT_TO_SHORTPTR(src_v);
7315#endif // CONFIG_VP9_HIGHBITDEPTH
7316 (void)cpi;
7317
7318 for (r = 0; r < rows; ++r) {
7319 for (c = 0; c < cols; ++c) {
7320#if CONFIG_VP9_HIGHBITDEPTH
7321 if (cpi->common.use_highbitdepth) {
7322 data[(r * cols + c) * 2 ] =
7323 src_u16[r * src_stride + c];
7324 data[(r * cols + c) * 2 + 1] =
7325 src_v16[r * src_stride + c];
7326 } else {
7327#endif // CONFIG_VP9_HIGHBITDEPTH
7328 data[(r * cols + c) * 2 ] =
7329 src_u[r * src_stride + c];
7330 data[(r * cols + c) * 2 + 1] =
7331 src_v[r * src_stride + c];
7332#if CONFIG_VP9_HIGHBITDEPTH
7333 }
7334#endif // CONFIG_VP9_HIGHBITDEPTH
7335 }
7336 }
7337
7338 for (r = 1; r < 3; ++r) {
7339 for (c = 0; c < pmi->palette_size[1]; ++c) {
7340 centroids[c * 2 + r - 1] = pmi->palette_colors[r * PALETTE_MAX_SIZE + c];
7341 }
7342 }
7343
7344 vp10_calc_indices(data, centroids, indices, rows * cols,
7345 pmi->palette_size[1], 2);
7346
7347 for (r = 0; r < rows; ++r)
7348 for (c = 0; c < cols; ++c)
7349 color_map[r * cols + c] = indices[r * cols + c];
7350}
7351
Yaowu Xu26a9afc2015-08-13 09:42:27 -07007352void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
Jingning Han4fa8e732015-09-10 12:24:06 -07007353 TileDataEnc *tile_data,
7354 MACROBLOCK *x,
7355 int mi_row, int mi_col,
Debargha Mukherjee3787b172015-11-19 16:51:16 -08007356 RD_COST *rd_cost,
7357#if CONFIG_SUPERTX
7358 int *returnrate_nocoef,
7359#endif // CONFIG_SUPERTX
7360 BLOCK_SIZE bsize,
Jingning Han4fa8e732015-09-10 12:24:06 -07007361 PICK_MODE_CONTEXT *ctx,
7362 int64_t best_rd_so_far) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07007363 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07007364 RD_OPT *const rd_opt = &cpi->rd;
7365 SPEED_FEATURES *const sf = &cpi->sf;
7366 MACROBLOCKD *const xd = &x->e_mbd;
7367 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
hui su78b0bd02016-02-23 15:22:25 -08007368 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Jingning Han3ee6db62015-08-05 19:00:31 -07007369 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
7370 const struct segmentation *const seg = &cm->seg;
7371 PREDICTION_MODE this_mode;
7372 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
7373 unsigned char segment_id = mbmi->segment_id;
7374 int comp_pred, i, k;
7375 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
Zoe Liu3ec16012015-11-12 02:12:17 -08007376 struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE];
Yue Chen1ac85872016-01-07 15:13:52 -08007377#if CONFIG_EXT_INTER
7378 int_mv single_newmvs[2][MAX_REF_FRAMES] = { { { 0 } }, { { 0 } } };
Geza Lore7ded0382016-02-22 10:55:32 +00007379 int single_newmvs_rate[2][MAX_REF_FRAMES] = { { 0 }, { 0 } };
Yue Chen1ac85872016-01-07 15:13:52 -08007380#else
Jingning Han3ee6db62015-08-05 19:00:31 -07007381 int_mv single_newmv[MAX_REF_FRAMES] = { { 0 } };
Yue Chen1ac85872016-01-07 15:13:52 -08007382#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007383 INTERP_FILTER single_inter_filter[MB_MODE_COUNT][MAX_REF_FRAMES];
7384 int single_skippable[MB_MODE_COUNT][MAX_REF_FRAMES];
Zoe Liu3ec16012015-11-12 02:12:17 -08007385 static const int flag_list[REFS_PER_FRAME + 1] = {
7386 0,
7387 VP9_LAST_FLAG,
7388#if CONFIG_EXT_REFS
7389 VP9_LAST2_FLAG,
7390 VP9_LAST3_FLAG,
7391 VP9_LAST4_FLAG,
7392#endif // CONFIG_EXT_REFS
7393 VP9_GOLD_FLAG,
7394 VP9_ALT_FLAG
7395 };
Jingning Han3ee6db62015-08-05 19:00:31 -07007396 int64_t best_rd = best_rd_so_far;
7397 int64_t best_pred_diff[REFERENCE_MODES];
7398 int64_t best_pred_rd[REFERENCE_MODES];
7399 int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
7400 int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
7401 MB_MODE_INFO best_mbmode;
7402 int best_mode_skippable = 0;
7403 int midx, best_mode_index = -1;
7404 unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
7405 vpx_prob comp_mode_p;
7406 int64_t best_intra_rd = INT64_MAX;
7407 unsigned int best_pred_sse = UINT_MAX;
7408 PREDICTION_MODE best_intra_mode = DC_PRED;
7409 int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES];
7410 int64_t dist_uv[TX_SIZES];
7411 int skip_uv[TX_SIZES];
7412 PREDICTION_MODE mode_uv[TX_SIZES];
hui su78b0bd02016-02-23 15:22:25 -08007413 PALETTE_MODE_INFO pmi_uv[TX_SIZES];
hui sube3559b2015-10-07 09:29:02 -07007414#if CONFIG_EXT_INTRA
7415 EXT_INTRA_MODE_INFO ext_intra_mode_info_uv[TX_SIZES];
hui su4aa50c12015-11-10 12:09:59 -08007416 int8_t uv_angle_delta[TX_SIZES];
hui sud7c8bc72015-11-12 19:18:32 -08007417 int is_directional_mode, angle_stats_ready = 0;
hui su4aa50c12015-11-10 12:09:59 -08007418 int rate_overhead, rate_dummy;
hui sud7c8bc72015-11-12 19:18:32 -08007419 uint8_t directional_mode_skip_mask[INTRA_MODES];
hui sube3559b2015-10-07 09:29:02 -07007420#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07007421 const int intra_cost_penalty = vp10_get_intra_cost_penalty(
7422 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
hui su1559afd2015-12-30 10:27:19 -08007423 const int * const intra_mode_cost =
7424 cpi->mbmode_cost[size_group_lookup[bsize]];
Jingning Han3ee6db62015-08-05 19:00:31 -07007425 int best_skip2 = 0;
7426 uint8_t ref_frame_skip_mask[2] = { 0 };
Yue Chen1ac85872016-01-07 15:13:52 -08007427#if CONFIG_EXT_INTER
7428 uint32_t mode_skip_mask[MAX_REF_FRAMES] = { 0 };
7429#else
Jingning Han3ee6db62015-08-05 19:00:31 -07007430 uint16_t mode_skip_mask[MAX_REF_FRAMES] = { 0 };
Yue Chen1ac85872016-01-07 15:13:52 -08007431#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007432 int mode_skip_start = sf->mode_skip_start + 1;
7433 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
7434 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
7435 int64_t mode_threshold[MAX_MODES];
7436 int *mode_map = tile_data->mode_map[bsize];
7437 const int mode_search_skip_flags = sf->mode_search_skip_flags;
7438 int64_t mask_filter = 0;
7439 int64_t filter_cache[SWITCHABLE_FILTER_CONTEXTS];
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08007440 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
hui su78b0bd02016-02-23 15:22:25 -08007441 int palette_ctx = 0;
7442 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
7443 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
7444 const MODE_INFO *above_mi = xd->above_mi;
7445 const MODE_INFO *left_mi = xd->left_mi;
Yue Chend1cad9c2016-01-27 14:18:53 -08007446#if CONFIG_OBMC
7447#if CONFIG_VP9_HIGHBITDEPTH
7448 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * 64 * 64]);
7449 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * 64 * 64]);
7450#else
7451 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * 64 * 64]);
7452 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * 64 * 64]);
7453#endif // CONFIG_VP9_HIGHBITDEPTH
7454 uint8_t *dst_buf1[3], *dst_buf2[3];
7455 int dst_stride1[3] = {64, 64, 64};
7456 int dst_stride2[3] = {64, 64, 64};
7457
7458#if CONFIG_VP9_HIGHBITDEPTH
7459 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
7460 int len = sizeof(uint16_t);
7461 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
7462 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + 4096 * len);
7463 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 8192 * len);
7464 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
7465 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + 4096 * len);
7466 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 8192 * len);
7467 } else {
7468#endif // CONFIG_VP9_HIGHBITDEPTH
7469 dst_buf1[0] = tmp_buf1;
7470 dst_buf1[1] = tmp_buf1 + 4096;
7471 dst_buf1[2] = tmp_buf1 + 8192;
7472 dst_buf2[0] = tmp_buf2;
7473 dst_buf2[1] = tmp_buf2 + 4096;
7474 dst_buf2[2] = tmp_buf2 + 8192;
7475#if CONFIG_VP9_HIGHBITDEPTH
7476 }
7477#endif // CONFIG_VP9_HIGHBITDEPTH
7478#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007479
7480 vp10_zero(best_mbmode);
hui su78b0bd02016-02-23 15:22:25 -08007481 vp10_zero(pmi_uv);
7482
7483 if (cm->allow_screen_content_tools) {
7484 if (above_mi)
7485 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
7486 if (left_mi)
7487 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
7488 }
Jingning Han3ee6db62015-08-05 19:00:31 -07007489
hui sud7c8bc72015-11-12 19:18:32 -08007490#if CONFIG_EXT_INTRA
7491 memset(directional_mode_skip_mask, 0,
7492 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
7493#endif // CONFIG_EXT_INTRA
7494
Jingning Han3ee6db62015-08-05 19:00:31 -07007495 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
7496 filter_cache[i] = INT64_MAX;
7497
7498 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
7499 &comp_mode_p);
7500
7501 for (i = 0; i < REFERENCE_MODES; ++i)
7502 best_pred_rd[i] = INT64_MAX;
7503 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
7504 best_filter_rd[i] = INT64_MAX;
7505 for (i = 0; i < TX_SIZES; i++)
7506 rate_uv_intra[i] = INT_MAX;
7507 for (i = 0; i < MAX_REF_FRAMES; ++i)
7508 x->pred_sse[i] = INT_MAX;
7509 for (i = 0; i < MB_MODE_COUNT; ++i) {
7510 for (k = 0; k < MAX_REF_FRAMES; ++k) {
7511 single_inter_filter[i][k] = SWITCHABLE;
7512 single_skippable[i][k] = 0;
7513 }
7514 }
7515
7516 rd_cost->rate = INT_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08007517#if CONFIG_SUPERTX
7518 *returnrate_nocoef = INT_MAX;
7519#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07007520
7521 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
7522 x->pred_mv_sad[ref_frame] = INT_MAX;
Jingning Han387a10e2015-12-09 09:07:39 -08007523 x->mbmi_ext->mode_context[ref_frame] = 0;
Yue Chen968bbc72016-01-19 16:45:45 -08007524#if CONFIG_REF_MV && CONFIG_EXT_INTER
7525 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
7526#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007527 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
7528 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
7529 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
7530 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
7531 }
7532 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
7533 frame_mv[ZEROMV][ref_frame].as_int = 0;
Yue Chen1ac85872016-01-07 15:13:52 -08007534#if CONFIG_EXT_INTER
7535 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
Yue Chen968bbc72016-01-19 16:45:45 -08007536 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
7537 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
Yue Chen1ac85872016-01-07 15:13:52 -08007538#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007539 }
7540
Jingning Han33cc1bd2016-01-12 15:06:59 -08007541#if CONFIG_REF_MV
7542 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
7543 MODE_INFO *const mi = xd->mi[0];
7544 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
7545 x->mbmi_ext->mode_context[ref_frame] = 0;
7546 vp10_find_mv_refs(cm, xd, mi, ref_frame,
Jingning Han33cc1bd2016-01-12 15:06:59 -08007547 &mbmi_ext->ref_mv_count[ref_frame],
7548 mbmi_ext->ref_mv_stack[ref_frame],
Yue Chen968bbc72016-01-19 16:45:45 -08007549#if CONFIG_EXT_INTER
7550 mbmi_ext->compound_mode_context,
7551#endif // CONFIG_EXT_INTER
Jingning Han33cc1bd2016-01-12 15:06:59 -08007552 candidates, mi_row, mi_col,
7553 NULL, NULL, mbmi_ext->mode_context);
7554 }
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08007555#endif // CONFIG_REF_MV
Jingning Han33cc1bd2016-01-12 15:06:59 -08007556
Yue Chend1cad9c2016-01-27 14:18:53 -08007557#if CONFIG_OBMC
7558 vp10_build_prediction_by_above_preds(cpi, xd, mi_row, mi_col, dst_buf1,
7559 dst_stride1);
7560 vp10_build_prediction_by_left_preds(cpi, xd, mi_row, mi_col, dst_buf2,
7561 dst_stride2);
7562 vp10_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
7563#endif // CONFIG_OBMC
7564
Jingning Han3ee6db62015-08-05 19:00:31 -07007565 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
7566 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
7567 // Skip checking missing references in both single and compound reference
7568 // modes. Note that a mode will be skipped iff both reference frames
7569 // are masked out.
7570 ref_frame_skip_mask[0] |= (1 << ref_frame);
7571 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
Jingning Han1eb760e2015-09-10 12:56:41 -07007572 } else {
Jingning Han3ee6db62015-08-05 19:00:31 -07007573 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
7574 // Skip fixed mv modes for poor references
7575 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
7576 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
7577 break;
7578 }
7579 }
7580 }
7581 // If the segment reference frame feature is enabled....
7582 // then do nothing if the current ref frame is not allowed..
7583 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
7584 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
7585 ref_frame_skip_mask[0] |= (1 << ref_frame);
7586 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7587 }
7588 }
7589
7590 // Disable this drop out case if the ref frame
7591 // segment level feature is enabled for this segment. This is to
7592 // prevent the possibility that we end up unable to pick any mode.
7593 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
7594 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
7595 // unless ARNR filtering is enabled in which case we want
7596 // an unfiltered alternative. We allow near/nearest as well
7597 // because they may result in zero-zero MVs but be cheaper.
7598 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Zoe Liu3ec16012015-11-12 02:12:17 -08007599 ref_frame_skip_mask[0] =
7600 (1 << LAST_FRAME) |
7601#if CONFIG_EXT_REFS
7602 (1 << LAST2_FRAME) |
7603 (1 << LAST3_FRAME) |
7604 (1 << LAST4_FRAME) |
7605#endif // CONFIG_EXT_REFS
7606 (1 << GOLDEN_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07007607 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
7608 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
7609 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != 0)
7610 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
7611 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != 0)
7612 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
Yue Chen968bbc72016-01-19 16:45:45 -08007613#if CONFIG_EXT_INTER
7614 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != 0)
7615 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
7616 if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != 0)
7617 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
7618 if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != 0)
7619 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
7620#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007621 }
7622 }
7623
7624 if (cpi->rc.is_src_frame_alt_ref) {
7625 if (sf->alt_ref_search_fp) {
7626 mode_skip_mask[ALTREF_FRAME] = 0;
7627 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
7628 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
7629 }
7630 }
7631
7632 if (sf->alt_ref_search_fp)
7633 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
7634 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
7635 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
7636
7637 if (sf->adaptive_mode_search) {
7638 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
7639 cpi->rc.frames_since_golden >= 3)
7640 if (x->pred_mv_sad[GOLDEN_FRAME] > (x->pred_mv_sad[LAST_FRAME] << 1))
7641 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
7642 }
7643
7644 if (bsize > sf->max_intra_bsize) {
7645 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
7646 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
7647 }
7648
7649 mode_skip_mask[INTRA_FRAME] |=
7650 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
7651
7652 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i)
7653 mode_threshold[i] = 0;
7654 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
7655 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
7656
7657 midx = sf->schedule_mode_search ? mode_skip_start : 0;
7658 while (midx > 4) {
7659 uint8_t end_pos = 0;
7660 for (i = 5; i < midx; ++i) {
7661 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
7662 uint8_t tmp = mode_map[i];
7663 mode_map[i] = mode_map[i - 1];
7664 mode_map[i - 1] = tmp;
7665 end_pos = i;
7666 }
7667 }
7668 midx = end_pos;
7669 }
7670
7671 for (midx = 0; midx < MAX_MODES; ++midx) {
7672 int mode_index = mode_map[midx];
7673 int mode_excluded = 0;
7674 int64_t this_rd = INT64_MAX;
7675 int disable_skip = 0;
7676 int compmode_cost = 0;
Geza Lore7ded0382016-02-22 10:55:32 +00007677#if CONFIG_EXT_INTER
7678 int compmode_interintra_cost = 0;
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08007679 int compmode_wedge_cost = 0;
Geza Lore7ded0382016-02-22 10:55:32 +00007680#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007681 int rate2 = 0, rate_y = 0, rate_uv = 0;
7682 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
7683 int skippable = 0;
7684 int this_skip2 = 0;
7685 int64_t total_sse = INT64_MAX;
7686 int early_term = 0;
Jingning Han28e03932016-01-20 17:40:47 -08007687#if CONFIG_REF_MV
7688 uint8_t ref_frame_type;
7689#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07007690
7691 this_mode = vp10_mode_order[mode_index].mode;
7692 ref_frame = vp10_mode_order[mode_index].ref_frame[0];
7693 second_ref_frame = vp10_mode_order[mode_index].ref_frame[1];
7694
Yue Chen968bbc72016-01-19 16:45:45 -08007695#if CONFIG_EXT_INTER
Geza Lore7ded0382016-02-22 10:55:32 +00007696 if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
7697 // Mode must by compatible
7698 assert(is_interintra_allowed_mode(this_mode));
7699
7700 if (!is_interintra_allowed_bsize(bsize))
7701 continue;
7702 }
7703
Yue Chen968bbc72016-01-19 16:45:45 -08007704 if (this_mode == NEAREST_NEARESTMV) {
7705 frame_mv[NEAREST_NEARESTMV][ref_frame].as_int =
7706 frame_mv[NEARESTMV][ref_frame].as_int;
7707 frame_mv[NEAREST_NEARESTMV][second_ref_frame].as_int =
7708 frame_mv[NEARESTMV][second_ref_frame].as_int;
7709 } else if (this_mode == NEAREST_NEARMV) {
7710 frame_mv[NEAREST_NEARMV][ref_frame].as_int =
7711 frame_mv[NEARESTMV][ref_frame].as_int;
7712 frame_mv[NEAREST_NEARMV][second_ref_frame].as_int =
7713 frame_mv[NEARMV][second_ref_frame].as_int;
7714 } else if (this_mode == NEAR_NEARESTMV) {
7715 frame_mv[NEAR_NEARESTMV][ref_frame].as_int =
7716 frame_mv[NEARMV][ref_frame].as_int;
7717 frame_mv[NEAR_NEARESTMV][second_ref_frame].as_int =
7718 frame_mv[NEARESTMV][second_ref_frame].as_int;
7719 } else if (this_mode == NEAREST_NEWMV) {
7720 frame_mv[NEAREST_NEWMV][ref_frame].as_int =
7721 frame_mv[NEARESTMV][ref_frame].as_int;
7722 frame_mv[NEAREST_NEWMV][second_ref_frame].as_int =
7723 frame_mv[NEWMV][second_ref_frame].as_int;
7724 } else if (this_mode == NEW_NEARESTMV) {
7725 frame_mv[NEW_NEARESTMV][ref_frame].as_int =
7726 frame_mv[NEWMV][ref_frame].as_int;
7727 frame_mv[NEW_NEARESTMV][second_ref_frame].as_int =
7728 frame_mv[NEARESTMV][second_ref_frame].as_int;
7729 } else if (this_mode == NEAR_NEWMV) {
7730 frame_mv[NEAR_NEWMV][ref_frame].as_int =
7731 frame_mv[NEARMV][ref_frame].as_int;
7732 frame_mv[NEAR_NEWMV][second_ref_frame].as_int =
7733 frame_mv[NEWMV][second_ref_frame].as_int;
7734 } else if (this_mode == NEW_NEARMV) {
7735 frame_mv[NEW_NEARMV][ref_frame].as_int =
7736 frame_mv[NEWMV][ref_frame].as_int;
7737 frame_mv[NEW_NEARMV][second_ref_frame].as_int =
7738 frame_mv[NEARMV][second_ref_frame].as_int;
7739 } else if (this_mode == NEW_NEWMV) {
7740 frame_mv[NEW_NEWMV][ref_frame].as_int =
7741 frame_mv[NEWMV][ref_frame].as_int;
7742 frame_mv[NEW_NEWMV][second_ref_frame].as_int =
7743 frame_mv[NEWMV][second_ref_frame].as_int;
7744 }
7745#endif // CONFIG_EXT_INTER
7746
Jingning Han3ee6db62015-08-05 19:00:31 -07007747 // Look at the reference frame of the best mode so far and set the
7748 // skip mask to look at a subset of the remaining modes.
7749 if (midx == mode_skip_start && best_mode_index >= 0) {
7750 switch (best_mbmode.ref_frame[0]) {
7751 case INTRA_FRAME:
7752 break;
7753 case LAST_FRAME:
7754 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
7755 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7756 break;
Zoe Liu3ec16012015-11-12 02:12:17 -08007757#if CONFIG_EXT_REFS
7758 case LAST2_FRAME:
7759 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
7760 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7761 break;
7762 case LAST3_FRAME:
7763 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
7764 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7765 break;
7766 case LAST4_FRAME:
7767 ref_frame_skip_mask[0] |= LAST4_FRAME_MODE_MASK;
7768 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7769 break;
7770#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07007771 case GOLDEN_FRAME:
7772 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
7773 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7774 break;
7775 case ALTREF_FRAME:
7776 ref_frame_skip_mask[0] |= ALT_REF_MODE_MASK;
7777 break;
7778 case NONE:
7779 case MAX_REF_FRAMES:
7780 assert(0 && "Invalid Reference frame");
7781 break;
7782 }
7783 }
7784
7785 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
James Zern5e16d392015-08-17 18:19:22 -07007786 (ref_frame_skip_mask[1] & (1 << VPXMAX(0, second_ref_frame))))
Jingning Han3ee6db62015-08-05 19:00:31 -07007787 continue;
7788
7789 if (mode_skip_mask[ref_frame] & (1 << this_mode))
7790 continue;
7791
7792 // Test best rd so far against threshold for trying this mode.
7793 if (best_mode_skippable && sf->schedule_mode_search)
7794 mode_threshold[mode_index] <<= 1;
7795
7796 if (best_rd < mode_threshold[mode_index])
7797 continue;
7798
Jingning Han3ee6db62015-08-05 19:00:31 -07007799 comp_pred = second_ref_frame > INTRA_FRAME;
7800 if (comp_pred) {
7801 if (!cpi->allow_comp_inter_inter)
7802 continue;
7803
7804 // Skip compound inter modes if ARF is not available.
7805 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
7806 continue;
7807
7808 // Do not allow compound prediction if the segment level reference frame
7809 // feature is in use as in this case there can only be one reference.
7810 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
7811 continue;
7812
7813 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
7814 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
7815 continue;
7816
7817 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
7818 } else {
7819 if (ref_frame != INTRA_FRAME)
7820 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
7821 }
7822
7823 if (ref_frame == INTRA_FRAME) {
7824 if (sf->adaptive_mode_search)
7825 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
7826 continue;
7827
7828 if (this_mode != DC_PRED) {
7829 // Disable intra modes other than DC_PRED for blocks with low variance
7830 // Threshold for intra skipping based on source variance
7831 // TODO(debargha): Specialize the threshold for super block sizes
7832 const unsigned int skip_intra_var_thresh = 64;
7833 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
7834 x->source_variance < skip_intra_var_thresh)
7835 continue;
7836 // Only search the oblique modes if the best so far is
7837 // one of the neighboring directional modes
7838 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
7839 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
7840 if (best_mode_index >= 0 &&
7841 best_mbmode.ref_frame[0] > INTRA_FRAME)
7842 continue;
7843 }
7844 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
7845 if (conditional_skipintra(this_mode, best_intra_mode))
7846 continue;
7847 }
7848 }
7849 } else {
7850 const MV_REFERENCE_FRAME ref_frames[2] = {ref_frame, second_ref_frame};
Yue Chen968bbc72016-01-19 16:45:45 -08007851 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
7852#if CONFIG_REF_MV && CONFIG_EXT_INTER
7853 mbmi_ext->compound_mode_context,
7854#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
7855 frame_mv,
Jingning Han387a10e2015-12-09 09:07:39 -08007856 this_mode, ref_frames, bsize, -1))
Jingning Han3ee6db62015-08-05 19:00:31 -07007857 continue;
7858 }
7859
7860 mbmi->mode = this_mode;
7861 mbmi->uv_mode = DC_PRED;
7862 mbmi->ref_frame[0] = ref_frame;
7863 mbmi->ref_frame[1] = second_ref_frame;
hui su78b0bd02016-02-23 15:22:25 -08007864 pmi->palette_size[0] = 0;
7865 pmi->palette_size[1] = 0;
hui sube3559b2015-10-07 09:29:02 -07007866#if CONFIG_EXT_INTRA
7867 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
7868 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
7869#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07007870 // Evaluate all sub-pel filters irrespective of whether we can use
7871 // them for this frame.
Debargha Mukherjeebab29122016-02-26 00:18:03 -08007872 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
Jingning Han3ee6db62015-08-05 19:00:31 -07007873 : cm->interp_filter;
7874 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chend1cad9c2016-01-27 14:18:53 -08007875#if CONFIG_OBMC
7876 mbmi->obmc = 0;
7877#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007878
7879 x->skip = 0;
7880 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
7881
7882 // Select prediction reference frames.
7883 for (i = 0; i < MAX_MB_PLANE; i++) {
7884 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
7885 if (comp_pred)
7886 xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
7887 }
7888
Geza Lore7ded0382016-02-22 10:55:32 +00007889#if CONFIG_EXT_INTER
7890 mbmi->interintra_mode = (PREDICTION_MODE)(DC_PRED - 1);
7891 mbmi->interintra_uv_mode = (PREDICTION_MODE)(DC_PRED - 1);
7892#endif // CONFIG_EXT_INTER
7893
Jingning Han3ee6db62015-08-05 19:00:31 -07007894 if (ref_frame == INTRA_FRAME) {
7895 TX_SIZE uv_tx;
7896 struct macroblockd_plane *const pd = &xd->plane[1];
7897 memset(x->skip_txfm, 0, sizeof(x->skip_txfm));
hui sube3559b2015-10-07 09:29:02 -07007898#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08007899 is_directional_mode = (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED);
7900 if (is_directional_mode) {
hui sud7c8bc72015-11-12 19:18:32 -08007901 if (!angle_stats_ready) {
7902 const int src_stride = x->plane[0].src.stride;
7903 const uint8_t *src = x->plane[0].src.buf;
7904 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
7905 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
7906 double hist[DIRECTIONAL_MODES];
7907 PREDICTION_MODE mode;
7908
7909#if CONFIG_VP9_HIGHBITDEPTH
7910 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
7911 highbd_angle_estimation(src, src_stride, rows, cols, hist);
7912 else
7913#endif
7914 angle_estimation(src, src_stride, rows, cols, hist);
7915 for (mode = 0; mode < INTRA_MODES; ++mode) {
7916 if (mode != DC_PRED && mode != TM_PRED) {
7917 int index = get_angle_index((double)mode_to_angle_map[mode]);
7918 double score, weight = 1.0;
7919 score = hist[index];
7920 if (index > 0) {
7921 score += hist[index - 1] * 0.5;
7922 weight += 0.5;
7923 }
7924 if (index < DIRECTIONAL_MODES - 1) {
7925 score += hist[index + 1] * 0.5;
7926 weight += 0.5;
7927 }
7928 score /= weight;
7929 if (score < ANGLE_SKIP_THRESH)
7930 directional_mode_skip_mask[mode] = 1;
7931 }
7932 }
7933 angle_stats_ready = 1;
7934 }
7935 if (directional_mode_skip_mask[mbmi->mode])
7936 continue;
hui su4aa50c12015-11-10 12:09:59 -08007937 rate_overhead = write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0) +
hui su1559afd2015-12-30 10:27:19 -08007938 intra_mode_cost[mbmi->mode];
hui su4aa50c12015-11-10 12:09:59 -08007939 rate_y = INT_MAX;
7940 this_rd =
7941 rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
7942 &skippable, bsize, rate_overhead, best_rd);
7943 } else {
7944 mbmi->angle_delta[0] = 0;
7945 super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
7946 NULL, bsize, best_rd);
7947 }
7948
hui sube3559b2015-10-07 09:29:02 -07007949 // TODO(huisu): ext-intra is turned off in lossless mode for now to
7950 // avoid a unit test failure
hui su4aa50c12015-11-10 12:09:59 -08007951 if (mbmi->mode == DC_PRED && !xd->lossless[mbmi->segment_id] &&
7952 ALLOW_FILTER_INTRA_MODES) {
hui sube3559b2015-10-07 09:29:02 -07007953 MB_MODE_INFO mbmi_copy = *mbmi;
hui sube3559b2015-10-07 09:29:02 -07007954
7955 if (rate_y != INT_MAX) {
hui su1559afd2015-12-30 10:27:19 -08007956 int this_rate = rate_y + intra_mode_cost[mbmi->mode] +
hui sube3559b2015-10-07 09:29:02 -07007957 vp10_cost_bit(cm->fc->ext_intra_probs[0], 0);
7958 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, distortion_y);
7959 } else {
7960 this_rd = best_rd;
7961 }
7962
7963 if (!rd_pick_ext_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
7964 &skippable, bsize,
hui su1559afd2015-12-30 10:27:19 -08007965 intra_mode_cost[mbmi->mode], &this_rd))
hui sube3559b2015-10-07 09:29:02 -07007966 *mbmi = mbmi_copy;
7967 }
hui su4aa50c12015-11-10 12:09:59 -08007968#else
7969 super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
7970 NULL, bsize, best_rd);
hui sube3559b2015-10-07 09:29:02 -07007971#endif // CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08007972
Jingning Han3ee6db62015-08-05 19:00:31 -07007973 if (rate_y == INT_MAX)
7974 continue;
Jingning Han3ee6db62015-08-05 19:00:31 -07007975 uv_tx = get_uv_tx_size_impl(mbmi->tx_size, bsize, pd->subsampling_x,
7976 pd->subsampling_y);
7977 if (rate_uv_intra[uv_tx] == INT_MAX) {
7978 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx,
7979 &rate_uv_intra[uv_tx], &rate_uv_tokenonly[uv_tx],
7980 &dist_uv[uv_tx], &skip_uv[uv_tx], &mode_uv[uv_tx]);
hui su78b0bd02016-02-23 15:22:25 -08007981 if (cm->allow_screen_content_tools)
7982 pmi_uv[uv_tx] = *pmi;
hui sube3559b2015-10-07 09:29:02 -07007983#if CONFIG_EXT_INTRA
7984 ext_intra_mode_info_uv[uv_tx] = mbmi->ext_intra_mode_info;
hui su4aa50c12015-11-10 12:09:59 -08007985 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui sube3559b2015-10-07 09:29:02 -07007986#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07007987 }
7988
7989 rate_uv = rate_uv_tokenonly[uv_tx];
7990 distortion_uv = dist_uv[uv_tx];
7991 skippable = skippable && skip_uv[uv_tx];
7992 mbmi->uv_mode = mode_uv[uv_tx];
hui su78b0bd02016-02-23 15:22:25 -08007993 if (cm->allow_screen_content_tools) {
7994 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
7995 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
7996 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
7997 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
7998 }
hui sube3559b2015-10-07 09:29:02 -07007999#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08008000 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui sube3559b2015-10-07 09:29:02 -07008001 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
8002 ext_intra_mode_info_uv[uv_tx].use_ext_intra_mode[1];
8003 if (ext_intra_mode_info_uv[uv_tx].use_ext_intra_mode[1]) {
8004 mbmi->ext_intra_mode_info.ext_intra_mode[1] =
8005 ext_intra_mode_info_uv[uv_tx].ext_intra_mode[1];
hui sube3559b2015-10-07 09:29:02 -07008006 }
8007#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07008008
hui su1559afd2015-12-30 10:27:19 -08008009 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv_intra[uv_tx];
hui su78b0bd02016-02-23 15:22:25 -08008010 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
8011 rate2 +=
8012 vp10_cost_bit(vp10_default_palette_y_mode_prob[bsize - BLOCK_8X8]
8013 [palette_ctx], 0);
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08008014
8015 if (!xd->lossless[mbmi->segment_id]) {
8016 // super_block_yrd above includes the cost of the tx_size in the
8017 // tokenonly rate, but for intra blocks, tx_size is always coded
8018 // (prediction granularity), so we account for it in the full rate,
8019 // not the tokenonly rate.
hui su954e5602016-03-07 15:25:50 -08008020 rate_y -=
8021 cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
8022 [mbmi->tx_size];
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08008023 }
hui sube3559b2015-10-07 09:29:02 -07008024#if CONFIG_EXT_INTRA
hui su3b1c7662016-01-12 16:38:58 -08008025 if (is_directional_mode) {
8026 int p_angle;
8027 const int intra_filter_ctx = vp10_get_pred_context_intra_interp(xd);
hui su4aa50c12015-11-10 12:09:59 -08008028 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
8029 MAX_ANGLE_DELTAS +
8030 mbmi->angle_delta[0]);
hui su3b1c7662016-01-12 16:38:58 -08008031 p_angle = mode_to_angle_map[mbmi->mode] +
8032 mbmi->angle_delta[0] * ANGLE_STEP;
8033 if (pick_intra_filter(p_angle))
8034 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
8035 }
hui su4aa50c12015-11-10 12:09:59 -08008036
8037 if (mbmi->mode == DC_PRED && ALLOW_FILTER_INTRA_MODES) {
hui sube3559b2015-10-07 09:29:02 -07008038 rate2 += vp10_cost_bit(cm->fc->ext_intra_probs[0],
8039 mbmi->ext_intra_mode_info.use_ext_intra_mode[0]);
8040 if (mbmi->ext_intra_mode_info.use_ext_intra_mode[0]) {
8041 EXT_INTRA_MODE ext_intra_mode =
8042 mbmi->ext_intra_mode_info.ext_intra_mode[0];
hui su4aa50c12015-11-10 12:09:59 -08008043 rate2 += write_uniform_cost(FILTER_INTRA_MODES, ext_intra_mode);
hui sube3559b2015-10-07 09:29:02 -07008044 }
8045 }
8046#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07008047 if (this_mode != DC_PRED && this_mode != TM_PRED)
8048 rate2 += intra_cost_penalty;
8049 distortion2 = distortion_y + distortion_uv;
8050 } else {
Geza Lore7ded0382016-02-22 10:55:32 +00008051#if CONFIG_EXT_INTER
8052 if (second_ref_frame == INTRA_FRAME) {
8053 mbmi->interintra_mode = best_intra_mode;
8054 mbmi->interintra_uv_mode = best_intra_mode;
8055#if CONFIG_EXT_INTRA
8056 // TODO(debargha|geza.lore):
8057 // Should we use ext_intra modes for interintra?
8058 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
8059 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
8060 mbmi->angle_delta[0] = 0;
8061 mbmi->angle_delta[1] = 0;
8062 mbmi->intra_filter = INTRA_FILTER_LINEAR;
8063#endif // CONFIG_EXT_INTRA
8064 }
8065#endif // CONFIG_EXT_INTER
Jingning Han28e03932016-01-20 17:40:47 -08008066#if CONFIG_REF_MV
8067 mbmi->ref_mv_idx = 0;
8068 ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
8069#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07008070 this_rd = handle_inter_mode(cpi, x, bsize,
8071 &rate2, &distortion2, &skippable,
8072 &rate_y, &rate_uv,
8073 &disable_skip, frame_mv,
8074 mi_row, mi_col,
Yue Chend1cad9c2016-01-27 14:18:53 -08008075#if CONFIG_OBMC
8076 dst_buf1, dst_stride1,
8077 dst_buf2, dst_stride2,
8078#endif // CONFIG_OBMC
Yue Chen1ac85872016-01-07 15:13:52 -08008079#if CONFIG_EXT_INTER
8080 single_newmvs,
Geza Lore7ded0382016-02-22 10:55:32 +00008081 single_newmvs_rate,
8082 &compmode_interintra_cost,
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08008083 &compmode_wedge_cost,
Yue Chen1ac85872016-01-07 15:13:52 -08008084#else
8085 single_newmv,
8086#endif // CONFIG_EXT_INTER
8087 single_inter_filter,
Geza Lore7ded0382016-02-22 10:55:32 +00008088 single_skippable,
8089 &total_sse, best_rd,
Jingning Han3ee6db62015-08-05 19:00:31 -07008090 &mask_filter, filter_cache);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07008091
Jingning Han67cf8902016-01-15 09:05:51 -08008092#if CONFIG_REF_MV
Jingning Han4fb8b212016-01-19 16:36:25 -08008093 // TODO(jingning): This needs some refactoring to improve code quality
8094 // and reduce redundant steps.
Jingning Han28e03932016-01-20 17:40:47 -08008095 if (mbmi->mode == NEARMV &&
8096 mbmi_ext->ref_mv_count[ref_frame_type] > 2) {
Jingning Han67cf8902016-01-15 09:05:51 -08008097 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
8098 int_mv cur_mv = mbmi_ext->ref_mv_stack[ref_frame][2].this_mv;
8099 MB_MODE_INFO backup_mbmi = *mbmi;
8100
Jingning Han4fb8b212016-01-19 16:36:25 -08008101 int64_t tmp_ref_rd = this_rd;
8102 int ref_idx;
Jingning Han28e03932016-01-20 17:40:47 -08008103 int ref_set = VPXMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 2);
8104
Jingning Han49589872016-01-21 18:07:31 -08008105 uint8_t drl0_ctx =
Jingning Hana39e83d2016-02-11 16:38:13 -08008106 vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 1);
Jingning Han49589872016-01-21 18:07:31 -08008107 rate2 += cpi->drl_mode_cost0[drl0_ctx][0];
Jingning Han67cf8902016-01-15 09:05:51 -08008108
Jingning Han590265e2016-01-15 11:33:40 -08008109 if (this_rd < INT64_MAX) {
8110 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
8111 RDCOST(x->rdmult, x->rddiv, 0, total_sse))
8112 tmp_ref_rd = RDCOST(x->rdmult, x->rddiv,
8113 rate2 + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0),
8114 distortion2);
8115 else
8116 tmp_ref_rd = RDCOST(x->rdmult, x->rddiv,
8117 rate2 + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1) -
8118 rate_y - rate_uv,
8119 total_sse);
8120 }
Jingning Han7174d632016-03-03 09:20:10 -08008121#if CONFIG_VAR_TX
8122 for (i = 0; i < MAX_MB_PLANE; ++i)
8123 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
8124 sizeof(uint8_t) * ctx->num_4x4_blk);
8125#endif
Jingning Han590265e2016-01-15 11:33:40 -08008126
Jingning Han4fb8b212016-01-19 16:36:25 -08008127 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
8128 int64_t tmp_alt_rd = INT64_MAX;
8129 int tmp_rate = 0, tmp_rate_y = 0, tmp_rate_uv = 0;
8130 int tmp_skip = 1;
8131 int64_t tmp_dist = 0, tmp_sse = 0;
Jingning Han590265e2016-01-15 11:33:40 -08008132
Jingning Han4fb8b212016-01-19 16:36:25 -08008133 cur_mv = mbmi_ext->ref_mv_stack[ref_frame][2 + ref_idx].this_mv;
8134 lower_mv_precision(&cur_mv.as_mv, cm->allow_high_precision_mv);
8135 clamp_mv2(&cur_mv.as_mv, xd);
8136
8137 if (!mv_check_bounds(x, &cur_mv.as_mv)) {
8138 int64_t dummy_filter_cache[SWITCHABLE_FILTER_CONTEXTS];
8139 INTERP_FILTER dummy_single_inter_filter[MB_MODE_COUNT]
8140 [MAX_REF_FRAMES];
8141 int dummy_single_skippable[MB_MODE_COUNT][MAX_REF_FRAMES];
8142 int dummy_disable_skip = 0;
8143 int64_t dummy_mask_filter = 0;
8144#if CONFIG_EXT_INTER
8145 int_mv dummy_single_newmvs[2][MAX_REF_FRAMES] =
8146 { { { 0 } }, { { 0 } } };
Geza Lore7ded0382016-02-22 10:55:32 +00008147 int dummy_single_newmvs_rate[2][MAX_REF_FRAMES] =
8148 { { 0 }, { 0 } };
8149 int dummy_compmode_interintra_cost = 0;
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08008150 int dummy_compmode_wedge_cost = 0;
Jingning Han4fb8b212016-01-19 16:36:25 -08008151#else
8152 int_mv dummy_single_newmv[MAX_REF_FRAMES] = { { 0 } };
8153#endif
Jingning Han28e03932016-01-20 17:40:47 -08008154 mbmi->ref_mv_idx = 1 + ref_idx;
8155
Jingning Han4fb8b212016-01-19 16:36:25 -08008156 frame_mv[NEARMV][ref_frame] = cur_mv;
8157 tmp_alt_rd = handle_inter_mode(cpi, x, bsize,
8158 &tmp_rate, &tmp_dist, &tmp_skip,
8159 &tmp_rate_y, &tmp_rate_uv,
8160 &dummy_disable_skip, frame_mv,
8161 mi_row, mi_col,
Yue Chend1cad9c2016-01-27 14:18:53 -08008162#if CONFIG_OBMC
8163 dst_buf1, dst_stride1,
8164 dst_buf2, dst_stride2,
8165#endif // CONFIG_OBMC
Jingning Han4fb8b212016-01-19 16:36:25 -08008166#if CONFIG_EXT_INTER
8167 dummy_single_newmvs,
Geza Lore7ded0382016-02-22 10:55:32 +00008168 dummy_single_newmvs_rate,
8169 &dummy_compmode_interintra_cost,
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08008170 &dummy_compmode_wedge_cost,
Jingning Han4fb8b212016-01-19 16:36:25 -08008171#else
8172 dummy_single_newmv,
8173#endif
8174 dummy_single_inter_filter,
8175 dummy_single_skippable,
8176 &tmp_sse, best_rd,
8177 &dummy_mask_filter,
8178 dummy_filter_cache);
8179 }
8180
Jingning Han49589872016-01-21 18:07:31 -08008181 tmp_rate += cpi->drl_mode_cost0[drl0_ctx][1];
8182
8183 if (mbmi_ext->ref_mv_count[ref_frame_type] > 3) {
8184 uint8_t drl1_ctx =
Jingning Hana39e83d2016-02-11 16:38:13 -08008185 vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 2);
Jingning Han49589872016-01-21 18:07:31 -08008186 tmp_rate += cpi->drl_mode_cost1[drl1_ctx][ref_idx];
8187 }
Jingning Han4fb8b212016-01-19 16:36:25 -08008188
8189 if (tmp_alt_rd < INT64_MAX) {
Yue Chena6142622016-02-18 12:35:14 -08008190#if CONFIG_OBMC
8191 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv, tmp_rate, tmp_dist);
8192#else
Jingning Han4fb8b212016-01-19 16:36:25 -08008193 if (RDCOST(x->rdmult, x->rddiv,
8194 tmp_rate_y + tmp_rate_uv, tmp_dist) <
8195 RDCOST(x->rdmult, x->rddiv, 0, tmp_sse))
8196 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv,
8197 tmp_rate + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0),
8198 tmp_dist);
8199 else
8200 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv,
8201 tmp_rate + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1) -
8202 tmp_rate_y - tmp_rate_uv,
8203 tmp_sse);
Yue Chena6142622016-02-18 12:35:14 -08008204#endif // CONFIG_OBMC
Jingning Han4fb8b212016-01-19 16:36:25 -08008205 }
8206
8207 if (tmp_ref_rd > tmp_alt_rd) {
8208 rate2 = tmp_rate;
8209 distortion2 = tmp_dist;
8210 skippable = tmp_skip;
8211 rate_y = tmp_rate_y;
8212 rate_uv = tmp_rate_uv;
8213 total_sse = tmp_sse;
8214 this_rd = tmp_alt_rd;
Jingning Han4fb8b212016-01-19 16:36:25 -08008215 tmp_ref_rd = tmp_alt_rd;
8216 backup_mbmi = *mbmi;
Jingning Han7174d632016-03-03 09:20:10 -08008217#if CONFIG_VAR_TX
8218 for (i = 0; i < MAX_MB_PLANE; ++i)
8219 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
8220 sizeof(uint8_t) * ctx->num_4x4_blk);
8221#endif
Jingning Han4fb8b212016-01-19 16:36:25 -08008222 } else {
8223 *mbmi = backup_mbmi;
8224 }
Jingning Han67cf8902016-01-15 09:05:51 -08008225 }
8226
8227 frame_mv[NEARMV][ref_frame] = backup_mv;
Jingning Han7174d632016-03-03 09:20:10 -08008228#if CONFIG_VAR_TX
8229 for (i = 0; i < MAX_MB_PLANE; ++i)
8230 memcpy(x->blk_skip[i], x->blk_skip_drl[i],
8231 sizeof(uint8_t) * ctx->num_4x4_blk);
8232#endif
Jingning Han67cf8902016-01-15 09:05:51 -08008233 }
Geza Lore7ded0382016-02-22 10:55:32 +00008234#endif // CONFIG_REF_MV
Jingning Han67cf8902016-01-15 09:05:51 -08008235
Jingning Han3ee6db62015-08-05 19:00:31 -07008236 if (this_rd == INT64_MAX)
8237 continue;
8238
8239 compmode_cost = vp10_cost_bit(comp_mode_p, comp_pred);
8240
8241 if (cm->reference_mode == REFERENCE_MODE_SELECT)
8242 rate2 += compmode_cost;
8243 }
8244
Geza Lore7ded0382016-02-22 10:55:32 +00008245#if CONFIG_EXT_INTER
8246 rate2 += compmode_interintra_cost;
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08008247 if (cm->reference_mode != SINGLE_REFERENCE && comp_pred)
8248 rate2 += compmode_wedge_cost;
Geza Lore7ded0382016-02-22 10:55:32 +00008249#endif // CONFIG_EXT_INTER
8250
Jingning Han3ee6db62015-08-05 19:00:31 -07008251 // Estimate the reference frame signaling cost and add it
8252 // to the rolling cost variable.
8253 if (comp_pred) {
8254 rate2 += ref_costs_comp[ref_frame];
8255 } else {
8256 rate2 += ref_costs_single[ref_frame];
8257 }
8258
Yue Chena6142622016-02-18 12:35:14 -08008259#if CONFIG_OBMC
8260 if (ref_frame == INTRA_FRAME) {
8261#else
Jingning Han3ee6db62015-08-05 19:00:31 -07008262 if (!disable_skip) {
Yue Chena6142622016-02-18 12:35:14 -08008263#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07008264 if (skippable) {
8265 // Back out the coefficient coding costs
8266 rate2 -= (rate_y + rate_uv);
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008267 rate_y = 0;
8268 rate_uv = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07008269 // Cost the skip mb case
8270 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04008271 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Jingning Han3ee6db62015-08-05 19:00:31 -07008272 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
8273 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
8274 // Add in the cost of the no skip flag.
8275 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
8276 } else {
8277 // FIXME(rbultje) make this work for splitmv also
8278 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
8279 distortion2 = total_sse;
8280 assert(total_sse >= 0);
8281 rate2 -= (rate_y + rate_uv);
8282 this_skip2 = 1;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008283 rate_y = 0;
8284 rate_uv = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07008285 }
8286 } else {
8287 // Add in the cost of the no skip flag.
8288 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
8289 }
8290
8291 // Calculate the final RD estimate for this mode.
8292 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yue Chena6142622016-02-18 12:35:14 -08008293#if CONFIG_OBMC
8294 } else {
8295 this_skip2 = mbmi->skip;
8296 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
8297#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07008298 }
8299
Yue Chena6142622016-02-18 12:35:14 -08008300
Jingning Han3ee6db62015-08-05 19:00:31 -07008301 // Apply an adjustment to the rd value based on the similarity of the
8302 // source variance and reconstructed variance.
Yue Chena6142622016-02-18 12:35:14 -08008303 rd_variance_adjustment(cpi, x, bsize, &this_rd, ref_frame,
8304#if CONFIG_OBMC
8305 is_inter_block(mbmi),
8306#endif // CONFIG_OBMC
8307 x->source_variance);
Jingning Han3ee6db62015-08-05 19:00:31 -07008308
8309 if (ref_frame == INTRA_FRAME) {
8310 // Keep record of best intra rd
8311 if (this_rd < best_intra_rd) {
8312 best_intra_rd = this_rd;
8313 best_intra_mode = mbmi->mode;
8314 }
8315 }
8316
8317 if (!disable_skip && ref_frame == INTRA_FRAME) {
8318 for (i = 0; i < REFERENCE_MODES; ++i)
James Zern5e16d392015-08-17 18:19:22 -07008319 best_pred_rd[i] = VPXMIN(best_pred_rd[i], this_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07008320 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
James Zern5e16d392015-08-17 18:19:22 -07008321 best_filter_rd[i] = VPXMIN(best_filter_rd[i], this_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07008322 }
8323
8324 // Did this mode help.. i.e. is it the new best mode
8325 if (this_rd < best_rd || x->skip) {
8326 int max_plane = MAX_MB_PLANE;
8327 if (!mode_excluded) {
8328 // Note index of best mode so far
8329 best_mode_index = mode_index;
8330
8331 if (ref_frame == INTRA_FRAME) {
8332 /* required for left and above block mv */
8333 mbmi->mv[0].as_int = 0;
8334 max_plane = 1;
8335 } else {
8336 best_pred_sse = x->pred_sse[ref_frame];
8337 }
8338
8339 rd_cost->rate = rate2;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008340#if CONFIG_SUPERTX
8341 *returnrate_nocoef = rate2 - rate_y - rate_uv;
8342 if (!disable_skip) {
8343 *returnrate_nocoef -= vp10_cost_bit(vp10_get_skip_prob(cm, xd),
8344 skippable || this_skip2);
8345 }
8346 *returnrate_nocoef -= vp10_cost_bit(vp10_get_intra_inter_prob(cm, xd),
8347 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chend1cad9c2016-01-27 14:18:53 -08008348#if CONFIG_OBMC
8349 if (is_inter_block(mbmi) && is_obmc_allowed(mbmi))
8350 *returnrate_nocoef -= cpi->obmc_cost[bsize][mbmi->obmc];
8351#endif // CONFIG_OBMC
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008352#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07008353 rd_cost->dist = distortion2;
8354 rd_cost->rdcost = this_rd;
8355 best_rd = this_rd;
8356 best_mbmode = *mbmi;
8357 best_skip2 = this_skip2;
8358 best_mode_skippable = skippable;
8359
8360 if (!x->select_tx_size)
8361 swap_block_ptr(x, ctx, 1, 0, 0, max_plane);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07008362
8363#if CONFIG_VAR_TX
8364 for (i = 0; i < MAX_MB_PLANE; ++i)
8365 memcpy(ctx->blk_skip[i], x->blk_skip[i],
8366 sizeof(uint8_t) * ctx->num_4x4_blk);
8367#else
Jingning Han3ee6db62015-08-05 19:00:31 -07008368 memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
hui su088b05f2015-08-12 10:41:51 -07008369 sizeof(ctx->zcoeff_blk[0]) * ctx->num_4x4_blk);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07008370#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07008371
8372 // TODO(debargha): enhance this test with a better distortion prediction
8373 // based on qp, activity mask and history
8374 if ((mode_search_skip_flags & FLAG_EARLY_TERMINATE) &&
8375 (mode_index > MIN_EARLY_TERM_INDEX)) {
8376 int qstep = xd->plane[0].dequant[1];
8377 // TODO(debargha): Enhance this by specializing for each mode_index
8378 int scale = 4;
8379#if CONFIG_VP9_HIGHBITDEPTH
8380 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
8381 qstep >>= (xd->bd - 8);
8382 }
8383#endif // CONFIG_VP9_HIGHBITDEPTH
8384 if (x->source_variance < UINT_MAX) {
8385 const int var_adjust = (x->source_variance < 16);
8386 scale -= var_adjust;
8387 }
8388 if (ref_frame > INTRA_FRAME &&
8389 distortion2 * scale < qstep * qstep) {
8390 early_term = 1;
8391 }
8392 }
8393 }
8394 }
8395
8396 /* keep record of best compound/single-only prediction */
8397 if (!disable_skip && ref_frame != INTRA_FRAME) {
8398 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
8399
8400 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
8401 single_rate = rate2 - compmode_cost;
8402 hybrid_rate = rate2;
8403 } else {
8404 single_rate = rate2;
8405 hybrid_rate = rate2 + compmode_cost;
8406 }
8407
8408 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
8409 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
8410
8411 if (!comp_pred) {
8412 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
8413 best_pred_rd[SINGLE_REFERENCE] = single_rd;
8414 } else {
8415 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
8416 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
8417 }
8418 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
8419 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
8420
8421 /* keep record of best filter type */
8422 if (!mode_excluded && cm->interp_filter != BILINEAR) {
8423 int64_t ref = filter_cache[cm->interp_filter == SWITCHABLE ?
8424 SWITCHABLE_FILTERS : cm->interp_filter];
8425
8426 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
8427 int64_t adj_rd;
8428 if (ref == INT64_MAX)
8429 adj_rd = 0;
8430 else if (filter_cache[i] == INT64_MAX)
8431 // when early termination is triggered, the encoder does not have
8432 // access to the rate-distortion cost. it only knows that the cost
8433 // should be above the maximum valid value. hence it takes the known
8434 // maximum plus an arbitrary constant as the rate-distortion cost.
8435 adj_rd = mask_filter - ref + 10;
8436 else
8437 adj_rd = filter_cache[i] - ref;
8438
8439 adj_rd += this_rd;
James Zern5e16d392015-08-17 18:19:22 -07008440 best_filter_rd[i] = VPXMIN(best_filter_rd[i], adj_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07008441 }
8442 }
8443 }
8444
8445 if (early_term)
8446 break;
8447
8448 if (x->skip && !comp_pred)
8449 break;
8450 }
8451
hui su78b0bd02016-02-23 15:22:25 -08008452 // Only try palette mode when the best mode so far is an intra mode.
8453 if (cm->allow_screen_content_tools && !is_inter_mode(best_mbmode.mode)) {
8454 PREDICTION_MODE mode_selected;
8455 int rate2 = 0, rate_y = 0;
8456 int64_t distortion2 = 0, distortion_y = 0, dummy_rd = best_rd, this_rd;
8457 int skippable = 0, rate_overhead = 0;
8458 TX_SIZE best_tx_size, uv_tx;
8459 PALETTE_MODE_INFO palette_mode_info;
8460 uint8_t *const best_palette_color_map =
8461 x->palette_buffer->best_palette_color_map;
8462 uint8_t *const color_map = xd->plane[0].color_index_map;
8463
8464 mbmi->mode = DC_PRED;
8465 mbmi->uv_mode = DC_PRED;
8466 mbmi->ref_frame[0] = INTRA_FRAME;
8467 mbmi->ref_frame[1] = NONE;
8468 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
8469 palette_mode_info.palette_size[0] = 0;
8470 rate_overhead =
8471 rd_pick_palette_intra_sby(cpi, x, bsize, palette_ctx,
8472 intra_mode_cost[DC_PRED],
8473 &palette_mode_info, best_palette_color_map,
8474 &best_tx_size, &mode_selected, &dummy_rd);
8475 if (palette_mode_info.palette_size[0] == 0)
8476 goto PALETTE_EXIT;
8477
8478 pmi->palette_size[0] =
8479 palette_mode_info.palette_size[0];
8480 if (palette_mode_info.palette_size[0] > 0) {
8481 memcpy(pmi->palette_colors, palette_mode_info.palette_colors,
8482 PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
8483 memcpy(color_map, best_palette_color_map,
8484 rows * cols * sizeof(best_palette_color_map[0]));
8485 }
8486 super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
8487 NULL, bsize, best_rd);
8488 if (rate_y == INT_MAX)
8489 goto PALETTE_EXIT;
8490 uv_tx = get_uv_tx_size_impl(mbmi->tx_size, bsize,
8491 xd->plane[1].subsampling_x,
8492 xd->plane[1].subsampling_y);
8493 if (rate_uv_intra[uv_tx] == INT_MAX) {
8494 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx,
8495 &rate_uv_intra[uv_tx], &rate_uv_tokenonly[uv_tx],
8496 &dist_uv[uv_tx], &skip_uv[uv_tx], &mode_uv[uv_tx]);
8497 pmi_uv[uv_tx] = *pmi;
8498#if CONFIG_EXT_INTRA
8499 ext_intra_mode_info_uv[uv_tx] = mbmi->ext_intra_mode_info;
8500 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
8501#endif // CONFIG_EXT_INTRA
8502 }
8503 mbmi->uv_mode = mode_uv[uv_tx];
8504 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
8505 if (pmi->palette_size[1] > 0)
8506 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
8507 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
8508 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
8509#if CONFIG_EXT_INTRA
8510 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
8511 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
8512 ext_intra_mode_info_uv[uv_tx].use_ext_intra_mode[1];
8513 if (ext_intra_mode_info_uv[uv_tx].use_ext_intra_mode[1]) {
8514 mbmi->ext_intra_mode_info.ext_intra_mode[1] =
8515 ext_intra_mode_info_uv[uv_tx].ext_intra_mode[1];
8516 }
8517#endif // CONFIG_EXT_INTRA
8518 skippable = skippable && skip_uv[uv_tx];
8519 distortion2 = distortion_y + dist_uv[uv_tx];
8520 rate2 = rate_y + rate_overhead + rate_uv_intra[uv_tx];
8521 rate2 += ref_costs_single[INTRA_FRAME];
8522
8523 if (skippable) {
8524 rate2 -= (rate_y + rate_uv_tokenonly[uv_tx]);
8525 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
8526 } else {
8527 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
8528 }
8529 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
8530 if (this_rd < best_rd) {
8531 int max_plane = MAX_MB_PLANE;
8532 best_mode_index = 3;
8533 mbmi->mv[0].as_int = 0;
8534 max_plane = 1;
8535 rd_cost->rate = rate2;
8536 rd_cost->dist = distortion2;
8537 rd_cost->rdcost = this_rd;
8538 best_rd = this_rd;
8539 best_mbmode = *mbmi;
8540 best_skip2 = 0;
8541 best_mode_skippable = skippable;
8542 if (!x->select_tx_size)
8543 swap_block_ptr(x, ctx, 1, 0, 0, max_plane);
8544 memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
8545 sizeof(ctx->zcoeff_blk[0]) * ctx->num_4x4_blk);
8546 }
8547 }
8548 PALETTE_EXIT:
8549
Jingning Han3ee6db62015-08-05 19:00:31 -07008550 // The inter modes' rate costs are not calculated precisely in some cases.
8551 // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
8552 // ZEROMV. Here, checks are added for those cases, and the mode decisions
8553 // are corrected.
Yue Chen1ac85872016-01-07 15:13:52 -08008554 if (best_mbmode.mode == NEWMV
8555#if CONFIG_EXT_INTER
8556 || best_mbmode.mode == NEWFROMNEARMV
Yue Chen968bbc72016-01-19 16:45:45 -08008557 || best_mbmode.mode == NEW_NEWMV
Yue Chen1ac85872016-01-07 15:13:52 -08008558#endif // CONFIG_EXT_INTER
8559 ) {
Jingning Han3ee6db62015-08-05 19:00:31 -07008560 const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0],
8561 best_mbmode.ref_frame[1]};
8562 int comp_pred_mode = refs[1] > INTRA_FRAME;
Jingning Han33cc1bd2016-01-12 15:06:59 -08008563#if CONFIG_REF_MV
Geza Lore7ded0382016-02-22 10:55:32 +00008564 const uint8_t rf_type = vp10_ref_frame_type(best_mbmode.ref_frame);
Jingning Han33cc1bd2016-01-12 15:06:59 -08008565 if (!comp_pred_mode) {
Geza Lore7ded0382016-02-22 10:55:32 +00008566 if (best_mbmode.ref_mv_idx > 0 && refs[1] == NONE) {
8567 int idx = best_mbmode.ref_mv_idx + 1;
8568 int_mv cur_mv = mbmi_ext->ref_mv_stack[refs[0]][idx].this_mv;
Jingning Han67cf8902016-01-15 09:05:51 -08008569 lower_mv_precision(&cur_mv.as_mv, cm->allow_high_precision_mv);
8570 frame_mv[NEARMV][refs[0]] = cur_mv;
8571 }
8572
Jingning Han33cc1bd2016-01-12 15:06:59 -08008573 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
8574 best_mbmode.mode = NEARESTMV;
8575 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
8576 best_mbmode.mode = NEARMV;
8577 else if (best_mbmode.mv[0].as_int == 0)
8578 best_mbmode.mode = ZEROMV;
8579 } else {
Jingning Han3944cfb2016-01-13 09:03:15 -08008580 int i;
8581 const int allow_hp = cm->allow_high_precision_mv;
8582 int_mv nearestmv[2] = { frame_mv[NEARESTMV][refs[0]],
8583 frame_mv[NEARESTMV][refs[1]] };
Jingning Han3ee6db62015-08-05 19:00:31 -07008584
Jingning Han3944cfb2016-01-13 09:03:15 -08008585 int_mv nearmv[2] = { frame_mv[NEARMV][refs[0]],
8586 frame_mv[NEARMV][refs[1]] };
8587
8588 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
Jingning Han33cc1bd2016-01-12 15:06:59 -08008589 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
8590 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
Jingning Han3944cfb2016-01-13 09:03:15 -08008591 }
8592
8593 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
Geza Lore7ded0382016-02-22 10:55:32 +00008594 int ref_mv_idx = best_mbmode.ref_mv_idx + 1;
Jingning Han28e03932016-01-20 17:40:47 -08008595 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][ref_mv_idx].this_mv;
8596 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][ref_mv_idx].comp_mv;
Jingning Han33cc1bd2016-01-12 15:06:59 -08008597 }
Jingning Han3944cfb2016-01-13 09:03:15 -08008598
8599 for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
8600 lower_mv_precision(&nearestmv[i].as_mv, allow_hp);
8601 lower_mv_precision(&nearmv[i].as_mv, allow_hp);
8602 }
8603
8604 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
8605 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
Yue Chen968bbc72016-01-19 16:45:45 -08008606#if CONFIG_EXT_INTER
8607 best_mbmode.mode = NEAREST_NEARESTMV;
8608 else if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
8609 nearmv[1].as_int == best_mbmode.mv[1].as_int)
8610 best_mbmode.mode = NEAREST_NEARMV;
8611 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
8612 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
8613 best_mbmode.mode = NEAR_NEARESTMV;
8614 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
8615 best_mbmode.mode = ZERO_ZEROMV;
8616#else
Jingning Han3944cfb2016-01-13 09:03:15 -08008617 best_mbmode.mode = NEARESTMV;
8618 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
8619 nearmv[1].as_int == best_mbmode.mv[1].as_int)
8620 best_mbmode.mode = NEARMV;
8621 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
8622 best_mbmode.mode = ZEROMV;
Yue Chen968bbc72016-01-19 16:45:45 -08008623#endif // CONFIG_EXT_INTER
Jingning Han33cc1bd2016-01-12 15:06:59 -08008624 }
8625#else
Yue Chen968bbc72016-01-19 16:45:45 -08008626#if CONFIG_EXT_INTER
8627 if (!comp_pred_mode) {
8628#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07008629 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
8630 ((comp_pred_mode && frame_mv[NEARESTMV][refs[1]].as_int ==
8631 best_mbmode.mv[1].as_int) || !comp_pred_mode))
8632 best_mbmode.mode = NEARESTMV;
8633 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
8634 ((comp_pred_mode && frame_mv[NEARMV][refs[1]].as_int ==
8635 best_mbmode.mv[1].as_int) || !comp_pred_mode))
8636 best_mbmode.mode = NEARMV;
8637 else if (best_mbmode.mv[0].as_int == 0 &&
8638 ((comp_pred_mode && best_mbmode.mv[1].as_int == 0) || !comp_pred_mode))
8639 best_mbmode.mode = ZEROMV;
Yue Chen968bbc72016-01-19 16:45:45 -08008640#if CONFIG_EXT_INTER
8641 } else {
8642 const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0],
8643 best_mbmode.ref_frame[1]};
8644
8645 if (frame_mv[NEAREST_NEARESTMV][refs[0]].as_int ==
8646 best_mbmode.mv[0].as_int &&
8647 frame_mv[NEAREST_NEARESTMV][refs[1]].as_int ==
8648 best_mbmode.mv[1].as_int)
8649 best_mbmode.mode = NEAREST_NEARESTMV;
8650 else if (frame_mv[NEAREST_NEARMV][refs[0]].as_int ==
8651 best_mbmode.mv[0].as_int &&
8652 frame_mv[NEAREST_NEARMV][refs[1]].as_int ==
8653 best_mbmode.mv[1].as_int)
8654 best_mbmode.mode = NEAREST_NEARMV;
8655 else if (frame_mv[NEAR_NEARESTMV][refs[0]].as_int ==
8656 best_mbmode.mv[0].as_int &&
8657 frame_mv[NEAR_NEARESTMV][refs[1]].as_int ==
8658 best_mbmode.mv[1].as_int)
8659 best_mbmode.mode = NEAR_NEARESTMV;
8660 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
8661 best_mbmode.mode = ZERO_ZEROMV;
8662 }
8663#endif // CONFIG_EXT_INTER
Jingning Han33cc1bd2016-01-12 15:06:59 -08008664#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07008665 }
8666
Jingning Hanaa5d53e2015-12-07 15:54:59 -08008667#if CONFIG_REF_MV
8668 if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
8669 best_mbmode.mv[0].as_int == 0 &&
Yue Chen968bbc72016-01-19 16:45:45 -08008670#if CONFIG_EXT_INTER
Geza Lore7ded0382016-02-22 10:55:32 +00008671 (best_mbmode.ref_frame[1] <= INTRA_FRAME)
Yue Chen968bbc72016-01-19 16:45:45 -08008672#else
Geza Lore7ded0382016-02-22 10:55:32 +00008673 (best_mbmode.ref_frame[1] == NONE || best_mbmode.mv[1].as_int == 0)
Yue Chen968bbc72016-01-19 16:45:45 -08008674#endif // CONFIG_EXT_INTER
Geza Lore7ded0382016-02-22 10:55:32 +00008675 ) {
Jingning Hanaa5d53e2015-12-07 15:54:59 -08008676 int16_t mode_ctx = mbmi_ext->mode_context[best_mbmode.ref_frame[0]];
Yue Chen968bbc72016-01-19 16:45:45 -08008677#if !CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08008678 if (best_mbmode.ref_frame[1] > NONE)
8679 mode_ctx &= (mbmi_ext->mode_context[best_mbmode.ref_frame[1]] | 0x00ff);
Yue Chen968bbc72016-01-19 16:45:45 -08008680#endif // !CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08008681
8682 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET))
8683 best_mbmode.mode = ZEROMV;
8684 }
8685#endif
8686
Jingning Han3ee6db62015-08-05 19:00:31 -07008687 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
8688 rd_cost->rate = INT_MAX;
8689 rd_cost->rdcost = INT64_MAX;
8690 return;
8691 }
8692
8693 // If we used an estimate for the uv intra rd in the loop above...
8694 if (sf->use_uv_intra_rd_estimate) {
8695 // Do Intra UV best rd mode selection if best mode choice above was intra.
8696 if (best_mbmode.ref_frame[0] == INTRA_FRAME) {
8697 TX_SIZE uv_tx_size;
8698 *mbmi = best_mbmode;
8699 uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
8700 rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra[uv_tx_size],
8701 &rate_uv_tokenonly[uv_tx_size],
8702 &dist_uv[uv_tx_size],
8703 &skip_uv[uv_tx_size],
8704 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize,
8705 uv_tx_size);
8706 }
8707 }
8708
8709 assert((cm->interp_filter == SWITCHABLE) ||
8710 (cm->interp_filter == best_mbmode.interp_filter) ||
8711 !is_inter_block(&best_mbmode));
8712
8713 if (!cpi->rc.is_src_frame_alt_ref)
8714 vp10_update_rd_thresh_fact(tile_data->thresh_freq_fact,
8715 sf->adaptive_rd_thresh, bsize, best_mode_index);
8716
8717 // macroblock modes
8718 *mbmi = best_mbmode;
8719 x->skip |= best_skip2;
8720
Jingning Handf59bb82016-02-18 11:57:44 -08008721#if CONFIG_REF_MV
8722 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
8723 if (mbmi->mode != NEWMV)
8724 mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
8725 else
8726 mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
8727 }
8728#endif
8729
Jingning Han3ee6db62015-08-05 19:00:31 -07008730 for (i = 0; i < REFERENCE_MODES; ++i) {
8731 if (best_pred_rd[i] == INT64_MAX)
8732 best_pred_diff[i] = INT_MIN;
8733 else
8734 best_pred_diff[i] = best_rd - best_pred_rd[i];
8735 }
8736
8737 if (!x->skip) {
8738 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
8739 if (best_filter_rd[i] == INT64_MAX)
8740 best_filter_diff[i] = 0;
8741 else
8742 best_filter_diff[i] = best_rd - best_filter_rd[i];
8743 }
8744 if (cm->interp_filter == SWITCHABLE)
8745 assert(best_filter_diff[SWITCHABLE_FILTERS] == 0);
8746 } else {
8747 vp10_zero(best_filter_diff);
8748 }
8749
8750 // TODO(yunqingwang): Moving this line in front of the above best_filter_diff
8751 // updating code causes PSNR loss. Need to figure out the confliction.
8752 x->skip |= best_mode_skippable;
8753
8754 if (!x->skip && !x->select_tx_size) {
8755 int has_high_freq_coeff = 0;
8756 int plane;
8757 int max_plane = is_inter_block(&xd->mi[0]->mbmi)
8758 ? MAX_MB_PLANE : 1;
8759 for (plane = 0; plane < max_plane; ++plane) {
8760 x->plane[plane].eobs = ctx->eobs_pbuf[plane][1];
8761 has_high_freq_coeff |= vp10_has_high_freq_in_plane(x, bsize, plane);
8762 }
8763
8764 for (plane = max_plane; plane < MAX_MB_PLANE; ++plane) {
8765 x->plane[plane].eobs = ctx->eobs_pbuf[plane][2];
8766 has_high_freq_coeff |= vp10_has_high_freq_in_plane(x, bsize, plane);
8767 }
8768
8769 best_mode_skippable |= !has_high_freq_coeff;
8770 }
8771
8772 assert(best_mode_index >= 0);
8773
8774 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
8775 best_filter_diff, best_mode_skippable);
hui su78b0bd02016-02-23 15:22:25 -08008776
8777 if (cm->allow_screen_content_tools && pmi->palette_size[1] > 0) {
8778 restore_uv_color_map(cpi, x);
8779 }
Jingning Han3ee6db62015-08-05 19:00:31 -07008780}
8781
Yaowu Xu26a9afc2015-08-13 09:42:27 -07008782void vp10_rd_pick_inter_mode_sb_seg_skip(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07008783 TileDataEnc *tile_data,
8784 MACROBLOCK *x,
8785 RD_COST *rd_cost,
8786 BLOCK_SIZE bsize,
8787 PICK_MODE_CONTEXT *ctx,
8788 int64_t best_rd_so_far) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07008789 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07008790 MACROBLOCKD *const xd = &x->e_mbd;
8791 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
8792 unsigned char segment_id = mbmi->segment_id;
8793 const int comp_pred = 0;
8794 int i;
8795 int64_t best_pred_diff[REFERENCE_MODES];
8796 int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
8797 unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
8798 vpx_prob comp_mode_p;
8799 INTERP_FILTER best_filter = SWITCHABLE;
8800 int64_t this_rd = INT64_MAX;
8801 int rate2 = 0;
8802 const int64_t distortion2 = 0;
8803
Jingning Han3ee6db62015-08-05 19:00:31 -07008804 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
8805 &comp_mode_p);
8806
8807 for (i = 0; i < MAX_REF_FRAMES; ++i)
8808 x->pred_sse[i] = INT_MAX;
8809 for (i = LAST_FRAME; i < MAX_REF_FRAMES; ++i)
8810 x->pred_mv_sad[i] = INT_MAX;
8811
8812 rd_cost->rate = INT_MAX;
8813
8814 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
8815
hui suc93e5cc2015-12-07 18:18:57 -08008816 mbmi->palette_mode_info.palette_size[0] = 0;
8817 mbmi->palette_mode_info.palette_size[1] = 0;
hui sube3559b2015-10-07 09:29:02 -07008818#if CONFIG_EXT_INTRA
8819 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
8820 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
8821#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07008822 mbmi->mode = ZEROMV;
8823 mbmi->uv_mode = DC_PRED;
8824 mbmi->ref_frame[0] = LAST_FRAME;
8825 mbmi->ref_frame[1] = NONE;
8826 mbmi->mv[0].as_int = 0;
8827 x->skip = 1;
8828
8829 if (cm->interp_filter != BILINEAR) {
Debargha Mukherjeebab29122016-02-26 00:18:03 -08008830 best_filter = EIGHTTAP_REGULAR;
Jingning Han3ee6db62015-08-05 19:00:31 -07008831 if (cm->interp_filter == SWITCHABLE &&
Debargha Mukherjee85514c42015-10-30 09:19:36 -07008832#if CONFIG_EXT_INTERP
8833 vp10_is_interp_needed(xd) &&
8834#endif // CONFIG_EXT_INTERP
Jingning Han3ee6db62015-08-05 19:00:31 -07008835 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
8836 int rs;
8837 int best_rs = INT_MAX;
8838 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
8839 mbmi->interp_filter = i;
8840 rs = vp10_get_switchable_rate(cpi, xd);
8841 if (rs < best_rs) {
8842 best_rs = rs;
8843 best_filter = mbmi->interp_filter;
8844 }
8845 }
8846 }
8847 }
8848 // Set the appropriate filter
8849 if (cm->interp_filter == SWITCHABLE) {
8850 mbmi->interp_filter = best_filter;
8851 rate2 += vp10_get_switchable_rate(cpi, xd);
8852 } else {
8853 mbmi->interp_filter = cm->interp_filter;
8854 }
8855
8856 if (cm->reference_mode == REFERENCE_MODE_SELECT)
8857 rate2 += vp10_cost_bit(comp_mode_p, comp_pred);
8858
8859 // Estimate the reference frame signaling cost and add it
8860 // to the rolling cost variable.
8861 rate2 += ref_costs_single[LAST_FRAME];
8862 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
8863
8864 rd_cost->rate = rate2;
8865 rd_cost->dist = distortion2;
8866 rd_cost->rdcost = this_rd;
8867
8868 if (this_rd >= best_rd_so_far) {
8869 rd_cost->rate = INT_MAX;
8870 rd_cost->rdcost = INT64_MAX;
8871 return;
8872 }
8873
8874 assert((cm->interp_filter == SWITCHABLE) ||
8875 (cm->interp_filter == mbmi->interp_filter));
8876
8877 vp10_update_rd_thresh_fact(tile_data->thresh_freq_fact,
8878 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
8879
8880 vp10_zero(best_pred_diff);
8881 vp10_zero(best_filter_diff);
8882
8883 if (!x->select_tx_size)
8884 swap_block_ptr(x, ctx, 1, 0, 0, MAX_MB_PLANE);
8885 store_coding_context(x, ctx, THR_ZEROMV,
8886 best_pred_diff, best_filter_diff, 0);
8887}
8888
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008889void vp10_rd_pick_inter_mode_sub8x8(struct VP10_COMP *cpi,
8890 TileDataEnc *tile_data,
8891 struct macroblock *x,
8892 int mi_row, int mi_col,
8893 struct RD_COST *rd_cost,
8894#if CONFIG_SUPERTX
8895 int *returnrate_nocoef,
8896#endif // CONFIG_SUPERTX
8897 BLOCK_SIZE bsize,
8898 PICK_MODE_CONTEXT *ctx,
8899 int64_t best_rd_so_far) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07008900 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07008901 RD_OPT *const rd_opt = &cpi->rd;
8902 SPEED_FEATURES *const sf = &cpi->sf;
8903 MACROBLOCKD *const xd = &x->e_mbd;
8904 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
8905 const struct segmentation *const seg = &cm->seg;
8906 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
8907 unsigned char segment_id = mbmi->segment_id;
8908 int comp_pred, i;
8909 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
Zoe Liu3ec16012015-11-12 02:12:17 -08008910 struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE];
8911 static const int flag_list[REFS_PER_FRAME + 1] = {
8912 0,
8913 VP9_LAST_FLAG,
8914#if CONFIG_EXT_REFS
8915 VP9_LAST2_FLAG,
8916 VP9_LAST3_FLAG,
8917 VP9_LAST4_FLAG,
8918#endif // CONFIG_EXT_REFS
8919 VP9_GOLD_FLAG,
8920 VP9_ALT_FLAG
8921 };
Jingning Han3ee6db62015-08-05 19:00:31 -07008922 int64_t best_rd = best_rd_so_far;
8923 int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
8924 int64_t best_pred_diff[REFERENCE_MODES];
8925 int64_t best_pred_rd[REFERENCE_MODES];
8926 int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
8927 int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
8928 MB_MODE_INFO best_mbmode;
8929 int ref_index, best_ref_index = 0;
8930 unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
8931 vpx_prob comp_mode_p;
8932 INTERP_FILTER tmp_best_filter = SWITCHABLE;
8933 int rate_uv_intra, rate_uv_tokenonly;
8934 int64_t dist_uv;
8935 int skip_uv;
8936 PREDICTION_MODE mode_uv = DC_PRED;
8937 const int intra_cost_penalty = vp10_get_intra_cost_penalty(
8938 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
Yue Chen1ac85872016-01-07 15:13:52 -08008939#if CONFIG_EXT_INTER
8940 int_mv seg_mvs[4][2][MAX_REF_FRAMES];
8941#else
Jingning Han3ee6db62015-08-05 19:00:31 -07008942 int_mv seg_mvs[4][MAX_REF_FRAMES];
Yue Chen1ac85872016-01-07 15:13:52 -08008943#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07008944 b_mode_info best_bmodes[4];
8945 int best_skip2 = 0;
8946 int ref_frame_skip_mask[2] = { 0 };
8947 int64_t mask_filter = 0;
8948 int64_t filter_cache[SWITCHABLE_FILTER_CONTEXTS];
8949 int internal_active_edge =
8950 vp10_active_edge_sb(cpi, mi_row, mi_col) && vp10_internal_image_edge(cpi);
8951
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008952#if CONFIG_SUPERTX
8953 best_rd_so_far = INT64_MAX;
8954 best_rd = best_rd_so_far;
8955 best_yrd = best_rd_so_far;
8956#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07008957 memset(x->zcoeff_blk[TX_4X4], 0, 4);
8958 vp10_zero(best_mbmode);
8959
hui sube3559b2015-10-07 09:29:02 -07008960#if CONFIG_EXT_INTRA
8961 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
8962 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
8963#endif // CONFIG_EXT_INTRA
Yue Chend1cad9c2016-01-27 14:18:53 -08008964#if CONFIG_OBMC
8965 mbmi->obmc = 0;
8966#endif // CONFIG_OBMC
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08008967#if CONFIG_EXT_INTER
8968 mbmi->use_wedge_interinter = 0;
8969 mbmi->use_wedge_interintra = 0;
8970#endif // CONFIG_EXT_INTER
hui sube3559b2015-10-07 09:29:02 -07008971
Jingning Han3ee6db62015-08-05 19:00:31 -07008972 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
8973 filter_cache[i] = INT64_MAX;
8974
8975 for (i = 0; i < 4; i++) {
8976 int j;
Yue Chen1ac85872016-01-07 15:13:52 -08008977#if CONFIG_EXT_INTER
8978 int k;
8979
8980 for (k = 0; k < 2; k++)
8981 for (j = 0; j < MAX_REF_FRAMES; j++)
8982 seg_mvs[i][k][j].as_int = INVALID_MV;
8983#else
Jingning Han3ee6db62015-08-05 19:00:31 -07008984 for (j = 0; j < MAX_REF_FRAMES; j++)
8985 seg_mvs[i][j].as_int = INVALID_MV;
Yue Chen1ac85872016-01-07 15:13:52 -08008986#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07008987 }
8988
8989 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
8990 &comp_mode_p);
8991
8992 for (i = 0; i < REFERENCE_MODES; ++i)
8993 best_pred_rd[i] = INT64_MAX;
8994 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
8995 best_filter_rd[i] = INT64_MAX;
8996 rate_uv_intra = INT_MAX;
8997
8998 rd_cost->rate = INT_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008999#if CONFIG_SUPERTX
9000 *returnrate_nocoef = INT_MAX;
9001#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07009002
9003 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
Jingning Han387a10e2015-12-09 09:07:39 -08009004 x->mbmi_ext->mode_context[ref_frame] = 0;
Yue Chen968bbc72016-01-19 16:45:45 -08009005#if CONFIG_REF_MV && CONFIG_EXT_INTER
9006 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
9007#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07009008 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
9009 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
9010 frame_mv[NEARESTMV], frame_mv[NEARMV],
9011 yv12_mb);
9012 } else {
9013 ref_frame_skip_mask[0] |= (1 << ref_frame);
9014 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9015 }
9016 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Yue Chen1ac85872016-01-07 15:13:52 -08009017#if CONFIG_EXT_INTER
9018 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
9019#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07009020 frame_mv[ZEROMV][ref_frame].as_int = 0;
9021 }
9022
hui suc93e5cc2015-12-07 18:18:57 -08009023 mbmi->palette_mode_info.palette_size[0] = 0;
9024 mbmi->palette_mode_info.palette_size[1] = 0;
9025
Jingning Han3ee6db62015-08-05 19:00:31 -07009026 for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
9027 int mode_excluded = 0;
9028 int64_t this_rd = INT64_MAX;
9029 int disable_skip = 0;
9030 int compmode_cost = 0;
9031 int rate2 = 0, rate_y = 0, rate_uv = 0;
9032 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
9033 int skippable = 0;
9034 int i;
9035 int this_skip2 = 0;
9036 int64_t total_sse = INT_MAX;
9037 int early_term = 0;
9038
9039 ref_frame = vp10_ref_order[ref_index].ref_frame[0];
9040 second_ref_frame = vp10_ref_order[ref_index].ref_frame[1];
9041
9042 // Look at the reference frame of the best mode so far and set the
9043 // skip mask to look at a subset of the remaining modes.
9044 if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
9045 if (ref_index == 3) {
9046 switch (best_mbmode.ref_frame[0]) {
9047 case INTRA_FRAME:
9048 break;
9049 case LAST_FRAME:
Zoe Liu3ec16012015-11-12 02:12:17 -08009050 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
9051#if CONFIG_EXT_REFS
9052 (1 << LAST2_FRAME) |
9053 (1 << LAST3_FRAME) |
9054 (1 << LAST4_FRAME) |
9055#endif // CONFIG_EXT_REFS
9056 (1 << ALTREF_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07009057 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9058 break;
Zoe Liu3ec16012015-11-12 02:12:17 -08009059#if CONFIG_EXT_REFS
9060 case LAST2_FRAME:
9061 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
9062 (1 << LAST3_FRAME) |
9063 (1 << LAST4_FRAME) |
9064 (1 << GOLDEN_FRAME) |
9065 (1 << ALTREF_FRAME);
9066 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9067 break;
9068 case LAST3_FRAME:
9069 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
9070 (1 << LAST2_FRAME) |
9071 (1 << LAST4_FRAME) |
9072 (1 << GOLDEN_FRAME) |
9073 (1 << ALTREF_FRAME);
9074 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9075 break;
9076 case LAST4_FRAME:
9077 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
9078 (1 << LAST2_FRAME) |
9079 (1 << LAST3_FRAME) |
9080 (1 << GOLDEN_FRAME) |
9081 (1 << ALTREF_FRAME);
9082 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9083 break;
9084#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07009085 case GOLDEN_FRAME:
Zoe Liu3ec16012015-11-12 02:12:17 -08009086 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
9087#if CONFIG_EXT_REFS
9088 (1 << LAST2_FRAME) |
9089 (1 << LAST3_FRAME) |
9090 (1 << LAST4_FRAME) |
9091#endif // CONFIG_EXT_REFS
9092 (1 << ALTREF_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07009093 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9094 break;
9095 case ALTREF_FRAME:
Zoe Liu3ec16012015-11-12 02:12:17 -08009096 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
9097#if CONFIG_EXT_REFS
9098 (1 << LAST2_FRAME) |
9099 (1 << LAST3_FRAME) |
9100 (1 << LAST4_FRAME) |
9101#endif // CONFIG_EXT_REFS
9102 (1 << LAST_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07009103 break;
9104 case NONE:
9105 case MAX_REF_FRAMES:
9106 assert(0 && "Invalid Reference frame");
9107 break;
9108 }
9109 }
9110 }
9111
9112 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
James Zern5e16d392015-08-17 18:19:22 -07009113 (ref_frame_skip_mask[1] & (1 << VPXMAX(0, second_ref_frame))))
Jingning Han3ee6db62015-08-05 19:00:31 -07009114 continue;
9115
9116 // Test best rd so far against threshold for trying this mode.
9117 if (!internal_active_edge &&
9118 rd_less_than_thresh(best_rd,
9119 rd_opt->threshes[segment_id][bsize][ref_index],
9120 tile_data->thresh_freq_fact[bsize][ref_index]))
9121 continue;
9122
9123 comp_pred = second_ref_frame > INTRA_FRAME;
9124 if (comp_pred) {
9125 if (!cpi->allow_comp_inter_inter)
9126 continue;
9127 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
9128 continue;
9129 // Do not allow compound prediction if the segment level reference frame
9130 // feature is in use as in this case there can only be one reference.
9131 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
9132 continue;
9133
9134 if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
9135 best_mbmode.ref_frame[0] == INTRA_FRAME)
9136 continue;
9137 }
9138
9139 // TODO(jingning, jkoleszar): scaling reference frame not supported for
9140 // sub8x8 blocks.
9141 if (ref_frame > INTRA_FRAME &&
9142 vp10_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
9143 continue;
9144
9145 if (second_ref_frame > INTRA_FRAME &&
9146 vp10_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
9147 continue;
9148
9149 if (comp_pred)
9150 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
9151 else if (ref_frame != INTRA_FRAME)
9152 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
9153
9154 // If the segment reference frame feature is enabled....
9155 // then do nothing if the current ref frame is not allowed..
9156 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
9157 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
9158 continue;
9159 // Disable this drop out case if the ref frame
9160 // segment level feature is enabled for this segment. This is to
9161 // prevent the possibility that we end up unable to pick any mode.
9162 } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
9163 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
9164 // unless ARNR filtering is enabled in which case we want
9165 // an unfiltered alternative. We allow near/nearest as well
9166 // because they may result in zero-zero MVs but be cheaper.
9167 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
9168 continue;
9169 }
9170
9171 mbmi->tx_size = TX_4X4;
9172 mbmi->uv_mode = DC_PRED;
9173 mbmi->ref_frame[0] = ref_frame;
9174 mbmi->ref_frame[1] = second_ref_frame;
9175 // Evaluate all sub-pel filters irrespective of whether we can use
9176 // them for this frame.
Debargha Mukherjeebab29122016-02-26 00:18:03 -08009177 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
Jingning Han3ee6db62015-08-05 19:00:31 -07009178 : cm->interp_filter;
9179 x->skip = 0;
9180 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
9181
9182 // Select prediction reference frames.
9183 for (i = 0; i < MAX_MB_PLANE; i++) {
9184 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
9185 if (comp_pred)
9186 xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
9187 }
9188
Jingning Han704985e2015-10-08 12:05:03 -07009189#if CONFIG_VAR_TX
Jingning Han0f34e352015-11-15 20:52:51 -08009190 mbmi->inter_tx_size[0] = mbmi->tx_size;
Jingning Han704985e2015-10-08 12:05:03 -07009191#endif
9192
Jingning Han3ee6db62015-08-05 19:00:31 -07009193 if (ref_frame == INTRA_FRAME) {
9194 int rate;
9195 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y,
9196 &distortion_y, best_rd) >= best_rd)
9197 continue;
9198 rate2 += rate;
9199 rate2 += intra_cost_penalty;
9200 distortion2 += distortion_y;
9201
9202 if (rate_uv_intra == INT_MAX) {
9203 choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4,
9204 &rate_uv_intra,
9205 &rate_uv_tokenonly,
9206 &dist_uv, &skip_uv,
9207 &mode_uv);
9208 }
9209 rate2 += rate_uv_intra;
9210 rate_uv = rate_uv_tokenonly;
9211 distortion2 += dist_uv;
9212 distortion_uv = dist_uv;
9213 mbmi->uv_mode = mode_uv;
9214 } else {
9215 int rate;
9216 int64_t distortion;
9217 int64_t this_rd_thresh;
9218 int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
9219 int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
9220 int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
9221 int tmp_best_skippable = 0;
9222 int switchable_filter_index;
9223 int_mv *second_ref = comp_pred ?
9224 &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL;
9225 b_mode_info tmp_best_bmodes[16];
9226 MB_MODE_INFO tmp_best_mbmode;
9227 BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
9228 int pred_exists = 0;
9229 int uv_skippable;
Yue Chen1ac85872016-01-07 15:13:52 -08009230#if CONFIG_EXT_INTER
9231 int_mv compound_seg_newmvs[4][2];
9232 int i;
9233
9234 for (i = 0; i < 4; i++) {
9235 compound_seg_newmvs[i][0].as_int = INVALID_MV;
9236 compound_seg_newmvs[i][1].as_int = INVALID_MV;
9237 }
9238#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07009239
9240 this_rd_thresh = (ref_frame == LAST_FRAME) ?
9241 rd_opt->threshes[segment_id][bsize][THR_LAST] :
9242 rd_opt->threshes[segment_id][bsize][THR_ALTR];
Zoe Liu3ec16012015-11-12 02:12:17 -08009243#if CONFIG_EXT_REFS
9244 this_rd_thresh = (ref_frame == LAST2_FRAME) ?
9245 rd_opt->threshes[segment_id][bsize][THR_LAST2] : this_rd_thresh;
9246 this_rd_thresh = (ref_frame == LAST3_FRAME) ?
9247 rd_opt->threshes[segment_id][bsize][THR_LAST3] : this_rd_thresh;
9248 this_rd_thresh = (ref_frame == LAST4_FRAME) ?
9249 rd_opt->threshes[segment_id][bsize][THR_LAST4] : this_rd_thresh;
9250#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07009251 this_rd_thresh = (ref_frame == GOLDEN_FRAME) ?
Zoe Liu3ec16012015-11-12 02:12:17 -08009252 rd_opt->threshes[segment_id][bsize][THR_GOLD] : this_rd_thresh;
Jingning Han3ee6db62015-08-05 19:00:31 -07009253 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
9254 filter_cache[i] = INT64_MAX;
9255
Debargha Mukherjeed46c1f22016-02-08 15:59:17 -08009256 // TODO(any): Add search of the tx_type to improve rd performance at the
9257 // expense of speed.
9258 mbmi->tx_type = DCT_DCT;
9259
Jingning Han3ee6db62015-08-05 19:00:31 -07009260 if (cm->interp_filter != BILINEAR) {
Debargha Mukherjeebab29122016-02-26 00:18:03 -08009261 tmp_best_filter = EIGHTTAP_REGULAR;
Jingning Han3ee6db62015-08-05 19:00:31 -07009262 if (x->source_variance < sf->disable_filter_search_var_thresh) {
Debargha Mukherjeebab29122016-02-26 00:18:03 -08009263 tmp_best_filter = EIGHTTAP_REGULAR;
Jingning Han3ee6db62015-08-05 19:00:31 -07009264 } else if (sf->adaptive_pred_interp_filter == 1 &&
9265 ctx->pred_interp_filter < SWITCHABLE) {
9266 tmp_best_filter = ctx->pred_interp_filter;
9267 } else if (sf->adaptive_pred_interp_filter == 2) {
9268 tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE ?
9269 ctx->pred_interp_filter : 0;
9270 } else {
9271 for (switchable_filter_index = 0;
9272 switchable_filter_index < SWITCHABLE_FILTERS;
9273 ++switchable_filter_index) {
9274 int newbest, rs;
9275 int64_t rs_rd;
9276 MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
9277 mbmi->interp_filter = switchable_filter_index;
9278 tmp_rd = rd_pick_best_sub8x8_mode(cpi, x,
9279 &mbmi_ext->ref_mvs[ref_frame][0],
9280 second_ref, best_yrd, &rate,
9281 &rate_y, &distortion,
9282 &skippable, &total_sse,
9283 (int) this_rd_thresh, seg_mvs,
Yue Chen1ac85872016-01-07 15:13:52 -08009284#if CONFIG_EXT_INTER
9285 compound_seg_newmvs,
9286#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07009287 bsi, switchable_filter_index,
9288 mi_row, mi_col);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07009289#if CONFIG_EXT_INTERP
9290 if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Debargha Mukherjeebab29122016-02-26 00:18:03 -08009291 mbmi->interp_filter != EIGHTTAP_REGULAR) // invalid config
Debargha Mukherjee85514c42015-10-30 09:19:36 -07009292 continue;
9293#endif // CONFIG_EXT_INTERP
Jingning Han3ee6db62015-08-05 19:00:31 -07009294 if (tmp_rd == INT64_MAX)
9295 continue;
9296 rs = vp10_get_switchable_rate(cpi, xd);
9297 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
9298 filter_cache[switchable_filter_index] = tmp_rd;
9299 filter_cache[SWITCHABLE_FILTERS] =
James Zern5e16d392015-08-17 18:19:22 -07009300 VPXMIN(filter_cache[SWITCHABLE_FILTERS], tmp_rd + rs_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07009301 if (cm->interp_filter == SWITCHABLE)
9302 tmp_rd += rs_rd;
9303
James Zern5e16d392015-08-17 18:19:22 -07009304 mask_filter = VPXMAX(mask_filter, tmp_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07009305
9306 newbest = (tmp_rd < tmp_best_rd);
9307 if (newbest) {
9308 tmp_best_filter = mbmi->interp_filter;
9309 tmp_best_rd = tmp_rd;
9310 }
9311 if ((newbest && cm->interp_filter == SWITCHABLE) ||
9312 (mbmi->interp_filter == cm->interp_filter &&
9313 cm->interp_filter != SWITCHABLE)) {
9314 tmp_best_rdu = tmp_rd;
9315 tmp_best_rate = rate;
9316 tmp_best_ratey = rate_y;
9317 tmp_best_distortion = distortion;
9318 tmp_best_sse = total_sse;
9319 tmp_best_skippable = skippable;
9320 tmp_best_mbmode = *mbmi;
9321 for (i = 0; i < 4; i++) {
9322 tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
9323 x->zcoeff_blk[TX_4X4][i] = !x->plane[0].eobs[i];
9324 }
9325 pred_exists = 1;
9326 if (switchable_filter_index == 0 &&
9327 sf->use_rd_breakout &&
9328 best_rd < INT64_MAX) {
9329 if (tmp_best_rdu / 2 > best_rd) {
9330 // skip searching the other filters if the first is
9331 // already substantially larger than the best so far
9332 tmp_best_filter = mbmi->interp_filter;
9333 tmp_best_rdu = INT64_MAX;
9334 break;
9335 }
9336 }
9337 }
9338 } // switchable_filter_index loop
9339 }
9340 }
9341
9342 if (tmp_best_rdu == INT64_MAX && pred_exists)
9343 continue;
9344
9345 mbmi->interp_filter = (cm->interp_filter == SWITCHABLE ?
9346 tmp_best_filter : cm->interp_filter);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07009347
Jingning Han3ee6db62015-08-05 19:00:31 -07009348 if (!pred_exists) {
9349 // Handles the special case when a filter that is not in the
Debargha Mukherjee85514c42015-10-30 09:19:36 -07009350 // switchable list (bilinear) is indicated at the frame level
Jingning Han3ee6db62015-08-05 19:00:31 -07009351 tmp_rd = rd_pick_best_sub8x8_mode(cpi, x,
9352 &x->mbmi_ext->ref_mvs[ref_frame][0],
9353 second_ref, best_yrd, &rate, &rate_y,
9354 &distortion, &skippable, &total_sse,
Yue Chen1ac85872016-01-07 15:13:52 -08009355 (int) this_rd_thresh, seg_mvs,
9356#if CONFIG_EXT_INTER
9357 compound_seg_newmvs,
9358#endif // CONFIG_EXT_INTER
9359 bsi, 0,
Jingning Han3ee6db62015-08-05 19:00:31 -07009360 mi_row, mi_col);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07009361#if CONFIG_EXT_INTERP
9362 if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Debargha Mukherjeebab29122016-02-26 00:18:03 -08009363 mbmi->interp_filter != EIGHTTAP_REGULAR) {
9364 mbmi->interp_filter = EIGHTTAP_REGULAR;
Debargha Mukherjee85514c42015-10-30 09:19:36 -07009365 }
9366#endif // CONFIG_EXT_INTERP
Jingning Han3ee6db62015-08-05 19:00:31 -07009367 if (tmp_rd == INT64_MAX)
9368 continue;
9369 } else {
9370 total_sse = tmp_best_sse;
9371 rate = tmp_best_rate;
9372 rate_y = tmp_best_ratey;
9373 distortion = tmp_best_distortion;
9374 skippable = tmp_best_skippable;
9375 *mbmi = tmp_best_mbmode;
9376 for (i = 0; i < 4; i++)
9377 xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
9378 }
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08009379 // Add in the cost of the transform type
9380 if (!xd->lossless[mbmi->segment_id]) {
9381 int rate_tx_type = 0;
9382#if CONFIG_EXT_TX
9383 if (get_ext_tx_types(mbmi->tx_size, bsize, 1) > 1) {
9384 const int eset = get_ext_tx_set(mbmi->tx_size, bsize, 1);
9385 rate_tx_type =
9386 cpi->inter_tx_type_costs[eset][mbmi->tx_size][mbmi->tx_type];
9387 }
9388#else
9389 if (mbmi->tx_size < TX_32X32) {
9390 rate_tx_type = cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
9391 }
9392#endif
9393 rate += rate_tx_type;
9394 rate_y += rate_tx_type;
9395 }
Jingning Han3ee6db62015-08-05 19:00:31 -07009396
9397 rate2 += rate;
9398 distortion2 += distortion;
9399
9400 if (cm->interp_filter == SWITCHABLE)
9401 rate2 += vp10_get_switchable_rate(cpi, xd);
9402
9403 if (!mode_excluded)
9404 mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
9405 : cm->reference_mode == COMPOUND_REFERENCE;
9406
9407 compmode_cost = vp10_cost_bit(comp_mode_p, comp_pred);
9408
9409 tmp_best_rdu = best_rd -
James Zern5e16d392015-08-17 18:19:22 -07009410 VPXMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
9411 RDCOST(x->rdmult, x->rddiv, 0, total_sse));
Jingning Han3ee6db62015-08-05 19:00:31 -07009412
9413 if (tmp_best_rdu > 0) {
9414 // If even the 'Y' rd value of split is higher than best so far
9415 // then dont bother looking at UV
9416 vp10_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col,
9417 BLOCK_8X8);
9418 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
Jingning Hana8dad552015-10-08 16:46:10 -07009419#if CONFIG_VAR_TX
9420 if (!inter_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
9421 &uv_sse, BLOCK_8X8, tmp_best_rdu))
9422 continue;
9423#else
Jingning Han3ee6db62015-08-05 19:00:31 -07009424 if (!super_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
9425 &uv_sse, BLOCK_8X8, tmp_best_rdu))
9426 continue;
Jingning Hana8dad552015-10-08 16:46:10 -07009427#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07009428 rate2 += rate_uv;
9429 distortion2 += distortion_uv;
9430 skippable = skippable && uv_skippable;
9431 total_sse += uv_sse;
hui su30d2d972016-03-17 11:20:59 -07009432 } else {
9433 continue;
Jingning Han3ee6db62015-08-05 19:00:31 -07009434 }
9435 }
9436
9437 if (cm->reference_mode == REFERENCE_MODE_SELECT)
9438 rate2 += compmode_cost;
9439
9440 // Estimate the reference frame signaling cost and add it
9441 // to the rolling cost variable.
9442 if (second_ref_frame > INTRA_FRAME) {
9443 rate2 += ref_costs_comp[ref_frame];
9444 } else {
9445 rate2 += ref_costs_single[ref_frame];
9446 }
9447
9448 if (!disable_skip) {
9449 // Skip is never coded at the segment level for sub8x8 blocks and instead
9450 // always coded in the bitstream at the mode info level.
9451
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04009452 if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Jingning Han3ee6db62015-08-05 19:00:31 -07009453 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
9454 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
9455 // Add in the cost of the no skip flag.
9456 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
9457 } else {
9458 // FIXME(rbultje) make this work for splitmv also
9459 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
9460 distortion2 = total_sse;
9461 assert(total_sse >= 0);
9462 rate2 -= (rate_y + rate_uv);
9463 rate_y = 0;
9464 rate_uv = 0;
9465 this_skip2 = 1;
9466 }
9467 } else {
9468 // Add in the cost of the no skip flag.
9469 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
9470 }
9471
9472 // Calculate the final RD estimate for this mode.
9473 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
9474 }
9475
9476 if (!disable_skip && ref_frame == INTRA_FRAME) {
9477 for (i = 0; i < REFERENCE_MODES; ++i)
James Zern5e16d392015-08-17 18:19:22 -07009478 best_pred_rd[i] = VPXMIN(best_pred_rd[i], this_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07009479 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
James Zern5e16d392015-08-17 18:19:22 -07009480 best_filter_rd[i] = VPXMIN(best_filter_rd[i], this_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07009481 }
9482
9483 // Did this mode help.. i.e. is it the new best mode
9484 if (this_rd < best_rd || x->skip) {
9485 if (!mode_excluded) {
9486 int max_plane = MAX_MB_PLANE;
9487 // Note index of best mode so far
9488 best_ref_index = ref_index;
9489
9490 if (ref_frame == INTRA_FRAME) {
9491 /* required for left and above block mv */
9492 mbmi->mv[0].as_int = 0;
9493 max_plane = 1;
9494 }
9495
9496 rd_cost->rate = rate2;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08009497#if CONFIG_SUPERTX
9498 *returnrate_nocoef = rate2 - rate_y - rate_uv;
9499 if (!disable_skip)
9500 *returnrate_nocoef -= vp10_cost_bit(vp10_get_skip_prob(cm, xd),
9501 this_skip2);
9502 *returnrate_nocoef -= vp10_cost_bit(vp10_get_intra_inter_prob(cm, xd),
9503 mbmi->ref_frame[0] != INTRA_FRAME);
9504 assert(*returnrate_nocoef > 0);
9505#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07009506 rd_cost->dist = distortion2;
9507 rd_cost->rdcost = this_rd;
9508 best_rd = this_rd;
9509 best_yrd = best_rd -
9510 RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
9511 best_mbmode = *mbmi;
9512 best_skip2 = this_skip2;
9513 if (!x->select_tx_size)
9514 swap_block_ptr(x, ctx, 1, 0, 0, max_plane);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07009515
9516#if CONFIG_VAR_TX
9517 for (i = 0; i < MAX_MB_PLANE; ++i)
9518 memset(ctx->blk_skip[i], 0, sizeof(uint8_t) * ctx->num_4x4_blk);
9519#else
Jingning Han3ee6db62015-08-05 19:00:31 -07009520 memcpy(ctx->zcoeff_blk, x->zcoeff_blk[TX_4X4],
hui su088b05f2015-08-12 10:41:51 -07009521 sizeof(ctx->zcoeff_blk[0]) * ctx->num_4x4_blk);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07009522#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07009523
9524 for (i = 0; i < 4; i++)
9525 best_bmodes[i] = xd->mi[0]->bmi[i];
9526
9527 // TODO(debargha): enhance this test with a better distortion prediction
9528 // based on qp, activity mask and history
9529 if ((sf->mode_search_skip_flags & FLAG_EARLY_TERMINATE) &&
9530 (ref_index > MIN_EARLY_TERM_INDEX)) {
9531 int qstep = xd->plane[0].dequant[1];
9532 // TODO(debargha): Enhance this by specializing for each mode_index
9533 int scale = 4;
9534#if CONFIG_VP9_HIGHBITDEPTH
9535 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
9536 qstep >>= (xd->bd - 8);
9537 }
9538#endif // CONFIG_VP9_HIGHBITDEPTH
9539 if (x->source_variance < UINT_MAX) {
9540 const int var_adjust = (x->source_variance < 16);
9541 scale -= var_adjust;
9542 }
9543 if (ref_frame > INTRA_FRAME &&
9544 distortion2 * scale < qstep * qstep) {
9545 early_term = 1;
9546 }
9547 }
9548 }
9549 }
9550
9551 /* keep record of best compound/single-only prediction */
9552 if (!disable_skip && ref_frame != INTRA_FRAME) {
9553 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
9554
9555 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
9556 single_rate = rate2 - compmode_cost;
9557 hybrid_rate = rate2;
9558 } else {
9559 single_rate = rate2;
9560 hybrid_rate = rate2 + compmode_cost;
9561 }
9562
9563 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
9564 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
9565
9566 if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE])
9567 best_pred_rd[SINGLE_REFERENCE] = single_rd;
9568 else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE])
9569 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
9570
9571 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
9572 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
9573 }
9574
9575 /* keep record of best filter type */
9576 if (!mode_excluded && !disable_skip && ref_frame != INTRA_FRAME &&
9577 cm->interp_filter != BILINEAR) {
9578 int64_t ref = filter_cache[cm->interp_filter == SWITCHABLE ?
9579 SWITCHABLE_FILTERS : cm->interp_filter];
9580 int64_t adj_rd;
9581 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
9582 if (ref == INT64_MAX)
9583 adj_rd = 0;
9584 else if (filter_cache[i] == INT64_MAX)
9585 // when early termination is triggered, the encoder does not have
9586 // access to the rate-distortion cost. it only knows that the cost
9587 // should be above the maximum valid value. hence it takes the known
9588 // maximum plus an arbitrary constant as the rate-distortion cost.
9589 adj_rd = mask_filter - ref + 10;
9590 else
9591 adj_rd = filter_cache[i] - ref;
9592
9593 adj_rd += this_rd;
James Zern5e16d392015-08-17 18:19:22 -07009594 best_filter_rd[i] = VPXMIN(best_filter_rd[i], adj_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07009595 }
9596 }
9597
9598 if (early_term)
9599 break;
9600
9601 if (x->skip && !comp_pred)
9602 break;
9603 }
9604
9605 if (best_rd >= best_rd_so_far) {
9606 rd_cost->rate = INT_MAX;
9607 rd_cost->rdcost = INT64_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08009608#if CONFIG_SUPERTX
9609 *returnrate_nocoef = INT_MAX;
9610#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07009611 return;
9612 }
9613
9614 // If we used an estimate for the uv intra rd in the loop above...
9615 if (sf->use_uv_intra_rd_estimate) {
9616 // Do Intra UV best rd mode selection if best mode choice above was intra.
9617 if (best_mbmode.ref_frame[0] == INTRA_FRAME) {
9618 *mbmi = best_mbmode;
9619 rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra,
9620 &rate_uv_tokenonly,
9621 &dist_uv,
9622 &skip_uv,
9623 BLOCK_8X8, TX_4X4);
9624 }
9625 }
9626
9627 if (best_rd == INT64_MAX) {
9628 rd_cost->rate = INT_MAX;
9629 rd_cost->dist = INT64_MAX;
9630 rd_cost->rdcost = INT64_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08009631#if CONFIG_SUPERTX
9632 *returnrate_nocoef = INT_MAX;
9633#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07009634 return;
9635 }
9636
9637 assert((cm->interp_filter == SWITCHABLE) ||
9638 (cm->interp_filter == best_mbmode.interp_filter) ||
9639 !is_inter_block(&best_mbmode));
9640
9641 vp10_update_rd_thresh_fact(tile_data->thresh_freq_fact,
9642 sf->adaptive_rd_thresh, bsize, best_ref_index);
9643
9644 // macroblock modes
9645 *mbmi = best_mbmode;
9646 x->skip |= best_skip2;
9647 if (!is_inter_block(&best_mbmode)) {
9648 for (i = 0; i < 4; i++)
9649 xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
9650 } else {
9651 for (i = 0; i < 4; ++i)
9652 memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
9653
9654 mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
9655 mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
Jingning Handf59bb82016-02-18 11:57:44 -08009656#if CONFIG_REF_MV
9657 mbmi->pred_mv[0].as_int = xd->mi[0]->bmi[3].pred_mv[0].as_int;
9658 mbmi->pred_mv[1].as_int = xd->mi[0]->bmi[3].pred_mv[1].as_int;
9659#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07009660 }
9661
9662 for (i = 0; i < REFERENCE_MODES; ++i) {
9663 if (best_pred_rd[i] == INT64_MAX)
9664 best_pred_diff[i] = INT_MIN;
9665 else
9666 best_pred_diff[i] = best_rd - best_pred_rd[i];
9667 }
9668
9669 if (!x->skip) {
9670 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
9671 if (best_filter_rd[i] == INT64_MAX)
9672 best_filter_diff[i] = 0;
9673 else
9674 best_filter_diff[i] = best_rd - best_filter_rd[i];
9675 }
9676 if (cm->interp_filter == SWITCHABLE)
9677 assert(best_filter_diff[SWITCHABLE_FILTERS] == 0);
9678 } else {
9679 vp10_zero(best_filter_diff);
9680 }
9681
9682 store_coding_context(x, ctx, best_ref_index,
9683 best_pred_diff, best_filter_diff, 0);
9684}
Yue Chend1cad9c2016-01-27 14:18:53 -08009685
9686#if CONFIG_OBMC
9687void vp10_build_prediction_by_above_preds(VP10_COMP *cpi,
9688 MACROBLOCKD *xd,
9689 int mi_row, int mi_col,
9690 uint8_t *tmp_buf[MAX_MB_PLANE],
9691 int tmp_stride[MAX_MB_PLANE]) {
9692 VP10_COMMON *const cm = &cpi->common;
9693 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
9694 int i, j, mi_step, ref;
9695
9696 if (mi_row == 0)
9697 return;
9698
9699 for (i = 0; i < VPXMIN(xd->n8_w, cm->mi_cols - mi_col); i += mi_step) {
9700 int mi_row_offset = -1;
9701 int mi_col_offset = i;
9702 int mi_x, mi_y, bw, bh;
9703 MODE_INFO *above_mi = xd->mi[mi_col_offset +
9704 mi_row_offset * xd->mi_stride];
9705 MB_MODE_INFO *above_mbmi = &above_mi->mbmi;
9706
9707 mi_step = VPXMIN(xd->n8_w,
9708 num_8x8_blocks_wide_lookup[above_mbmi->sb_type]);
9709
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009710 if (!is_neighbor_overlappable(above_mbmi))
Yue Chend1cad9c2016-01-27 14:18:53 -08009711 continue;
9712
9713 for (j = 0; j < MAX_MB_PLANE; ++j) {
9714 struct macroblockd_plane *const pd = &xd->plane[j];
9715 setup_pred_plane(&pd->dst,
9716 tmp_buf[j], tmp_stride[j],
9717 0, i, NULL,
9718 pd->subsampling_x, pd->subsampling_y);
9719 }
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009720 /*
Yue Chend1cad9c2016-01-27 14:18:53 -08009721 set_ref_ptrs(cm, xd, above_mbmi->ref_frame[0], above_mbmi->ref_frame[1]);
9722 for (ref = 0; ref < 1 + has_second_ref(above_mbmi); ++ref) {
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009723 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(
9724 cpi, above_mbmi->ref_frame[ref]);
Yue Chend1cad9c2016-01-27 14:18:53 -08009725 assert(cfg != NULL);
9726 vp10_setup_pre_planes(xd, ref, cfg, mi_row, mi_col + i,
9727 &xd->block_refs[ref]->sf);
9728 }
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009729 */
9730 for (ref = 0; ref < 1 + has_second_ref(above_mbmi); ++ref) {
9731 MV_REFERENCE_FRAME frame = above_mbmi->ref_frame[ref];
9732 RefBuffer *ref_buf = &cm->frame_refs[frame - LAST_FRAME];
9733
9734 xd->block_refs[ref] = ref_buf;
9735 if ((!vp10_is_valid_scale(&ref_buf->sf)))
9736 vpx_internal_error(xd->error_info, VPX_CODEC_UNSUP_BITSTREAM,
9737 "Reference frame has invalid dimensions");
9738 vp10_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col + i,
9739 &ref_buf->sf);
9740 }
Yue Chend1cad9c2016-01-27 14:18:53 -08009741
9742 xd->mb_to_left_edge = -(((mi_col + i) * MI_SIZE) * 8);
9743 mi_x = (mi_col + i) << MI_SIZE_LOG2;
9744 mi_y = mi_row << MI_SIZE_LOG2;
9745
9746 for (j = 0; j < MAX_MB_PLANE; ++j) {
9747 const struct macroblockd_plane *pd = &xd->plane[j];
9748 bw = (mi_step * 8) >> pd->subsampling_x;
9749 bh = VPXMAX((num_4x4_blocks_high_lookup[bsize] * 2) >> pd->subsampling_y,
9750 4);
9751
9752 if (above_mbmi->sb_type < BLOCK_8X8) {
9753 const PARTITION_TYPE bp = BLOCK_8X8 - above_mbmi->sb_type;
9754 const int have_vsplit = bp != PARTITION_HORZ;
9755 const int have_hsplit = bp != PARTITION_VERT;
9756 const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
9757 const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);
9758 const int pw = 8 >> (have_vsplit | pd->subsampling_x);
9759 int x, y;
9760
9761 for (y = 0; y < num_4x4_h; ++y)
9762 for (x = 0; x < num_4x4_w; ++x) {
9763 if ((bp == PARTITION_HORZ || bp == PARTITION_SPLIT)
9764 && y == 0 && !pd->subsampling_y)
9765 continue;
9766
9767 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
9768 y * 2 + x, bw, bh,
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009769 4 * x, 0, pw, bh,
9770#if CONFIG_SUPERTX && CONFIG_EXT_INTER
9771 0, 0,
9772#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
9773 mi_x, mi_y);
Yue Chend1cad9c2016-01-27 14:18:53 -08009774 }
9775 } else {
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009776 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
9777 0, bw, bh, 0, 0, bw, bh,
9778#if CONFIG_SUPERTX && CONFIG_EXT_INTER
9779 0, 0,
9780#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
9781 mi_x, mi_y);
Yue Chend1cad9c2016-01-27 14:18:53 -08009782 }
9783 }
9784 }
9785 xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8);
9786}
9787
9788void vp10_build_prediction_by_left_preds(VP10_COMP *cpi,
9789 MACROBLOCKD *xd,
9790 int mi_row, int mi_col,
9791 uint8_t *tmp_buf[MAX_MB_PLANE],
9792 int tmp_stride[MAX_MB_PLANE]) {
9793 VP10_COMMON *const cm = &cpi->common;
9794 const TileInfo *const tile = &xd->tile;
9795 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
9796 int i, j, mi_step, ref;
9797
9798 if (mi_col == 0 || (mi_col - 1 < tile->mi_col_start) ||
9799 (mi_col - 1) >= tile->mi_col_end)
9800 return;
9801
9802 for (i = 0; i < VPXMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) {
9803 int mi_row_offset = i;
9804 int mi_col_offset = -1;
9805 int mi_x, mi_y, bw, bh;
9806 MODE_INFO *left_mi = xd->mi[mi_col_offset +
9807 mi_row_offset * xd->mi_stride];
9808 MB_MODE_INFO *left_mbmi = &left_mi->mbmi;
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009809 const int is_compound = has_second_ref(left_mbmi);
Yue Chend1cad9c2016-01-27 14:18:53 -08009810
9811 mi_step = VPXMIN(xd->n8_h,
9812 num_8x8_blocks_high_lookup[left_mbmi->sb_type]);
9813
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009814 if (!is_neighbor_overlappable(left_mbmi))
Yue Chend1cad9c2016-01-27 14:18:53 -08009815 continue;
9816
9817 for (j = 0; j < MAX_MB_PLANE; ++j) {
9818 struct macroblockd_plane *const pd = &xd->plane[j];
9819 setup_pred_plane(&pd->dst,
9820 tmp_buf[j], tmp_stride[j],
9821 i, 0, NULL,
9822 pd->subsampling_x, pd->subsampling_y);
9823 }
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009824 /*
Yue Chend1cad9c2016-01-27 14:18:53 -08009825 set_ref_ptrs(cm, xd, left_mbmi->ref_frame[0], left_mbmi->ref_frame[1]);
9826 for (ref = 0; ref < 1 + has_second_ref(left_mbmi); ++ref) {
9827 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi,
9828 left_mbmi->ref_frame[ref]);
9829 assert(cfg != NULL);
9830 vp10_setup_pre_planes(xd, ref, cfg, mi_row + i, mi_col,
9831 &xd->block_refs[ref]->sf);
9832 }
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009833 */
9834 for (ref = 0; ref < 1 + is_compound; ++ref) {
9835 MV_REFERENCE_FRAME frame = left_mbmi->ref_frame[ref];
9836 RefBuffer *ref_buf = &cm->frame_refs[frame - LAST_FRAME];
9837
9838 xd->block_refs[ref] = ref_buf;
9839 if ((!vp10_is_valid_scale(&ref_buf->sf)))
9840 vpx_internal_error(xd->error_info, VPX_CODEC_UNSUP_BITSTREAM,
9841 "Reference frame has invalid dimensions");
9842 vp10_setup_pre_planes(xd, ref, ref_buf->buf, mi_row + i, mi_col,
9843 &ref_buf->sf);
9844 }
Yue Chend1cad9c2016-01-27 14:18:53 -08009845
9846 xd->mb_to_top_edge = -(((mi_row + i) * MI_SIZE) * 8);
9847 mi_x = mi_col << MI_SIZE_LOG2;
9848 mi_y = (mi_row + i) << MI_SIZE_LOG2;
9849
9850 for (j = 0; j < MAX_MB_PLANE; ++j) {
9851 const struct macroblockd_plane *pd = &xd->plane[j];
9852 bw = VPXMAX((num_4x4_blocks_wide_lookup[bsize] * 2) >> pd->subsampling_x,
9853 4);
9854 bh = (mi_step << MI_SIZE_LOG2) >> pd->subsampling_y;
9855
9856 if (left_mbmi->sb_type < BLOCK_8X8) {
9857 const PARTITION_TYPE bp = BLOCK_8X8 - left_mbmi->sb_type;
9858 const int have_vsplit = bp != PARTITION_HORZ;
9859 const int have_hsplit = bp != PARTITION_VERT;
9860 const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
9861 const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);
9862 const int ph = 8 >> (have_hsplit | pd->subsampling_y);
9863 int x, y;
9864
9865 for (y = 0; y < num_4x4_h; ++y)
9866 for (x = 0; x < num_4x4_w; ++x) {
9867 if ((bp == PARTITION_VERT || bp == PARTITION_SPLIT)
9868 && x == 0 && !pd->subsampling_x)
9869 continue;
9870
9871 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
9872 y * 2 + x, bw, bh,
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009873 0, 4 * y, bw, ph,
9874#if CONFIG_SUPERTX && CONFIG_EXT_INTER
9875 0, 0,
9876#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
9877 mi_x, mi_y);
Yue Chend1cad9c2016-01-27 14:18:53 -08009878 }
9879 } else {
9880 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0,
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009881 bw, bh, 0, 0, bw, bh,
9882#if CONFIG_SUPERTX && CONFIG_EXT_INTER
9883 0, 0,
9884#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
9885 mi_x, mi_y);
Yue Chend1cad9c2016-01-27 14:18:53 -08009886 }
9887 }
9888 }
9889 xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8);
9890}
9891#endif // CONFIG_OBMC