blob: 2b7d8f5a8d41bf584b201e9b0a10d104c7dbbc66 [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;
3499 }
3500
3501 if (!is_cost_valid) {
3502 // reset cost value
3503 *rate = INT_MAX;
3504 *distortion = INT64_MAX;
3505 *sse = INT64_MAX;
3506 *skippable = 0;
3507 }
3508
3509 return is_cost_valid;
3510}
3511
hui su78b0bd02016-02-23 15:22:25 -08003512static void rd_pick_palette_intra_sbuv(VP10_COMP *cpi, MACROBLOCK *x,
3513 PICK_MODE_CONTEXT *ctx, int dc_mode_cost,
3514 PALETTE_MODE_INFO *palette_mode_info,
3515 uint8_t *best_palette_color_map,
3516 PREDICTION_MODE *mode_selected,
3517 int64_t *best_rd, int *rate,
3518 int *rate_tokenonly,
3519 int64_t *distortion, int *skippable) {
3520 MACROBLOCKD *const xd = &x->e_mbd;
3521 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3522 const BLOCK_SIZE bsize = mbmi->sb_type;
3523 const int rows = (4 * num_4x4_blocks_high_lookup[bsize]) >>
3524 (xd->plane[1].subsampling_y);
3525 const int cols = (4 * num_4x4_blocks_wide_lookup[bsize]) >>
3526 (xd->plane[1].subsampling_x);
3527 int this_rate, this_rate_tokenonly, s;
3528 int64_t this_distortion, this_rd;
3529 int colors_u, colors_v, colors;
3530 const int src_stride = x->plane[1].src.stride;
3531 const uint8_t *const src_u = x->plane[1].src.buf;
3532 const uint8_t *const src_v = x->plane[2].src.buf;
3533
3534#if CONFIG_EXT_INTRA
3535 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
3536#endif // CONFIG_EXT_INTRA
3537
3538#if CONFIG_VP9_HIGHBITDEPTH
3539 if (cpi->common.use_highbitdepth) {
3540 colors_u = vp10_count_colors_highbd(src_u, src_stride, rows, cols,
3541 cpi->common.bit_depth);
3542 colors_v = vp10_count_colors_highbd(src_v, src_stride, rows, cols,
3543 cpi->common.bit_depth);
3544 } else {
3545#endif // CONFIG_VP9_HIGHBITDEPTH
3546 colors_u = vp10_count_colors(src_u, src_stride, rows, cols);
3547 colors_v = vp10_count_colors(src_v, src_stride, rows, cols);
3548#if CONFIG_VP9_HIGHBITDEPTH
3549 }
3550#endif // CONFIG_VP9_HIGHBITDEPTH
3551
3552 colors = colors_u > colors_v ? colors_u : colors_v;
3553 if (colors > 1 && colors <= 64) {
3554 int r, c, n, i, j;
3555 const int max_itr = 50;
3556 int color_ctx, color_idx = 0;
3557 int color_order[PALETTE_MAX_SIZE];
3558 int64_t this_sse;
3559 double lb_u, ub_u, val_u;
3560 double lb_v, ub_v, val_v;
3561 double *const data = x->palette_buffer->kmeans_data_buf;
3562 uint8_t *const indices = x->palette_buffer->kmeans_indices_buf;
3563 uint8_t *const pre_indices = x->palette_buffer->kmeans_pre_indices_buf;
3564 double centroids[2 * PALETTE_MAX_SIZE];
3565 uint8_t *const color_map = xd->plane[1].color_index_map;
3566 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
3567
3568#if CONFIG_VP9_HIGHBITDEPTH
3569 uint16_t *src_u16 = CONVERT_TO_SHORTPTR(src_u);
3570 uint16_t *src_v16 = CONVERT_TO_SHORTPTR(src_v);
3571 if (cpi->common.use_highbitdepth) {
3572 lb_u = src_u16[0];
3573 ub_u = src_u16[0];
3574 lb_v = src_v16[0];
3575 ub_v = src_v16[0];
3576 } else {
3577#endif // CONFIG_VP9_HIGHBITDEPTH
3578 lb_u = src_u[0];
3579 ub_u = src_u[0];
3580 lb_v = src_v[0];
3581 ub_v = src_v[0];
3582#if CONFIG_VP9_HIGHBITDEPTH
3583 }
3584#endif // CONFIG_VP9_HIGHBITDEPTH
3585
3586 mbmi->uv_mode = DC_PRED;
3587#if CONFIG_EXT_INTRA
3588 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
3589#endif // CONFIG_EXT_INTRA
3590 for (r = 0; r < rows; ++r) {
3591 for (c = 0; c < cols; ++c) {
3592#if CONFIG_VP9_HIGHBITDEPTH
3593 if (cpi->common.use_highbitdepth) {
3594 val_u = src_u16[r * src_stride + c];
3595 val_v = src_v16[r * src_stride + c];
3596 data[(r * cols + c) * 2 ] = val_u;
3597 data[(r * cols + c) * 2 + 1] = val_v;
3598 } else {
3599#endif // CONFIG_VP9_HIGHBITDEPTH
3600 val_u = src_u[r * src_stride + c];
3601 val_v = src_v[r * src_stride + c];
3602 data[(r * cols + c) * 2 ] = val_u;
3603 data[(r * cols + c) * 2 + 1] = val_v;
3604#if CONFIG_VP9_HIGHBITDEPTH
3605 }
3606#endif // CONFIG_VP9_HIGHBITDEPTH
3607 if (val_u < lb_u)
3608 lb_u = val_u;
3609 else if (val_u > ub_u)
3610 ub_u = val_u;
3611 if (val_v < lb_v)
3612 lb_v = val_v;
3613 else if (val_v > ub_v)
3614 ub_v = val_v;
3615 }
3616 }
3617
3618 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors;
3619 n >= 2; --n) {
3620 for (i = 0; i < n; ++i) {
3621 centroids[i * 2] = lb_u + (2 * i + 1) * (ub_u - lb_u) / n / 2;
3622 centroids[i * 2 + 1] =
3623 lb_v + (2 * i + 1) * (ub_v - lb_v) / n / 2;;
3624 }
3625 r = vp10_k_means(data, centroids, indices, pre_indices, rows * cols, n,
3626 2, max_itr);
3627 pmi->palette_size[1] = n;
3628 for (i = 1; i < 3; ++i) {
3629 for (j = 0; j < n; ++j) {
3630#if CONFIG_VP9_HIGHBITDEPTH
3631 if (cpi->common.use_highbitdepth)
3632 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
3633 clip_pixel_highbd(round(centroids[j * 2 + i - 1]),
3634 cpi->common.bit_depth);
3635 else
3636#endif // CONFIG_VP9_HIGHBITDEPTH
3637 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
3638 clip_pixel(round(centroids[j * 2 + i - 1]));
3639 }
3640 }
3641 for (r = 0; r < rows; ++r)
3642 for (c = 0; c < cols; ++c)
3643 color_map[r * cols + c] = indices[r * cols + c];
3644
3645 super_block_uvrd(cpi, x, &this_rate_tokenonly,
3646 &this_distortion, &s, &this_sse, bsize, *best_rd);
3647 if (this_rate_tokenonly == INT_MAX)
3648 continue;
3649 this_rate = this_rate_tokenonly + dc_mode_cost +
3650 2 * cpi->common.bit_depth * n * vp10_cost_bit(128, 0) +
3651 cpi->palette_uv_size_cost[bsize - BLOCK_8X8][n - 2] +
3652 write_uniform_cost(n, color_map[0]) +
3653 vp10_cost_bit(vp10_default_palette_uv_mode_prob
3654 [pmi->palette_size[0] > 0], 1);
3655
3656 for (i = 0; i < rows; ++i) {
3657 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
3658 color_ctx = vp10_get_palette_color_context(color_map, cols, i, j, n,
3659 color_order);
3660 for (r = 0; r < n; ++r)
3661 if (color_map[i * cols + j] == color_order[r]) {
3662 color_idx = r;
3663 break;
3664 }
3665 assert(color_idx >= 0 && color_idx < n);
3666 this_rate +=
3667 cpi->palette_uv_color_cost[n - 2][color_ctx][color_idx];
3668 }
3669 }
3670
3671 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3672 if (this_rd < *best_rd) {
3673 *best_rd = this_rd;
3674 *palette_mode_info = *pmi;
3675 memcpy(best_palette_color_map, xd->plane[1].color_index_map,
3676 rows * cols * sizeof(best_palette_color_map[0]));
3677 *mode_selected = DC_PRED;
3678 *rate = this_rate;
3679 *distortion = this_distortion;
3680 *rate_tokenonly = this_rate_tokenonly;
3681 *skippable = s;
3682 if (!x->select_tx_size)
3683 swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE);
3684 }
3685 }
3686 }
3687}
3688
hui sube3559b2015-10-07 09:29:02 -07003689#if CONFIG_EXT_INTRA
3690// Return 1 if an ext intra mode is selected; return 0 otherwise.
3691static int rd_pick_ext_intra_sbuv(VP10_COMP *cpi, MACROBLOCK *x,
3692 PICK_MODE_CONTEXT *ctx,
3693 int *rate, int *rate_tokenonly,
3694 int64_t *distortion, int *skippable,
3695 BLOCK_SIZE bsize, int64_t *best_rd) {
3696 MACROBLOCKD *const xd = &x->e_mbd;
3697 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
3698 int ext_intra_selected_flag = 0;
3699 int this_rate_tokenonly, this_rate, s;
hui su4aa50c12015-11-10 12:09:59 -08003700 int64_t this_distortion, this_sse, this_rd;
hui sube3559b2015-10-07 09:29:02 -07003701 EXT_INTRA_MODE mode;
hui sube3559b2015-10-07 09:29:02 -07003702 EXT_INTRA_MODE_INFO ext_intra_mode_info;
3703
3704 vp10_zero(ext_intra_mode_info);
3705 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 1;
3706 mbmi->uv_mode = DC_PRED;
hui su78b0bd02016-02-23 15:22:25 -08003707 mbmi->palette_mode_info.palette_size[1] = 0;
hui sube3559b2015-10-07 09:29:02 -07003708
hui su4aa50c12015-11-10 12:09:59 -08003709 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
3710 mbmi->ext_intra_mode_info.ext_intra_mode[1] = mode;
3711 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3712 &this_distortion, &s, &this_sse, bsize, *best_rd))
3713 continue;
hui sube3559b2015-10-07 09:29:02 -07003714
hui su4aa50c12015-11-10 12:09:59 -08003715 this_rate = this_rate_tokenonly +
3716 vp10_cost_bit(cpi->common.fc->ext_intra_probs[1], 1) +
3717 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
3718 write_uniform_cost(FILTER_INTRA_MODES, mode);
3719 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3720 if (this_rd < *best_rd) {
3721 *best_rd = this_rd;
3722 *rate = this_rate;
3723 *rate_tokenonly = this_rate_tokenonly;
3724 *distortion = this_distortion;
3725 *skippable = s;
3726 ext_intra_mode_info = mbmi->ext_intra_mode_info;
3727 ext_intra_selected_flag = 1;
3728 if (!x->select_tx_size)
3729 swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE);
hui sube3559b2015-10-07 09:29:02 -07003730 }
3731 }
3732
hui sube3559b2015-10-07 09:29:02 -07003733
3734 if (ext_intra_selected_flag) {
3735 mbmi->uv_mode = DC_PRED;
3736 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
3737 ext_intra_mode_info.use_ext_intra_mode[1];
3738 mbmi->ext_intra_mode_info.ext_intra_mode[1] =
3739 ext_intra_mode_info.ext_intra_mode[1];
hui sube3559b2015-10-07 09:29:02 -07003740 return 1;
3741 } else {
3742 return 0;
3743 }
3744}
hui su4aa50c12015-11-10 12:09:59 -08003745
hui su5a7c8d82016-02-08 10:39:17 -08003746static void pick_intra_angle_routine_sbuv(VP10_COMP *cpi, MACROBLOCK *x,
3747 int *rate, int *rate_tokenonly,
3748 int64_t *distortion, int *skippable,
3749 int *best_angle_delta,
3750 BLOCK_SIZE bsize, int rate_overhead,
3751 int64_t *best_rd) {
3752 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
3753 int this_rate_tokenonly, this_rate, s;
3754 int64_t this_distortion, this_sse, this_rd;
3755
3756 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3757 &this_distortion, &s, &this_sse, bsize, *best_rd))
3758 return;
3759
3760 this_rate = this_rate_tokenonly + rate_overhead;
3761 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3762 if (this_rd < *best_rd) {
3763 *best_rd = this_rd;
3764 *best_angle_delta = mbmi->angle_delta[1];
3765 *rate = this_rate;
3766 *rate_tokenonly = this_rate_tokenonly;
3767 *distortion = this_distortion;
3768 *skippable = s;
3769 }
3770}
3771
hui su4aa50c12015-11-10 12:09:59 -08003772static int rd_pick_intra_angle_sbuv(VP10_COMP *cpi, MACROBLOCK *x,
3773 PICK_MODE_CONTEXT *ctx,
3774 int *rate, int *rate_tokenonly,
3775 int64_t *distortion, int *skippable,
3776 BLOCK_SIZE bsize, int rate_overhead,
3777 int64_t best_rd) {
3778 MACROBLOCKD *const xd = &x->e_mbd;
3779 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
3780 int this_rate_tokenonly, this_rate, s;
3781 int64_t this_distortion, this_sse, this_rd;
3782 int angle_delta, best_angle_delta = 0;
3783 const double rd_adjust = 1.2;
3784
3785 (void)ctx;
3786 *rate_tokenonly = INT_MAX;
3787 if (ANGLE_FAST_SEARCH) {
3788 int deltas_level1[3] = {0, -2, 2};
3789 int deltas_level2[3][2] = {
3790 {-1, 1}, {-3, -1}, {1, 3},
3791 };
3792 const int level1 = 3, level2 = 2;
3793 int i, j, best_i = -1;
3794
3795 for (i = 0; i < level1; ++i) {
Yaowu Xu28eb7842016-03-07 16:23:26 -08003796 int64_t tmp_best_rd;
hui su4aa50c12015-11-10 12:09:59 -08003797 mbmi->angle_delta[1] = deltas_level1[i];
Yaowu Xu28eb7842016-03-07 16:23:26 -08003798 tmp_best_rd = (i == 0 && best_rd < INT64_MAX) ?
3799 (int64_t)(best_rd * rd_adjust) : best_rd;
3800 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion,
3801 &s, &this_sse, bsize, tmp_best_rd)) {
hui su4aa50c12015-11-10 12:09:59 -08003802 if (i == 0)
3803 break;
3804 else
3805 continue;
3806 }
3807 this_rate = this_rate_tokenonly + rate_overhead;
3808 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3809 if (i == 0 && best_rd < INT64_MAX && this_rd > best_rd * rd_adjust)
3810 break;
3811 if (this_rd < best_rd) {
3812 best_i = i;
3813 best_rd = this_rd;
3814 best_angle_delta = mbmi->angle_delta[1];
3815 *rate = this_rate;
3816 *rate_tokenonly = this_rate_tokenonly;
3817 *distortion = this_distortion;
3818 *skippable = s;
3819 }
3820 }
3821
3822 if (best_i >= 0) {
3823 for (j = 0; j < level2; ++j) {
3824 mbmi->angle_delta[1] = deltas_level2[best_i][j];
hui su5a7c8d82016-02-08 10:39:17 -08003825 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly,
3826 distortion, skippable,
3827 &best_angle_delta, bsize,
3828 rate_overhead, &best_rd);
hui su4aa50c12015-11-10 12:09:59 -08003829 }
3830 }
3831 } else {
3832 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
3833 ++angle_delta) {
3834 mbmi->angle_delta[1] = angle_delta;
hui su5a7c8d82016-02-08 10:39:17 -08003835 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly,
3836 distortion, skippable,
3837 &best_angle_delta, bsize,
3838 rate_overhead, &best_rd);
hui su4aa50c12015-11-10 12:09:59 -08003839 }
3840 }
3841
3842 mbmi->angle_delta[1] = best_angle_delta;
3843 if (*rate_tokenonly != INT_MAX)
3844 super_block_uvrd(cpi, x, &this_rate_tokenonly,
3845 &this_distortion, &s, &this_sse, bsize, INT_MAX);
3846 return *rate_tokenonly != INT_MAX;
3847}
hui sube3559b2015-10-07 09:29:02 -07003848#endif // CONFIG_EXT_INTRA
3849
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003850static int64_t rd_pick_intra_sbuv_mode(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003851 PICK_MODE_CONTEXT *ctx,
3852 int *rate, int *rate_tokenonly,
3853 int64_t *distortion, int *skippable,
3854 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
3855 MACROBLOCKD *xd = &x->e_mbd;
hui sube3559b2015-10-07 09:29:02 -07003856 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Jingning Han3ee6db62015-08-05 19:00:31 -07003857 PREDICTION_MODE mode;
3858 PREDICTION_MODE mode_selected = DC_PRED;
3859 int64_t best_rd = INT64_MAX, this_rd;
3860 int this_rate_tokenonly, this_rate, s;
3861 int64_t this_distortion, this_sse;
hui su78b0bd02016-02-23 15:22:25 -08003862 const int rows = (4 * num_4x4_blocks_high_lookup[bsize]) >>
3863 (xd->plane[1].subsampling_y);
3864 const int cols = (4 * num_4x4_blocks_wide_lookup[bsize]) >>
3865 (xd->plane[1].subsampling_x);
3866 PALETTE_MODE_INFO palette_mode_info;
3867 PALETTE_MODE_INFO *const pmi = &xd->mi[0]->mbmi.palette_mode_info;
3868 uint8_t *best_palette_color_map = NULL;
hui sube3559b2015-10-07 09:29:02 -07003869#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08003870 int is_directional_mode, rate_overhead, best_angle_delta = 0;
hui sube3559b2015-10-07 09:29:02 -07003871 EXT_INTRA_MODE_INFO ext_intra_mode_info;
Jingning Han3ee6db62015-08-05 19:00:31 -07003872
hui sube3559b2015-10-07 09:29:02 -07003873 ext_intra_mode_info.use_ext_intra_mode[1] = 0;
3874 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
3875#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07003876 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
hui su78b0bd02016-02-23 15:22:25 -08003877 palette_mode_info.palette_size[1] = 0;
3878 pmi->palette_size[1] = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07003879 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
3880 if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode)))
3881 continue;
3882
hui sube3559b2015-10-07 09:29:02 -07003883 mbmi->uv_mode = mode;
hui su4aa50c12015-11-10 12:09:59 -08003884#if CONFIG_EXT_INTRA
3885 is_directional_mode = (mode != DC_PRED && mode != TM_PRED);
3886 rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
3887 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
3888 mbmi->angle_delta[1] = 0;
3889 if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode) {
3890 if (!rd_pick_intra_angle_sbuv(cpi, x, ctx, &this_rate,
3891 &this_rate_tokenonly, &this_distortion, &s,
3892 bsize, rate_overhead, best_rd))
3893 continue;
3894 } else {
3895 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3896 &this_distortion, &s, &this_sse, bsize, best_rd))
3897 continue;
3898 }
3899 this_rate = this_rate_tokenonly +
3900 cpi->intra_uv_mode_cost[mbmi->mode][mode];
3901 if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode)
3902 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
3903 MAX_ANGLE_DELTAS +
3904 mbmi->angle_delta[1]);
hui su8102aeb2016-03-11 10:23:51 -08003905 if (mode == DC_PRED)
hui su4aa50c12015-11-10 12:09:59 -08003906 this_rate += vp10_cost_bit(cpi->common.fc->ext_intra_probs[1], 0);
3907#else
Jingning Han3ee6db62015-08-05 19:00:31 -07003908 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3909 &this_distortion, &s, &this_sse, bsize, best_rd))
3910 continue;
hui su6ab6ac42015-11-06 13:56:51 -08003911 this_rate = this_rate_tokenonly +
hui su78b0bd02016-02-23 15:22:25 -08003912 cpi->intra_uv_mode_cost[mbmi->mode][mode];
hui sube3559b2015-10-07 09:29:02 -07003913#endif // CONFIG_EXT_INTRA
hui su78b0bd02016-02-23 15:22:25 -08003914 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8 &&
3915 mode == DC_PRED)
3916 this_rate += vp10_cost_bit(vp10_default_palette_uv_mode_prob
3917 [pmi->palette_size[0] > 0], 0);
hui su4aa50c12015-11-10 12:09:59 -08003918
Jingning Han3ee6db62015-08-05 19:00:31 -07003919 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3920
3921 if (this_rd < best_rd) {
3922 mode_selected = mode;
hui su4aa50c12015-11-10 12:09:59 -08003923#if CONFIG_EXT_INTRA
3924 best_angle_delta = mbmi->angle_delta[1];
3925#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07003926 best_rd = this_rd;
3927 *rate = this_rate;
3928 *rate_tokenonly = this_rate_tokenonly;
3929 *distortion = this_distortion;
3930 *skippable = s;
3931 if (!x->select_tx_size)
3932 swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE);
3933 }
3934 }
3935
hui su78b0bd02016-02-23 15:22:25 -08003936 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8) {
3937 best_palette_color_map = x->palette_buffer->best_palette_color_map;
3938 rd_pick_palette_intra_sbuv(cpi, x, ctx,
3939 cpi->intra_uv_mode_cost[mbmi->mode][DC_PRED],
3940 &palette_mode_info, best_palette_color_map,
3941 &mode_selected, &best_rd, rate, rate_tokenonly,
3942 distortion, skippable);
3943 }
3944
hui sube3559b2015-10-07 09:29:02 -07003945#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08003946 if (mbmi->sb_type >= BLOCK_8X8 && ALLOW_FILTER_INTRA_MODES) {
hui sube3559b2015-10-07 09:29:02 -07003947 if (rd_pick_ext_intra_sbuv(cpi, x, ctx, rate, rate_tokenonly, distortion,
3948 skippable, bsize, &best_rd)) {
3949 mode_selected = mbmi->uv_mode;
3950 ext_intra_mode_info = mbmi->ext_intra_mode_info;
3951 }
3952 }
3953
3954 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
3955 ext_intra_mode_info.use_ext_intra_mode[1];
hui su78b0bd02016-02-23 15:22:25 -08003956 if (ext_intra_mode_info.use_ext_intra_mode[1]) {
hui sube3559b2015-10-07 09:29:02 -07003957 mbmi->ext_intra_mode_info.ext_intra_mode[1] =
3958 ext_intra_mode_info.ext_intra_mode[1];
hui su78b0bd02016-02-23 15:22:25 -08003959 palette_mode_info.palette_size[1] = 0;
3960 }
hui su4aa50c12015-11-10 12:09:59 -08003961 mbmi->angle_delta[1] = best_angle_delta;
hui sube3559b2015-10-07 09:29:02 -07003962#endif // CONFIG_EXT_INTRA
3963 mbmi->uv_mode = mode_selected;
hui su78b0bd02016-02-23 15:22:25 -08003964 pmi->palette_size[1] = palette_mode_info.palette_size[1];
3965 if (palette_mode_info.palette_size[1] > 0) {
3966 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
3967 palette_mode_info.palette_colors + PALETTE_MAX_SIZE,
3968 2 * PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
3969 memcpy(xd->plane[1].color_index_map, best_palette_color_map,
3970 rows * cols * sizeof(best_palette_color_map[0]));
3971 }
3972
Jingning Han3ee6db62015-08-05 19:00:31 -07003973 return best_rd;
3974}
3975
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003976static int64_t rd_sbuv_dcpred(const VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003977 int *rate, int *rate_tokenonly,
3978 int64_t *distortion, int *skippable,
3979 BLOCK_SIZE bsize) {
Jingning Han3ee6db62015-08-05 19:00:31 -07003980 int64_t unused;
3981
3982 x->e_mbd.mi[0]->mbmi.uv_mode = DC_PRED;
3983 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
3984 super_block_uvrd(cpi, x, rate_tokenonly, distortion,
3985 skippable, &unused, bsize, INT64_MAX);
hui su6ab6ac42015-11-06 13:56:51 -08003986 *rate = *rate_tokenonly +
3987 cpi->intra_uv_mode_cost[x->e_mbd.mi[0]->mbmi.mode][DC_PRED];
Jingning Han3ee6db62015-08-05 19:00:31 -07003988 return RDCOST(x->rdmult, x->rddiv, *rate, *distortion);
3989}
3990
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003991static void choose_intra_uv_mode(VP10_COMP *cpi, MACROBLOCK *const x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003992 PICK_MODE_CONTEXT *ctx,
3993 BLOCK_SIZE bsize, TX_SIZE max_tx_size,
3994 int *rate_uv, int *rate_uv_tokenonly,
3995 int64_t *dist_uv, int *skip_uv,
3996 PREDICTION_MODE *mode_uv) {
3997 // Use an estimated rd for uv_intra based on DC_PRED if the
3998 // appropriate speed flag is set.
3999 if (cpi->sf.use_uv_intra_rd_estimate) {
4000 rd_sbuv_dcpred(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv,
4001 skip_uv, bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize);
4002 // Else do a proper rd search for each possible transform size that may
4003 // be considered in the main rd loop.
4004 } else {
4005 rd_pick_intra_sbuv_mode(cpi, x, ctx,
4006 rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4007 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
4008 }
4009 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
4010}
4011
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004012static int cost_mv_ref(const VP10_COMP *cpi, PREDICTION_MODE mode,
Yue Chen1ac85872016-01-07 15:13:52 -08004013#if CONFIG_REF_MV && CONFIG_EXT_INTER
4014 int is_compound,
4015#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004016 int16_t mode_context) {
Jingning Han1dc18072015-12-02 10:59:01 -08004017#if CONFIG_REF_MV
4018 int mode_cost = 0;
Yue Chen968bbc72016-01-19 16:45:45 -08004019#if CONFIG_EXT_INTER
4020 int16_t mode_ctx = is_compound ? mode_context :
4021 (mode_context & NEWMV_CTX_MASK);
4022#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004023 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
Yue Chen968bbc72016-01-19 16:45:45 -08004024#endif // CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004025 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
Jingning Han1dc18072015-12-02 10:59:01 -08004026
4027 assert(is_inter_mode(mode));
4028
Yue Chen1ac85872016-01-07 15:13:52 -08004029#if CONFIG_EXT_INTER
Yue Chen968bbc72016-01-19 16:45:45 -08004030 if (is_compound) {
4031 return cpi->inter_compound_mode_cost[mode_context]
4032 [INTER_COMPOUND_OFFSET(mode)];
4033 } else {
4034 if (mode == NEWMV || mode == NEWFROMNEARMV) {
Yue Chen1ac85872016-01-07 15:13:52 -08004035#else
Jingning Han1dc18072015-12-02 10:59:01 -08004036 if (mode == NEWMV) {
Yue Chen1ac85872016-01-07 15:13:52 -08004037#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08004038 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
Yue Chen1ac85872016-01-07 15:13:52 -08004039#if CONFIG_EXT_INTER
4040 if (!is_compound)
4041 mode_cost += cpi->new2mv_mode_cost[mode == NEWFROMNEARMV];
4042#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08004043 return mode_cost;
4044 } else {
4045 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
4046 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004047
4048 if (is_all_zero_mv)
4049 return mode_cost;
4050
Jingning Han1dc18072015-12-02 10:59:01 -08004051 if (mode == ZEROMV) {
4052 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
4053 return mode_cost;
4054 } else {
4055 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004056 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
Jingning Han387a10e2015-12-09 09:07:39 -08004057
4058 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET))
4059 mode_ctx = 6;
4060 if (mode_context & (1 << SKIP_NEARMV_OFFSET))
4061 mode_ctx = 7;
4062 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET))
4063 mode_ctx = 8;
4064
Jingning Han1dc18072015-12-02 10:59:01 -08004065 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
4066 return mode_cost;
4067 }
4068 }
Yue Chen968bbc72016-01-19 16:45:45 -08004069#if CONFIG_EXT_INTER
4070 }
4071#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08004072#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004073 assert(is_inter_mode(mode));
Yue Chen968bbc72016-01-19 16:45:45 -08004074#if CONFIG_EXT_INTER
4075 if (is_inter_compound_mode(mode)) {
4076 return cpi->inter_compound_mode_cost[mode_context]
4077 [INTER_COMPOUND_OFFSET(mode)];
4078 } else {
4079#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004080 return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
Yue Chen968bbc72016-01-19 16:45:45 -08004081#if CONFIG_EXT_INTER
4082 }
4083#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08004084#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07004085}
4086
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004087static int set_and_cost_bmi_mvs(VP10_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd,
Jingning Han3ee6db62015-08-05 19:00:31 -07004088 int i,
4089 PREDICTION_MODE mode, int_mv this_mv[2],
4090 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
4091 int_mv seg_mvs[MAX_REF_FRAMES],
Yue Chen1ac85872016-01-07 15:13:52 -08004092#if CONFIG_EXT_INTER
4093 int_mv compound_seg_newmvs[2],
4094#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004095 int_mv *best_ref_mv[2], const int *mvjcost,
4096 int *mvcost[2]) {
4097 MODE_INFO *const mic = xd->mi[0];
4098 const MB_MODE_INFO *const mbmi = &mic->mbmi;
4099 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4100 int thismvcost = 0;
4101 int idx, idy;
4102 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
4103 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
4104 const int is_compound = has_second_ref(mbmi);
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004105 int mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
Jingning Han3ee6db62015-08-05 19:00:31 -07004106
4107 switch (mode) {
4108 case NEWMV:
Yue Chen1ac85872016-01-07 15:13:52 -08004109#if CONFIG_EXT_INTER
4110 case NEWFROMNEARMV:
Yue Chen1ac85872016-01-07 15:13:52 -08004111#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004112 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08004113#if CONFIG_EXT_INTER
4114 if (!cpi->common.allow_high_precision_mv ||
4115 !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
4116 lower_mv_precision(&this_mv[0].as_mv, 0);
4117#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004118 thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4119 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yue Chen968bbc72016-01-19 16:45:45 -08004120#if !CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004121 if (is_compound) {
4122 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
4123 thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4124 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
4125 }
Yue Chen968bbc72016-01-19 16:45:45 -08004126#endif // !CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004127 break;
4128 case NEARMV:
4129 case NEARESTMV:
4130 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4131 if (is_compound)
4132 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4133 break;
4134 case ZEROMV:
4135 this_mv[0].as_int = 0;
4136 if (is_compound)
4137 this_mv[1].as_int = 0;
4138 break;
Yue Chen968bbc72016-01-19 16:45:45 -08004139#if CONFIG_EXT_INTER
4140 case NEW_NEWMV:
4141 if (compound_seg_newmvs[0].as_int == INVALID_MV ||
4142 compound_seg_newmvs[1].as_int == INVALID_MV) {
4143 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
4144 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
4145 } else {
4146 this_mv[0].as_int = compound_seg_newmvs[0].as_int;
4147 this_mv[1].as_int = compound_seg_newmvs[1].as_int;
4148 }
4149 if (!cpi->common.allow_high_precision_mv ||
4150 !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
4151 lower_mv_precision(&this_mv[0].as_mv, 0);
4152 if (!cpi->common.allow_high_precision_mv ||
4153 !vp10_use_mv_hp(&best_ref_mv[1]->as_mv))
4154 lower_mv_precision(&this_mv[1].as_mv, 0);
4155 thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv,
4156 &best_ref_mv[0]->as_mv,
4157 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
4158 thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv,
4159 &best_ref_mv[1]->as_mv,
4160 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
4161 break;
4162 case NEW_NEARMV:
4163 case NEW_NEARESTMV:
4164 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
4165 if (!cpi->common.allow_high_precision_mv ||
4166 !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
4167 lower_mv_precision(&this_mv[0].as_mv, 0);
4168 thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4169 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
4170 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4171 break;
4172 case NEAR_NEWMV:
4173 case NEAREST_NEWMV:
4174 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4175 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
4176 if (!cpi->common.allow_high_precision_mv ||
4177 !vp10_use_mv_hp(&best_ref_mv[1]->as_mv))
4178 lower_mv_precision(&this_mv[1].as_mv, 0);
4179 thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4180 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
4181 break;
4182 case NEAREST_NEARMV:
4183 case NEAR_NEARESTMV:
4184 case NEAREST_NEARESTMV:
4185 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4186 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4187 break;
4188 case ZERO_ZEROMV:
4189 this_mv[0].as_int = 0;
4190 this_mv[1].as_int = 0;
4191 break;
4192#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004193 default:
4194 break;
4195 }
4196
4197 mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
4198 if (is_compound)
4199 mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
4200
4201 mic->bmi[i].as_mode = mode;
4202
Jingning Han876c8b02016-02-17 16:10:38 -08004203#if CONFIG_REF_MV
4204 if (mode == NEWMV) {
4205 mic->bmi[i].pred_mv[0].as_int =
4206 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_int;
4207 if (is_compound)
4208 mic->bmi[i].pred_mv[1].as_int =
4209 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_int;
4210 } else {
4211 mic->bmi[i].pred_mv[0].as_int = this_mv[0].as_int;
4212 if (is_compound)
4213 mic->bmi[i].pred_mv[1].as_int = this_mv[1].as_int;
4214 }
4215#endif
4216
Jingning Han3ee6db62015-08-05 19:00:31 -07004217 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
4218 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
4219 memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
4220
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004221#if CONFIG_REF_MV
Yue Chen968bbc72016-01-19 16:45:45 -08004222#if CONFIG_EXT_INTER
4223 if (is_compound)
4224 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
4225 else
4226#endif // CONFIG_EXT_INTER
Jingning Han387a10e2015-12-09 09:07:39 -08004227 mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
4228 mbmi->ref_frame, mbmi->sb_type, i);
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004229#endif
Yue Chen1ac85872016-01-07 15:13:52 -08004230#if CONFIG_REF_MV && CONFIG_EXT_INTER
4231 return cost_mv_ref(cpi, mode, is_compound, mode_ctx) + thismvcost;
4232#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004233 return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
Yue Chen1ac85872016-01-07 15:13:52 -08004234#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004235}
4236
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004237static int64_t encode_inter_mb_segment(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07004238 MACROBLOCK *x,
4239 int64_t best_yrd,
4240 int i,
4241 int *labelyrate,
4242 int64_t *distortion, int64_t *sse,
4243 ENTROPY_CONTEXT *ta,
4244 ENTROPY_CONTEXT *tl,
Yaowu Xu7c514e22015-09-28 15:55:46 -07004245 int ir, int ic,
Jingning Han3ee6db62015-08-05 19:00:31 -07004246 int mi_row, int mi_col) {
4247 int k;
4248 MACROBLOCKD *xd = &x->e_mbd;
4249 struct macroblockd_plane *const pd = &xd->plane[0];
4250 struct macroblock_plane *const p = &x->plane[0];
4251 MODE_INFO *const mi = xd->mi[0];
4252 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
4253 const int width = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
4254 const int height = 4 * num_4x4_blocks_high_lookup[plane_bsize];
4255 int idx, idy;
Yaowu Xu7c514e22015-09-28 15:55:46 -07004256 void (*fwd_txm4x4)(const int16_t *input, tran_low_t *output, int stride);
Jingning Han3ee6db62015-08-05 19:00:31 -07004257
4258 const uint8_t *const src =
4259 &p->src.buf[vp10_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
4260 uint8_t *const dst = &pd->dst.buf[vp10_raster_block_offset(BLOCK_8X8, i,
4261 pd->dst.stride)];
4262 int64_t thisdistortion = 0, thissse = 0;
Yaowu Xu7c514e22015-09-28 15:55:46 -07004263 int thisrate = 0;
hui sub3cc3a02015-08-24 14:37:54 -07004264 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, i, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07004265 const scan_order *so = get_scan(TX_4X4, tx_type, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07004266
Yaowu Xu7c514e22015-09-28 15:55:46 -07004267 vp10_build_inter_predictor_sub8x8(xd, 0, i, ir, ic, mi_row, mi_col);
4268
Jingning Han3ee6db62015-08-05 19:00:31 -07004269#if CONFIG_VP9_HIGHBITDEPTH
4270 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04004271 fwd_txm4x4 = xd->lossless[mi->mbmi.segment_id] ? vp10_highbd_fwht4x4
4272 : vpx_highbd_fdct4x4;
Jingning Han3ee6db62015-08-05 19:00:31 -07004273 } else {
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04004274 fwd_txm4x4 = xd->lossless[mi->mbmi.segment_id] ? vp10_fwht4x4 : vpx_fdct4x4;
Jingning Han3ee6db62015-08-05 19:00:31 -07004275 }
4276#else
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04004277 fwd_txm4x4 = xd->lossless[mi->mbmi.segment_id] ? vp10_fwht4x4 : vpx_fdct4x4;
Jingning Han3ee6db62015-08-05 19:00:31 -07004278#endif // CONFIG_VP9_HIGHBITDEPTH
Jingning Han3ee6db62015-08-05 19:00:31 -07004279
4280#if CONFIG_VP9_HIGHBITDEPTH
4281 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
4282 vpx_highbd_subtract_block(
4283 height, width, vp10_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
4284 8, src, p->src.stride, dst, pd->dst.stride, xd->bd);
4285 } else {
4286 vpx_subtract_block(
4287 height, width, vp10_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
4288 8, src, p->src.stride, dst, pd->dst.stride);
4289 }
4290#else
4291 vpx_subtract_block(height, width,
4292 vp10_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
4293 8, src, p->src.stride, dst, pd->dst.stride);
4294#endif // CONFIG_VP9_HIGHBITDEPTH
4295
4296 k = i;
4297 for (idy = 0; idy < height / 4; ++idy) {
4298 for (idx = 0; idx < width / 4; ++idx) {
Yue Chenef8f7c12016-03-04 09:48:57 -08004299 int64_t dist, ssz, rd, rd1, rd2;
Jingning Han3ee6db62015-08-05 19:00:31 -07004300 tran_low_t* coeff;
Jingning Han2cdc1272015-10-09 09:57:42 -07004301#if CONFIG_VAR_TX
4302 int coeff_ctx;
4303#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07004304 k += (idy * 2 + idx);
Jingning Han2cdc1272015-10-09 09:57:42 -07004305#if CONFIG_VAR_TX
4306 coeff_ctx = combine_entropy_contexts(*(ta + (k & 1)),
4307 *(tl + (k >> 1)));
4308#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07004309 coeff = BLOCK_OFFSET(p->coeff, k);
Yaowu Xu7c514e22015-09-28 15:55:46 -07004310 fwd_txm4x4(vp10_raster_block_offset_int16(BLOCK_8X8, k, p->src_diff),
4311 coeff, 8);
Jingning Han3ee6db62015-08-05 19:00:31 -07004312 vp10_regular_quantize_b_4x4(x, 0, k, so->scan, so->iscan);
Yue Chenef8f7c12016-03-04 09:48:57 -08004313 dist_block(cpi, x, 0, k, idy + (i >> 1), idx + (i & 0x1), TX_4X4,
4314 &dist, &ssz);
4315 thisdistortion += dist;
Jingning Han3ee6db62015-08-05 19:00:31 -07004316 thissse += ssz;
Jingning Han2cdc1272015-10-09 09:57:42 -07004317#if CONFIG_VAR_TX
4318 thisrate += cost_coeffs(x, 0, k, coeff_ctx,
4319 TX_4X4,
Jingning Han3ee6db62015-08-05 19:00:31 -07004320 so->scan, so->neighbors,
4321 cpi->sf.use_fast_coef_costing);
Jingning Han2cdc1272015-10-09 09:57:42 -07004322 *(ta + (k & 1)) = !(p->eobs[k] == 0);
4323 *(tl + (k >> 1)) = !(p->eobs[k] == 0);
4324#else
4325 thisrate += cost_coeffs(x, 0, k, ta + (k & 1), tl + (k >> 1),
4326 TX_4X4,
4327 so->scan, so->neighbors,
4328 cpi->sf.use_fast_coef_costing);
4329#endif
Yue Chenef8f7c12016-03-04 09:48:57 -08004330 rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion);
4331 rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse);
James Zern5e16d392015-08-17 18:19:22 -07004332 rd = VPXMIN(rd1, rd2);
Jingning Han3ee6db62015-08-05 19:00:31 -07004333 if (rd >= best_yrd)
4334 return INT64_MAX;
4335 }
4336 }
4337
Yue Chenef8f7c12016-03-04 09:48:57 -08004338 *distortion = thisdistortion;
Jingning Han3ee6db62015-08-05 19:00:31 -07004339 *labelyrate = thisrate;
Yue Chenef8f7c12016-03-04 09:48:57 -08004340 *sse = thissse;
Jingning Han3ee6db62015-08-05 19:00:31 -07004341
4342 return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
4343}
4344
4345typedef struct {
4346 int eobs;
4347 int brate;
4348 int byrate;
4349 int64_t bdist;
4350 int64_t bsse;
4351 int64_t brdcost;
4352 int_mv mvs[2];
Yue Chen1ac85872016-01-07 15:13:52 -08004353#if CONFIG_EXT_INTER
4354 int_mv ref_mv[2];
4355#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004356 ENTROPY_CONTEXT ta[2];
4357 ENTROPY_CONTEXT tl[2];
4358} SEG_RDSTAT;
4359
4360typedef struct {
4361 int_mv *ref_mv[2];
4362 int_mv mvp;
4363
4364 int64_t segment_rd;
4365 int r;
4366 int64_t d;
4367 int64_t sse;
4368 int segment_yrate;
4369 PREDICTION_MODE modes[4];
Yue Chen968bbc72016-01-19 16:45:45 -08004370#if CONFIG_EXT_INTER
4371 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
4372#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004373 SEG_RDSTAT rdstat[4][INTER_MODES];
Yue Chen968bbc72016-01-19 16:45:45 -08004374#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004375 int mvthresh;
4376} BEST_SEG_INFO;
4377
4378static INLINE int mv_check_bounds(const MACROBLOCK *x, const MV *mv) {
4379 return (mv->row >> 3) < x->mv_row_min ||
4380 (mv->row >> 3) > x->mv_row_max ||
4381 (mv->col >> 3) < x->mv_col_min ||
4382 (mv->col >> 3) > x->mv_col_max;
4383}
4384
4385static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
4386 MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
4387 struct macroblock_plane *const p = &x->plane[0];
4388 struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
4389
4390 p->src.buf = &p->src.buf[vp10_raster_block_offset(BLOCK_8X8, i,
4391 p->src.stride)];
4392 assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
4393 pd->pre[0].buf = &pd->pre[0].buf[vp10_raster_block_offset(BLOCK_8X8, i,
4394 pd->pre[0].stride)];
4395 if (has_second_ref(mbmi))
4396 pd->pre[1].buf = &pd->pre[1].buf[vp10_raster_block_offset(BLOCK_8X8, i,
4397 pd->pre[1].stride)];
4398}
4399
4400static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
4401 struct buf_2d orig_pre[2]) {
4402 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
4403 x->plane[0].src = orig_src;
4404 x->e_mbd.plane[0].pre[0] = orig_pre[0];
4405 if (has_second_ref(mbmi))
4406 x->e_mbd.plane[0].pre[1] = orig_pre[1];
4407}
4408
Jingning Han3ee6db62015-08-05 19:00:31 -07004409// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
4410// TODO(aconverse): Find out if this is still productive then clean up or remove
4411static int check_best_zero_mv(
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004412 const VP10_COMP *cpi, const int16_t mode_context[MAX_REF_FRAMES],
Yue Chen968bbc72016-01-19 16:45:45 -08004413#if CONFIG_REF_MV && CONFIG_EXT_INTER
4414 const int16_t compound_mode_context[MAX_REF_FRAMES],
4415#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004416 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES], int this_mode,
Jingning Han387a10e2015-12-09 09:07:39 -08004417 const MV_REFERENCE_FRAME ref_frames[2],
4418 const BLOCK_SIZE bsize, int block) {
Geza Lore7ded0382016-02-22 10:55:32 +00004419
4420#if !CONFIG_EXT_INTER
4421 assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
4422#endif
4423
Jingning Han3ee6db62015-08-05 19:00:31 -07004424 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
4425 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
Geza Lore7ded0382016-02-22 10:55:32 +00004426 (ref_frames[1] <= INTRA_FRAME ||
Jingning Han3ee6db62015-08-05 19:00:31 -07004427 frame_mv[this_mode][ref_frames[1]].as_int == 0)) {
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004428#if CONFIG_REF_MV
Jingning Han387a10e2015-12-09 09:07:39 -08004429 int16_t rfc = vp10_mode_context_analyzer(mode_context,
4430 ref_frames, bsize, block);
Jingning Hanaa5d53e2015-12-07 15:54:59 -08004431#else
4432 int16_t rfc = mode_context[ref_frames[0]];
4433#endif
Yue Chen1ac85872016-01-07 15:13:52 -08004434#if CONFIG_REF_MV && CONFIG_EXT_INTER
4435 int c1 = cost_mv_ref(cpi, NEARMV, ref_frames[1] > INTRA_FRAME, rfc);
4436 int c2 = cost_mv_ref(cpi, NEARESTMV, ref_frames[1] > INTRA_FRAME, rfc);
4437 int c3 = cost_mv_ref(cpi, ZEROMV, ref_frames[1] > INTRA_FRAME, rfc);
4438#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004439 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
4440 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
4441 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
Yue Chen1ac85872016-01-07 15:13:52 -08004442#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004443
Jingning Han387a10e2015-12-09 09:07:39 -08004444#if !CONFIG_REF_MV
4445 (void)bsize;
4446 (void)block;
4447#endif
4448
Jingning Han3ee6db62015-08-05 19:00:31 -07004449 if (this_mode == NEARMV) {
4450 if (c1 > c3) return 0;
4451 } else if (this_mode == NEARESTMV) {
4452 if (c2 > c3) return 0;
4453 } else {
4454 assert(this_mode == ZEROMV);
Geza Lore7ded0382016-02-22 10:55:32 +00004455 if (ref_frames[1] <= INTRA_FRAME) {
Jingning Han3ee6db62015-08-05 19:00:31 -07004456 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
4457 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
4458 return 0;
4459 } else {
4460 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
4461 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
4462 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
4463 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
4464 return 0;
4465 }
4466 }
4467 }
Yue Chen968bbc72016-01-19 16:45:45 -08004468#if CONFIG_EXT_INTER
4469 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
4470 this_mode == NEAR_NEARESTMV || this_mode == ZERO_ZEROMV) &&
4471 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
4472 frame_mv[this_mode][ref_frames[1]].as_int == 0) {
4473#if CONFIG_REF_MV
4474 int16_t rfc = compound_mode_context[ref_frames[0]];
4475 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, 1, rfc);
4476 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, 1, rfc);
4477 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, 1, rfc);
4478 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, 1, rfc);
4479#else
4480 int16_t rfc = mode_context[ref_frames[0]];
4481 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
4482 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
4483 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
4484 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
4485#endif
4486
4487 if (this_mode == NEAREST_NEARMV) {
4488 if (c1 > c3) return 0;
4489 } else if (this_mode == NEAREST_NEARESTMV) {
4490 if (c2 > c3) return 0;
4491 } else if (this_mode == NEAR_NEARESTMV) {
4492 if (c4 > c3) return 0;
4493 } else {
4494 assert(this_mode == ZERO_ZEROMV);
Geza Lore7ded0382016-02-22 10:55:32 +00004495 if ((c3 >= c2 &&
4496 frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
4497 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
4498 (c3 >= c1 &&
4499 frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
4500 frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
4501 (c3 >= c4 &&
4502 frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
4503 frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
4504 return 0;
Yue Chen968bbc72016-01-19 16:45:45 -08004505 }
4506 }
4507#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004508 return 1;
4509}
4510
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004511static void joint_motion_search(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07004512 BLOCK_SIZE bsize,
4513 int_mv *frame_mv,
4514 int mi_row, int mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08004515#if CONFIG_EXT_INTER
4516 int_mv* ref_mv_sub8x8[2],
4517#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07004518 int_mv single_newmv[MAX_REF_FRAMES],
Yunqing Wang342a3682016-02-16 14:33:18 -08004519 int *rate_mv,
4520 const int block) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07004521 const VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07004522 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
4523 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
4524 MACROBLOCKD *xd = &x->e_mbd;
4525 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4526 const int refs[2] = {mbmi->ref_frame[0],
4527 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]};
4528 int_mv ref_mv[2];
4529 int ite, ref;
Angie Chiang10ad97b2016-02-01 12:49:15 -08004530 const INTERP_FILTER interp_filter = mbmi->interp_filter;
Jingning Han3ee6db62015-08-05 19:00:31 -07004531 struct scale_factors sf;
4532
4533 // Do joint motion search in compound mode to get more accurate mv.
4534 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
4535 int last_besterr[2] = {INT_MAX, INT_MAX};
4536 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
4537 vp10_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
4538 vp10_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
4539 };
4540
4541 // Prediction buffer from second frame.
4542#if CONFIG_VP9_HIGHBITDEPTH
4543 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[64 * 64]);
4544 uint8_t *second_pred;
4545#else
4546 DECLARE_ALIGNED(16, uint8_t, second_pred[64 * 64]);
4547#endif // CONFIG_VP9_HIGHBITDEPTH
4548
4549 for (ref = 0; ref < 2; ++ref) {
Yue Chen1ac85872016-01-07 15:13:52 -08004550#if CONFIG_EXT_INTER
4551 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
4552 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
4553 else
4554#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004555 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
4556
4557 if (scaled_ref_frame[ref]) {
4558 int i;
4559 // Swap out the reference frame for a version that's been scaled to
4560 // match the resolution of the current frame, allowing the existing
4561 // motion search code to be used without additional modifications.
4562 for (i = 0; i < MAX_MB_PLANE; i++)
4563 backup_yv12[ref][i] = xd->plane[i].pre[ref];
4564 vp10_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
4565 NULL);
4566 }
4567
4568 frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
4569 }
4570
4571 // Since we have scaled the reference frames to match the size of the current
4572 // frame we must use a unit scaling factor during mode selection.
4573#if CONFIG_VP9_HIGHBITDEPTH
4574 vp10_setup_scale_factors_for_frame(&sf, cm->width, cm->height,
Debargha Mukherjee85514c42015-10-30 09:19:36 -07004575 cm->width, cm->height,
4576 cm->use_highbitdepth);
Jingning Han3ee6db62015-08-05 19:00:31 -07004577#else
4578 vp10_setup_scale_factors_for_frame(&sf, cm->width, cm->height,
Debargha Mukherjee85514c42015-10-30 09:19:36 -07004579 cm->width, cm->height);
Jingning Han3ee6db62015-08-05 19:00:31 -07004580#endif // CONFIG_VP9_HIGHBITDEPTH
4581
4582 // Allow joint search multiple times iteratively for each reference frame
4583 // and break out of the search loop if it couldn't find a better mv.
4584 for (ite = 0; ite < 4; ite++) {
4585 struct buf_2d ref_yv12[2];
4586 int bestsme = INT_MAX;
4587 int sadpb = x->sadperbit16;
4588 MV tmp_mv;
4589 int search_range = 3;
4590
4591 int tmp_col_min = x->mv_col_min;
4592 int tmp_col_max = x->mv_col_max;
4593 int tmp_row_min = x->mv_row_min;
4594 int tmp_row_max = x->mv_row_max;
4595 int id = ite % 2; // Even iterations search in the first reference frame,
4596 // odd iterations search in the second. The predictor
4597 // found for the 'other' reference frame is factored in.
4598
4599 // Initialized here because of compiler problem in Visual Studio.
4600 ref_yv12[0] = xd->plane[0].pre[0];
4601 ref_yv12[1] = xd->plane[0].pre[1];
4602
4603 // Get the prediction block from the 'other' reference frame.
4604#if CONFIG_VP9_HIGHBITDEPTH
4605 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
4606 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
4607 vp10_highbd_build_inter_predictor(ref_yv12[!id].buf,
4608 ref_yv12[!id].stride,
4609 second_pred, pw,
4610 &frame_mv[refs[!id]].as_mv,
4611 &sf, pw, ph, 0,
Angie Chiang10ad97b2016-02-01 12:49:15 -08004612 interp_filter, MV_PRECISION_Q3,
Jingning Han3ee6db62015-08-05 19:00:31 -07004613 mi_col * MI_SIZE, mi_row * MI_SIZE,
4614 xd->bd);
4615 } else {
4616 second_pred = (uint8_t *)second_pred_alloc_16;
4617 vp10_build_inter_predictor(ref_yv12[!id].buf,
4618 ref_yv12[!id].stride,
4619 second_pred, pw,
4620 &frame_mv[refs[!id]].as_mv,
4621 &sf, pw, ph, 0,
Angie Chiang10ad97b2016-02-01 12:49:15 -08004622 interp_filter, MV_PRECISION_Q3,
Jingning Han3ee6db62015-08-05 19:00:31 -07004623 mi_col * MI_SIZE, mi_row * MI_SIZE);
4624 }
4625#else
4626 vp10_build_inter_predictor(ref_yv12[!id].buf,
4627 ref_yv12[!id].stride,
4628 second_pred, pw,
4629 &frame_mv[refs[!id]].as_mv,
4630 &sf, pw, ph, 0,
Angie Chiang10ad97b2016-02-01 12:49:15 -08004631 interp_filter, MV_PRECISION_Q3,
Jingning Han3ee6db62015-08-05 19:00:31 -07004632 mi_col * MI_SIZE, mi_row * MI_SIZE);
4633#endif // CONFIG_VP9_HIGHBITDEPTH
4634
4635 // Do compound motion search on the current reference frame.
4636 if (id)
4637 xd->plane[0].pre[0] = ref_yv12[id];
4638 vp10_set_mv_search_range(x, &ref_mv[id].as_mv);
4639
4640 // Use the mv result from the single mode as mv predictor.
4641 tmp_mv = frame_mv[refs[id]].as_mv;
4642
4643 tmp_mv.col >>= 3;
4644 tmp_mv.row >>= 3;
4645
Jingning Han03c01bc2016-02-19 10:41:04 -08004646#if CONFIG_REF_MV
4647 vp10_set_mvcost(x, refs[id]);
4648#endif
4649
Jingning Han3ee6db62015-08-05 19:00:31 -07004650 // Small-range full-pixel motion search.
4651 bestsme = vp10_refining_search_8p_c(x, &tmp_mv, sadpb,
4652 search_range,
4653 &cpi->fn_ptr[bsize],
4654 &ref_mv[id].as_mv, second_pred);
4655 if (bestsme < INT_MAX)
4656 bestsme = vp10_get_mvpred_av_var(x, &tmp_mv, &ref_mv[id].as_mv,
4657 second_pred, &cpi->fn_ptr[bsize], 1);
4658
4659 x->mv_col_min = tmp_col_min;
4660 x->mv_col_max = tmp_col_max;
4661 x->mv_row_min = tmp_row_min;
4662 x->mv_row_max = tmp_row_max;
4663
4664 if (bestsme < INT_MAX) {
4665 int dis; /* TODO: use dis in distortion calculation later. */
4666 unsigned int sse;
Yunqing Wange6e2d882016-03-10 11:07:50 -08004667 if (cpi->sf.use_upsampled_references) {
4668 // Use up-sampled reference frames.
4669 struct macroblockd_plane *const pd = &xd->plane[0];
4670 struct buf_2d backup_pred = pd->pre[0];
4671 const YV12_BUFFER_CONFIG *upsampled_ref =
4672 get_upsampled_ref(cpi, refs[id]);
Yunqing Wang342a3682016-02-16 14:33:18 -08004673
Yunqing Wange6e2d882016-03-10 11:07:50 -08004674 // Set pred for Y plane
4675 setup_pred_plane(&pd->pre[0], upsampled_ref->y_buffer,
4676 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3),
4677 NULL, pd->subsampling_x, pd->subsampling_y);
Yunqing Wang342a3682016-02-16 14:33:18 -08004678
Yunqing Wange6e2d882016-03-10 11:07:50 -08004679 // If bsize < BLOCK_8X8, adjust pred pointer for this block
4680 if (bsize < BLOCK_8X8)
4681 pd->pre[0].buf =
4682 &pd->pre[0].buf[(vp10_raster_block_offset(BLOCK_8X8, block,
4683 pd->pre[0].stride)) << 3];
Yunqing Wang342a3682016-02-16 14:33:18 -08004684
Yunqing Wange6e2d882016-03-10 11:07:50 -08004685 bestsme = cpi->find_fractional_mv_step(
4686 x, &tmp_mv,
4687 &ref_mv[id].as_mv,
4688 cpi->common.allow_high_precision_mv,
4689 x->errorperbit,
4690 &cpi->fn_ptr[bsize],
4691 0, cpi->sf.mv.subpel_iters_per_step,
4692 NULL,
4693 x->nmvjointcost, x->mvcost,
4694 &dis, &sse, second_pred,
4695 pw, ph, 1);
Yunqing Wang342a3682016-02-16 14:33:18 -08004696
Yunqing Wange6e2d882016-03-10 11:07:50 -08004697 // Restore the reference frames.
4698 pd->pre[0] = backup_pred;
4699 } else {
4700 (void) block;
4701 bestsme = cpi->find_fractional_mv_step(
4702 x, &tmp_mv,
4703 &ref_mv[id].as_mv,
4704 cpi->common.allow_high_precision_mv,
4705 x->errorperbit,
4706 &cpi->fn_ptr[bsize],
4707 0, cpi->sf.mv.subpel_iters_per_step,
4708 NULL,
4709 x->nmvjointcost, x->mvcost,
4710 &dis, &sse, second_pred,
4711 pw, ph, 0);
4712 }
Jingning Han3ee6db62015-08-05 19:00:31 -07004713 }
4714
4715 // Restore the pointer to the first (possibly scaled) prediction buffer.
4716 if (id)
4717 xd->plane[0].pre[0] = ref_yv12[0];
4718
4719 if (bestsme < last_besterr[id]) {
4720 frame_mv[refs[id]].as_mv = tmp_mv;
4721 last_besterr[id] = bestsme;
4722 } else {
4723 break;
4724 }
4725 }
4726
4727 *rate_mv = 0;
4728
4729 for (ref = 0; ref < 2; ++ref) {
4730 if (scaled_ref_frame[ref]) {
4731 // Restore the prediction frame pointers to their unscaled versions.
4732 int i;
4733 for (i = 0; i < MAX_MB_PLANE; i++)
4734 xd->plane[i].pre[ref] = backup_yv12[ref][i];
4735 }
4736
Yue Chen1ac85872016-01-07 15:13:52 -08004737#if CONFIG_EXT_INTER
4738 if (bsize >= BLOCK_8X8)
4739#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004740 *rate_mv += vp10_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08004741 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
4742 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yue Chen1ac85872016-01-07 15:13:52 -08004743#if CONFIG_EXT_INTER
4744 else
4745 *rate_mv += vp10_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
4746 &ref_mv_sub8x8[ref]->as_mv,
4747 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
4748#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004749 }
4750}
4751
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004752static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07004753 int_mv *best_ref_mv,
4754 int_mv *second_best_ref_mv,
4755 int64_t best_rd, int *returntotrate,
4756 int *returnyrate,
4757 int64_t *returndistortion,
4758 int *skippable, int64_t *psse,
4759 int mvthresh,
Yue Chen1ac85872016-01-07 15:13:52 -08004760#if CONFIG_EXT_INTER
4761 int_mv seg_mvs[4][2][MAX_REF_FRAMES],
4762 int_mv compound_seg_newmvs[4][2],
4763#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004764 int_mv seg_mvs[4][MAX_REF_FRAMES],
Yue Chen1ac85872016-01-07 15:13:52 -08004765#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004766 BEST_SEG_INFO *bsi_buf, int filter_idx,
4767 int mi_row, int mi_col) {
4768 int i;
4769 BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
4770 MACROBLOCKD *xd = &x->e_mbd;
4771 MODE_INFO *mi = xd->mi[0];
4772 MB_MODE_INFO *mbmi = &mi->mbmi;
4773 int mode_idx;
4774 int k, br = 0, idx, idy;
4775 int64_t bd = 0, block_sse = 0;
4776 PREDICTION_MODE this_mode;
Yaowu Xufc7cbd12015-08-13 09:36:53 -07004777 VP10_COMMON *cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07004778 struct macroblock_plane *const p = &x->plane[0];
4779 struct macroblockd_plane *const pd = &xd->plane[0];
4780 const int label_count = 4;
4781 int64_t this_segment_rd = 0;
4782 int label_mv_thresh;
4783 int segmentyrate = 0;
4784 const BLOCK_SIZE bsize = mbmi->sb_type;
4785 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
4786 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
4787 ENTROPY_CONTEXT t_above[2], t_left[2];
4788 int subpelmv = 1, have_ref = 0;
4789 const int has_second_rf = has_second_ref(mbmi);
4790 const int inter_mode_mask = cpi->sf.inter_mode_mask[bsize];
4791 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4792
4793 vp10_zero(*bsi);
4794
4795 bsi->segment_rd = best_rd;
4796 bsi->ref_mv[0] = best_ref_mv;
4797 bsi->ref_mv[1] = second_best_ref_mv;
4798 bsi->mvp.as_int = best_ref_mv->as_int;
4799 bsi->mvthresh = mvthresh;
4800
4801 for (i = 0; i < 4; i++)
4802 bsi->modes[i] = ZEROMV;
4803
4804 memcpy(t_above, pd->above_context, sizeof(t_above));
4805 memcpy(t_left, pd->left_context, sizeof(t_left));
4806
4807 // 64 makes this threshold really big effectively
4808 // making it so that we very rarely check mvs on
4809 // segments. setting this to 1 would make mv thresh
4810 // roughly equal to what it is for macroblocks
4811 label_mv_thresh = 1 * bsi->mvthresh / label_count;
4812
4813 // Segmentation method overheads
4814 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
4815 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
4816 // TODO(jingning,rbultje): rewrite the rate-distortion optimization
4817 // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
4818 int_mv mode_mv[MB_MODE_COUNT][2];
4819 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
4820 PREDICTION_MODE mode_selected = ZEROMV;
4821 int64_t best_rd = INT64_MAX;
4822 const int i = idy * 2 + idx;
4823 int ref;
Yue Chen1ac85872016-01-07 15:13:52 -08004824#if CONFIG_EXT_INTER
4825 int mv_idx;
4826 int_mv ref_mvs_sub8x8[2][2];
4827#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004828
4829 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
4830 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
Yue Chen1ac85872016-01-07 15:13:52 -08004831#if CONFIG_EXT_INTER
4832 int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
4833 vp10_update_mv_context(cm, xd, mi, frame, mv_ref_list, i,
4834 mi_row, mi_col, NULL);
4835#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004836 frame_mv[ZEROMV][frame].as_int = 0;
4837 vp10_append_sub8x8_mvs_for_idx(cm, xd, i, ref, mi_row, mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08004838#if CONFIG_EXT_INTER
4839 mv_ref_list,
4840#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004841 &frame_mv[NEARESTMV][frame],
Jingning Han40cedd62015-11-25 13:42:59 -08004842 &frame_mv[NEARMV][frame]);
Yue Chen1ac85872016-01-07 15:13:52 -08004843#if CONFIG_EXT_INTER
4844 mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
4845 mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
4846 vp10_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
4847 &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
Yue Chen968bbc72016-01-19 16:45:45 -08004848
4849 if (has_second_rf) {
4850 frame_mv[ZERO_ZEROMV][frame].as_int = 0;
4851 frame_mv[NEAREST_NEARESTMV][frame].as_int =
4852 frame_mv[NEARESTMV][frame].as_int;
4853
4854 if (ref == 0) {
4855 frame_mv[NEAREST_NEARMV][frame].as_int =
4856 frame_mv[NEARESTMV][frame].as_int;
4857 frame_mv[NEAR_NEARESTMV][frame].as_int =
4858 frame_mv[NEARMV][frame].as_int;
4859 frame_mv[NEAREST_NEWMV][frame].as_int =
4860 frame_mv[NEARESTMV][frame].as_int;
4861 frame_mv[NEAR_NEWMV][frame].as_int =
4862 frame_mv[NEARMV][frame].as_int;
4863 } else if (ref == 1) {
4864 frame_mv[NEAREST_NEARMV][frame].as_int =
4865 frame_mv[NEARMV][frame].as_int;
4866 frame_mv[NEAR_NEARESTMV][frame].as_int =
4867 frame_mv[NEARESTMV][frame].as_int;
4868 frame_mv[NEW_NEARESTMV][frame].as_int =
4869 frame_mv[NEARESTMV][frame].as_int;
4870 frame_mv[NEW_NEARMV][frame].as_int =
4871 frame_mv[NEARMV][frame].as_int;
4872 }
4873 }
Yue Chen1ac85872016-01-07 15:13:52 -08004874#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004875 }
4876
4877 // search for the best motion vector on this segment
Yue Chen1ac85872016-01-07 15:13:52 -08004878#if CONFIG_EXT_INTER
Yue Chen968bbc72016-01-19 16:45:45 -08004879 for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
4880 this_mode <= (has_second_rf ? NEW_NEWMV : NEWFROMNEARMV);
4881 ++this_mode) {
Yue Chen1ac85872016-01-07 15:13:52 -08004882#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004883 for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
Yue Chen1ac85872016-01-07 15:13:52 -08004884#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004885 const struct buf_2d orig_src = x->plane[0].src;
4886 struct buf_2d orig_pre[2];
4887
4888 mode_idx = INTER_OFFSET(this_mode);
Yue Chen1ac85872016-01-07 15:13:52 -08004889#if CONFIG_EXT_INTER
4890 mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
Yue Chen968bbc72016-01-19 16:45:45 -08004891
Yue Chen1ac85872016-01-07 15:13:52 -08004892 for (ref = 0; ref < 1 + has_second_rf; ++ref)
4893 bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[mv_idx][ref].as_int;
4894#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004895 bsi->rdstat[i][mode_idx].brdcost = INT64_MAX;
4896 if (!(inter_mode_mask & (1 << this_mode)))
4897 continue;
4898
Yue Chen968bbc72016-01-19 16:45:45 -08004899 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
4900#if CONFIG_REF_MV && CONFIG_EXT_INTER
4901 mbmi_ext->compound_mode_context,
4902#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4903 frame_mv,
Jingning Han387a10e2015-12-09 09:07:39 -08004904 this_mode, mbmi->ref_frame, bsize, i))
Jingning Han3ee6db62015-08-05 19:00:31 -07004905 continue;
4906
4907 memcpy(orig_pre, pd->pre, sizeof(orig_pre));
4908 memcpy(bsi->rdstat[i][mode_idx].ta, t_above,
4909 sizeof(bsi->rdstat[i][mode_idx].ta));
4910 memcpy(bsi->rdstat[i][mode_idx].tl, t_left,
4911 sizeof(bsi->rdstat[i][mode_idx].tl));
4912
4913 // motion search for newmv (single predictor case only)
Yue Chen1ac85872016-01-07 15:13:52 -08004914 if (!has_second_rf &&
4915#if CONFIG_EXT_INTER
4916 have_newmv_in_inter_mode(this_mode) &&
4917 seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV
4918#else
4919 this_mode == NEWMV &&
4920 seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV
4921#endif // CONFIG_EXT_INTER
4922 ) {
4923#if CONFIG_EXT_INTER
4924 MV *const new_mv = &mode_mv[this_mode][0].as_mv;
4925#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004926 MV *const new_mv = &mode_mv[NEWMV][0].as_mv;
Yue Chen1ac85872016-01-07 15:13:52 -08004927#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004928 int step_param = 0;
paulwilkins4e692bb2015-12-08 15:48:24 +00004929 int bestsme = INT_MAX;
Jingning Han3ee6db62015-08-05 19:00:31 -07004930 int sadpb = x->sadperbit4;
4931 MV mvp_full;
4932 int max_mv;
4933 int cost_list[5];
4934
4935 /* Is the best so far sufficiently good that we cant justify doing
4936 * and new motion search. */
4937 if (best_rd < label_mv_thresh)
4938 break;
4939
4940 if (cpi->oxcf.mode != BEST) {
Yue Chen1ac85872016-01-07 15:13:52 -08004941#if CONFIG_EXT_INTER
4942 bsi->mvp.as_int = bsi->ref_mv[0]->as_int;
4943#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004944 // use previous block's result as next block's MV predictor.
4945 if (i > 0) {
4946 bsi->mvp.as_int = mi->bmi[i - 1].as_mv[0].as_int;
4947 if (i == 2)
4948 bsi->mvp.as_int = mi->bmi[i - 2].as_mv[0].as_int;
4949 }
Yue Chen1ac85872016-01-07 15:13:52 -08004950#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004951 }
4952 if (i == 0)
4953 max_mv = x->max_mv_context[mbmi->ref_frame[0]];
4954 else
James Zern5e16d392015-08-17 18:19:22 -07004955 max_mv =
4956 VPXMAX(abs(bsi->mvp.as_mv.row), abs(bsi->mvp.as_mv.col)) >> 3;
Jingning Han3ee6db62015-08-05 19:00:31 -07004957
4958 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
4959 // Take wtd average of the step_params based on the last frame's
4960 // max mv magnitude and the best ref mvs of the current block for
4961 // the given reference.
4962 step_param = (vp10_init_search_range(max_mv) +
4963 cpi->mv_step_param) / 2;
4964 } else {
4965 step_param = cpi->mv_step_param;
4966 }
4967
4968 mvp_full.row = bsi->mvp.as_mv.row >> 3;
4969 mvp_full.col = bsi->mvp.as_mv.col >> 3;
4970
4971 if (cpi->sf.adaptive_motion_search) {
4972 mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
4973 mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
James Zern5e16d392015-08-17 18:19:22 -07004974 step_param = VPXMAX(step_param, 8);
Jingning Han3ee6db62015-08-05 19:00:31 -07004975 }
4976
4977 // adjust src pointer for this block
4978 mi_buf_shift(x, i);
4979
4980 vp10_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
4981
Jingning Han03c01bc2016-02-19 10:41:04 -08004982#if CONFIG_REF_MV
4983 vp10_set_mvcost(x, mbmi->ref_frame[0]);
4984#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07004985 bestsme = vp10_full_pixel_search(
4986 cpi, x, bsize, &mvp_full, step_param, sadpb,
4987 cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
4988 &bsi->ref_mv[0]->as_mv, new_mv,
4989 INT_MAX, 1);
4990
Jingning Han3ee6db62015-08-05 19:00:31 -07004991 if (bestsme < INT_MAX) {
4992 int distortion;
Yunqing Wange6e2d882016-03-10 11:07:50 -08004993 if (cpi->sf.use_upsampled_references) {
4994 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
4995 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
4996 // Use up-sampled reference frames.
4997 struct macroblockd_plane *const pd = &xd->plane[0];
4998 struct buf_2d backup_pred = pd->pre[0];
4999 const YV12_BUFFER_CONFIG *upsampled_ref =
5000 get_upsampled_ref(cpi, mbmi->ref_frame[0]);
Yunqing Wang342a3682016-02-16 14:33:18 -08005001
Yunqing Wange6e2d882016-03-10 11:07:50 -08005002 // Set pred for Y plane
5003 setup_pred_plane(&pd->pre[0], upsampled_ref->y_buffer,
5004 upsampled_ref->y_stride,
5005 (mi_row << 3), (mi_col << 3),
5006 NULL, pd->subsampling_x, pd->subsampling_y);
Yunqing Wang342a3682016-02-16 14:33:18 -08005007
Yunqing Wange6e2d882016-03-10 11:07:50 -08005008 // adjust pred pointer for this block
5009 pd->pre[0].buf =
5010 &pd->pre[0].buf[(vp10_raster_block_offset(BLOCK_8X8, i,
5011 pd->pre[0].stride)) << 3];
Yunqing Wang342a3682016-02-16 14:33:18 -08005012
Yunqing Wange6e2d882016-03-10 11:07:50 -08005013 cpi->find_fractional_mv_step(
5014 x,
5015 new_mv,
5016 &bsi->ref_mv[0]->as_mv,
5017 cm->allow_high_precision_mv,
5018 x->errorperbit, &cpi->fn_ptr[bsize],
5019 cpi->sf.mv.subpel_force_stop,
5020 cpi->sf.mv.subpel_iters_per_step,
5021 cond_cost_list(cpi, cost_list),
5022 x->nmvjointcost, x->mvcost,
5023 &distortion,
5024 &x->pred_sse[mbmi->ref_frame[0]],
5025 NULL, pw, ph, 1);
Yunqing Wang342a3682016-02-16 14:33:18 -08005026
Yunqing Wange6e2d882016-03-10 11:07:50 -08005027 // Restore the reference frames.
5028 pd->pre[0] = backup_pred;
5029 } else {
5030 cpi->find_fractional_mv_step(
5031 x,
5032 new_mv,
5033 &bsi->ref_mv[0]->as_mv,
5034 cm->allow_high_precision_mv,
5035 x->errorperbit, &cpi->fn_ptr[bsize],
5036 cpi->sf.mv.subpel_force_stop,
5037 cpi->sf.mv.subpel_iters_per_step,
5038 cond_cost_list(cpi, cost_list),
5039 x->nmvjointcost, x->mvcost,
5040 &distortion,
5041 &x->pred_sse[mbmi->ref_frame[0]],
5042 NULL, 0, 0, 0);
5043 }
Jingning Han3ee6db62015-08-05 19:00:31 -07005044
5045 // save motion search result for use in compound prediction
Yue Chen1ac85872016-01-07 15:13:52 -08005046#if CONFIG_EXT_INTER
5047 seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_mv = *new_mv;
5048#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005049 seg_mvs[i][mbmi->ref_frame[0]].as_mv = *new_mv;
Yue Chen1ac85872016-01-07 15:13:52 -08005050#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005051 }
5052
5053 if (cpi->sf.adaptive_motion_search)
5054 x->pred_mv[mbmi->ref_frame[0]] = *new_mv;
5055
5056 // restore src pointers
5057 mi_buf_restore(x, orig_src, orig_pre);
5058 }
5059
5060 if (has_second_rf) {
Yue Chen1ac85872016-01-07 15:13:52 -08005061#if CONFIG_EXT_INTER
5062 if (seg_mvs[i][mv_idx][mbmi->ref_frame[1]].as_int == INVALID_MV ||
5063 seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
5064#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005065 if (seg_mvs[i][mbmi->ref_frame[1]].as_int == INVALID_MV ||
5066 seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yue Chen1ac85872016-01-07 15:13:52 -08005067#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005068 continue;
5069 }
5070
Yue Chen968bbc72016-01-19 16:45:45 -08005071 if (has_second_rf &&
5072#if CONFIG_EXT_INTER
5073 this_mode == NEW_NEWMV &&
5074#else
5075 this_mode == NEWMV &&
5076#endif // CONFIG_EXT_INTER
Debargha Mukherjeebab29122016-02-26 00:18:03 -08005077 mbmi->interp_filter == EIGHTTAP_REGULAR) {
Jingning Han3ee6db62015-08-05 19:00:31 -07005078 // adjust src pointers
5079 mi_buf_shift(x, i);
5080 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
5081 int rate_mv;
5082 joint_motion_search(cpi, x, bsize, frame_mv[this_mode],
Yue Chen1ac85872016-01-07 15:13:52 -08005083 mi_row, mi_col,
5084#if CONFIG_EXT_INTER
5085 bsi->ref_mv,
5086 seg_mvs[i][mv_idx],
5087#else
5088 seg_mvs[i],
5089#endif // CONFIG_EXT_INTER
Yunqing Wang342a3682016-02-16 14:33:18 -08005090 &rate_mv, i);
Yue Chen1ac85872016-01-07 15:13:52 -08005091#if CONFIG_EXT_INTER
5092 compound_seg_newmvs[i][0].as_int =
5093 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
5094 compound_seg_newmvs[i][1].as_int =
5095 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
5096#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005097 seg_mvs[i][mbmi->ref_frame[0]].as_int =
5098 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
5099 seg_mvs[i][mbmi->ref_frame[1]].as_int =
5100 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08005101#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005102 }
5103 // restore src pointers
5104 mi_buf_restore(x, orig_src, orig_pre);
5105 }
5106
5107 bsi->rdstat[i][mode_idx].brate =
5108 set_and_cost_bmi_mvs(cpi, x, xd, i, this_mode, mode_mv[this_mode],
Yue Chen1ac85872016-01-07 15:13:52 -08005109 frame_mv,
5110#if CONFIG_EXT_INTER
5111 seg_mvs[i][mv_idx],
5112 compound_seg_newmvs[i],
5113#else
5114 seg_mvs[i],
5115#endif // CONFIG_EXT_INTER
5116 bsi->ref_mv,
Jingning Han3ee6db62015-08-05 19:00:31 -07005117 x->nmvjointcost, x->mvcost);
5118
5119 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5120 bsi->rdstat[i][mode_idx].mvs[ref].as_int =
5121 mode_mv[this_mode][ref].as_int;
5122 if (num_4x4_blocks_wide > 1)
5123 bsi->rdstat[i + 1][mode_idx].mvs[ref].as_int =
5124 mode_mv[this_mode][ref].as_int;
5125 if (num_4x4_blocks_high > 1)
5126 bsi->rdstat[i + 2][mode_idx].mvs[ref].as_int =
5127 mode_mv[this_mode][ref].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08005128#if CONFIG_EXT_INTER
5129 bsi->rdstat[i][mode_idx].ref_mv[ref].as_int =
5130 bsi->ref_mv[ref]->as_int;
5131 if (num_4x4_blocks_wide > 1)
5132 bsi->rdstat[i + 1][mode_idx].ref_mv[ref].as_int =
5133 bsi->ref_mv[ref]->as_int;
5134 if (num_4x4_blocks_high > 1)
5135 bsi->rdstat[i + 2][mode_idx].ref_mv[ref].as_int =
5136 bsi->ref_mv[ref]->as_int;
5137#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005138 }
5139
5140 // Trap vectors that reach beyond the UMV borders
5141 if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
5142 (has_second_rf &&
5143 mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
5144 continue;
5145
5146 if (filter_idx > 0) {
5147 BEST_SEG_INFO *ref_bsi = bsi_buf;
5148 subpelmv = 0;
5149 have_ref = 1;
5150
5151 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5152 subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
Yue Chen1ac85872016-01-07 15:13:52 -08005153#if CONFIG_EXT_INTER
5154 if (have_newmv_in_inter_mode(this_mode))
5155 have_ref &= (
5156 (mode_mv[this_mode][ref].as_int ==
5157 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int) &&
5158 (bsi->ref_mv[ref]->as_int ==
5159 ref_bsi->rdstat[i][mode_idx].ref_mv[ref].as_int));
5160 else
5161#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005162 have_ref &= mode_mv[this_mode][ref].as_int ==
5163 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
5164 }
5165
5166 if (filter_idx > 1 && !subpelmv && !have_ref) {
5167 ref_bsi = bsi_buf + 1;
5168 have_ref = 1;
5169 for (ref = 0; ref < 1 + has_second_rf; ++ref)
Yue Chen1ac85872016-01-07 15:13:52 -08005170#if CONFIG_EXT_INTER
5171 if (have_newmv_in_inter_mode(this_mode))
5172 have_ref &= (
5173 (mode_mv[this_mode][ref].as_int ==
5174 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int) &&
5175 (bsi->ref_mv[ref]->as_int ==
5176 ref_bsi->rdstat[i][mode_idx].ref_mv[ref].as_int));
5177 else
5178#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005179 have_ref &= mode_mv[this_mode][ref].as_int ==
5180 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
5181 }
5182
5183 if (!subpelmv && have_ref &&
5184 ref_bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) {
5185 memcpy(&bsi->rdstat[i][mode_idx], &ref_bsi->rdstat[i][mode_idx],
5186 sizeof(SEG_RDSTAT));
5187 if (num_4x4_blocks_wide > 1)
5188 bsi->rdstat[i + 1][mode_idx].eobs =
5189 ref_bsi->rdstat[i + 1][mode_idx].eobs;
5190 if (num_4x4_blocks_high > 1)
5191 bsi->rdstat[i + 2][mode_idx].eobs =
5192 ref_bsi->rdstat[i + 2][mode_idx].eobs;
5193
5194 if (bsi->rdstat[i][mode_idx].brdcost < best_rd) {
5195 mode_selected = this_mode;
5196 best_rd = bsi->rdstat[i][mode_idx].brdcost;
5197 }
5198 continue;
5199 }
5200 }
5201
5202 bsi->rdstat[i][mode_idx].brdcost =
5203 encode_inter_mb_segment(cpi, x,
5204 bsi->segment_rd - this_segment_rd, i,
5205 &bsi->rdstat[i][mode_idx].byrate,
5206 &bsi->rdstat[i][mode_idx].bdist,
5207 &bsi->rdstat[i][mode_idx].bsse,
5208 bsi->rdstat[i][mode_idx].ta,
5209 bsi->rdstat[i][mode_idx].tl,
Yaowu Xu7c514e22015-09-28 15:55:46 -07005210 idy, idx,
Jingning Han3ee6db62015-08-05 19:00:31 -07005211 mi_row, mi_col);
5212 if (bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) {
5213 bsi->rdstat[i][mode_idx].brdcost += RDCOST(x->rdmult, x->rddiv,
5214 bsi->rdstat[i][mode_idx].brate, 0);
5215 bsi->rdstat[i][mode_idx].brate += bsi->rdstat[i][mode_idx].byrate;
5216 bsi->rdstat[i][mode_idx].eobs = p->eobs[i];
5217 if (num_4x4_blocks_wide > 1)
5218 bsi->rdstat[i + 1][mode_idx].eobs = p->eobs[i + 1];
5219 if (num_4x4_blocks_high > 1)
5220 bsi->rdstat[i + 2][mode_idx].eobs = p->eobs[i + 2];
5221 }
5222
5223 if (bsi->rdstat[i][mode_idx].brdcost < best_rd) {
5224 mode_selected = this_mode;
5225 best_rd = bsi->rdstat[i][mode_idx].brdcost;
5226 }
5227 } /*for each 4x4 mode*/
5228
5229 if (best_rd == INT64_MAX) {
5230 int iy, midx;
5231 for (iy = i + 1; iy < 4; ++iy)
Yue Chen968bbc72016-01-19 16:45:45 -08005232#if CONFIG_EXT_INTER
5233 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
5234#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005235 for (midx = 0; midx < INTER_MODES; ++midx)
Yue Chen968bbc72016-01-19 16:45:45 -08005236#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005237 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
5238 bsi->segment_rd = INT64_MAX;
5239 return INT64_MAX;
5240 }
5241
5242 mode_idx = INTER_OFFSET(mode_selected);
5243 memcpy(t_above, bsi->rdstat[i][mode_idx].ta, sizeof(t_above));
5244 memcpy(t_left, bsi->rdstat[i][mode_idx].tl, sizeof(t_left));
5245
Yue Chen1ac85872016-01-07 15:13:52 -08005246#if CONFIG_EXT_INTER
5247 mv_idx = (mode_selected == NEWFROMNEARMV) ? 1 : 0;
5248 bsi->ref_mv[0]->as_int = bsi->rdstat[i][mode_idx].ref_mv[0].as_int;
5249 if (has_second_rf)
5250 bsi->ref_mv[1]->as_int = bsi->rdstat[i][mode_idx].ref_mv[1].as_int;
5251#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005252 set_and_cost_bmi_mvs(cpi, x, xd, i, mode_selected, mode_mv[mode_selected],
Yue Chen1ac85872016-01-07 15:13:52 -08005253 frame_mv,
5254#if CONFIG_EXT_INTER
5255 seg_mvs[i][mv_idx],
5256 compound_seg_newmvs[i],
5257#else
5258 seg_mvs[i],
5259#endif // CONFIG_EXT_INTER
5260 bsi->ref_mv, x->nmvjointcost, x->mvcost);
Jingning Han3ee6db62015-08-05 19:00:31 -07005261
5262 br += bsi->rdstat[i][mode_idx].brate;
5263 bd += bsi->rdstat[i][mode_idx].bdist;
5264 block_sse += bsi->rdstat[i][mode_idx].bsse;
5265 segmentyrate += bsi->rdstat[i][mode_idx].byrate;
5266 this_segment_rd += bsi->rdstat[i][mode_idx].brdcost;
5267
5268 if (this_segment_rd > bsi->segment_rd) {
5269 int iy, midx;
5270 for (iy = i + 1; iy < 4; ++iy)
Yue Chen968bbc72016-01-19 16:45:45 -08005271#if CONFIG_EXT_INTER
5272 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
5273#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005274 for (midx = 0; midx < INTER_MODES; ++midx)
Yue Chen968bbc72016-01-19 16:45:45 -08005275#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005276 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
5277 bsi->segment_rd = INT64_MAX;
5278 return INT64_MAX;
5279 }
5280 }
5281 } /* for each label */
5282
5283 bsi->r = br;
5284 bsi->d = bd;
5285 bsi->segment_yrate = segmentyrate;
5286 bsi->segment_rd = this_segment_rd;
5287 bsi->sse = block_sse;
5288
5289 // update the coding decisions
5290 for (k = 0; k < 4; ++k)
5291 bsi->modes[k] = mi->bmi[k].as_mode;
5292
5293 if (bsi->segment_rd > best_rd)
5294 return INT64_MAX;
5295 /* set it to the best */
5296 for (i = 0; i < 4; i++) {
5297 mode_idx = INTER_OFFSET(bsi->modes[i]);
5298 mi->bmi[i].as_mv[0].as_int = bsi->rdstat[i][mode_idx].mvs[0].as_int;
5299 if (has_second_ref(mbmi))
5300 mi->bmi[i].as_mv[1].as_int = bsi->rdstat[i][mode_idx].mvs[1].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08005301#if CONFIG_EXT_INTER
5302 mi->bmi[i].ref_mv[0].as_int = bsi->rdstat[i][mode_idx].ref_mv[0].as_int;
5303 if (has_second_rf)
5304 mi->bmi[i].ref_mv[1].as_int = bsi->rdstat[i][mode_idx].ref_mv[1].as_int;
5305#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005306 x->plane[0].eobs[i] = bsi->rdstat[i][mode_idx].eobs;
5307 mi->bmi[i].as_mode = bsi->modes[i];
5308 }
5309
5310 /*
5311 * used to set mbmi->mv.as_int
5312 */
5313 *returntotrate = bsi->r;
5314 *returndistortion = bsi->d;
5315 *returnyrate = bsi->segment_yrate;
5316 *skippable = vp10_is_skippable_in_plane(x, BLOCK_8X8, 0);
5317 *psse = bsi->sse;
5318 mbmi->mode = bsi->modes[3];
5319
5320 return bsi->segment_rd;
5321}
5322
Yaowu Xufc7cbd12015-08-13 09:36:53 -07005323static void estimate_ref_frame_costs(const VP10_COMMON *cm,
Jingning Han3ee6db62015-08-05 19:00:31 -07005324 const MACROBLOCKD *xd,
5325 int segment_id,
5326 unsigned int *ref_costs_single,
5327 unsigned int *ref_costs_comp,
5328 vpx_prob *comp_mode_p) {
5329 int seg_ref_active = segfeature_active(&cm->seg, segment_id,
5330 SEG_LVL_REF_FRAME);
5331 if (seg_ref_active) {
5332 memset(ref_costs_single, 0, MAX_REF_FRAMES * sizeof(*ref_costs_single));
5333 memset(ref_costs_comp, 0, MAX_REF_FRAMES * sizeof(*ref_costs_comp));
5334 *comp_mode_p = 128;
5335 } else {
5336 vpx_prob intra_inter_p = vp10_get_intra_inter_prob(cm, xd);
5337 vpx_prob comp_inter_p = 128;
5338
5339 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
5340 comp_inter_p = vp10_get_reference_mode_prob(cm, xd);
5341 *comp_mode_p = comp_inter_p;
5342 } else {
5343 *comp_mode_p = 128;
5344 }
5345
5346 ref_costs_single[INTRA_FRAME] = vp10_cost_bit(intra_inter_p, 0);
5347
5348 if (cm->reference_mode != COMPOUND_REFERENCE) {
5349 vpx_prob ref_single_p1 = vp10_get_pred_prob_single_ref_p1(cm, xd);
5350 vpx_prob ref_single_p2 = vp10_get_pred_prob_single_ref_p2(cm, xd);
Zoe Liu3ec16012015-11-12 02:12:17 -08005351#if CONFIG_EXT_REFS
5352 vpx_prob ref_single_p3 = vp10_get_pred_prob_single_ref_p3(cm, xd);
5353 vpx_prob ref_single_p4 = vp10_get_pred_prob_single_ref_p4(cm, xd);
5354 vpx_prob ref_single_p5 = vp10_get_pred_prob_single_ref_p5(cm, xd);
5355#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07005356 unsigned int base_cost = vp10_cost_bit(intra_inter_p, 1);
5357
Zoe Liu3ec16012015-11-12 02:12:17 -08005358 ref_costs_single[LAST_FRAME] =
5359#if CONFIG_EXT_REFS
5360 ref_costs_single[LAST2_FRAME] =
5361 ref_costs_single[LAST3_FRAME] =
5362 ref_costs_single[LAST4_FRAME] =
5363#endif // CONFIG_EXT_REFS
5364 ref_costs_single[GOLDEN_FRAME] =
Jingning Han3ee6db62015-08-05 19:00:31 -07005365 ref_costs_single[ALTREF_FRAME] = base_cost;
Zoe Liu3ec16012015-11-12 02:12:17 -08005366
5367#if CONFIG_EXT_REFS
5368 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p1, 0);
5369 ref_costs_single[LAST2_FRAME] += vp10_cost_bit(ref_single_p1, 0);
5370 ref_costs_single[LAST3_FRAME] += vp10_cost_bit(ref_single_p1, 0);
5371 ref_costs_single[LAST4_FRAME] += vp10_cost_bit(ref_single_p1, 0);
5372 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p1, 1);
5373 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p1, 1);
5374
5375 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p3, 0);
5376 ref_costs_single[LAST2_FRAME] += vp10_cost_bit(ref_single_p3, 0);
5377 ref_costs_single[LAST3_FRAME] += vp10_cost_bit(ref_single_p3, 1);
5378 ref_costs_single[LAST4_FRAME] += vp10_cost_bit(ref_single_p3, 1);
5379 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p2, 0);
5380 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p2, 1);
5381
5382 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p4, 0);
5383 ref_costs_single[LAST2_FRAME] += vp10_cost_bit(ref_single_p4, 1);
5384 ref_costs_single[LAST3_FRAME] += vp10_cost_bit(ref_single_p5, 0);
5385 ref_costs_single[LAST4_FRAME] += vp10_cost_bit(ref_single_p5, 1);
5386#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005387 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p1, 0);
5388 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p1, 1);
5389 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p1, 1);
5390 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p2, 0);
5391 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p2, 1);
Zoe Liu3ec16012015-11-12 02:12:17 -08005392#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07005393 } else {
5394 ref_costs_single[LAST_FRAME] = 512;
Zoe Liu3ec16012015-11-12 02:12:17 -08005395#if CONFIG_EXT_REFS
5396 ref_costs_single[LAST2_FRAME] = 512;
5397 ref_costs_single[LAST3_FRAME] = 512;
5398 ref_costs_single[LAST4_FRAME] = 512;
5399#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07005400 ref_costs_single[GOLDEN_FRAME] = 512;
5401 ref_costs_single[ALTREF_FRAME] = 512;
5402 }
Zoe Liu3ec16012015-11-12 02:12:17 -08005403
Jingning Han3ee6db62015-08-05 19:00:31 -07005404 if (cm->reference_mode != SINGLE_REFERENCE) {
5405 vpx_prob ref_comp_p = vp10_get_pred_prob_comp_ref_p(cm, xd);
Zoe Liu3ec16012015-11-12 02:12:17 -08005406#if CONFIG_EXT_REFS
5407 vpx_prob ref_comp_p1 = vp10_get_pred_prob_comp_ref_p1(cm, xd);
5408 vpx_prob ref_comp_p2 = vp10_get_pred_prob_comp_ref_p2(cm, xd);
5409 vpx_prob ref_comp_p3 = vp10_get_pred_prob_comp_ref_p3(cm, xd);
5410#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07005411 unsigned int base_cost = vp10_cost_bit(intra_inter_p, 1);
5412
Zoe Liu3ec16012015-11-12 02:12:17 -08005413 ref_costs_comp[LAST_FRAME] =
5414#if CONFIG_EXT_REFS
5415 ref_costs_comp[LAST2_FRAME] =
5416 ref_costs_comp[LAST3_FRAME] =
5417 ref_costs_comp[LAST4_FRAME] =
5418#endif // CONFIG_EXT_REFS
5419 ref_costs_comp[GOLDEN_FRAME] = base_cost;
5420
5421#if CONFIG_EXT_REFS
5422 ref_costs_comp[LAST_FRAME] += vp10_cost_bit(ref_comp_p, 0);
5423 ref_costs_comp[LAST2_FRAME] += vp10_cost_bit(ref_comp_p, 0);
5424 ref_costs_comp[LAST3_FRAME] += vp10_cost_bit(ref_comp_p, 1);
5425 ref_costs_comp[LAST4_FRAME] += vp10_cost_bit(ref_comp_p, 1);
5426 ref_costs_comp[GOLDEN_FRAME] += vp10_cost_bit(ref_comp_p, 1);
5427
5428 ref_costs_comp[LAST_FRAME] += vp10_cost_bit(ref_comp_p1, 1);
5429 ref_costs_comp[LAST2_FRAME] += vp10_cost_bit(ref_comp_p1, 0);
5430 ref_costs_comp[LAST3_FRAME] += vp10_cost_bit(ref_comp_p2, 0);
5431 ref_costs_comp[LAST4_FRAME] += vp10_cost_bit(ref_comp_p2, 0);
5432 ref_costs_comp[GOLDEN_FRAME] += vp10_cost_bit(ref_comp_p2, 1);
5433
5434 ref_costs_comp[LAST3_FRAME] += vp10_cost_bit(ref_comp_p3, 1);
5435 ref_costs_comp[LAST4_FRAME] += vp10_cost_bit(ref_comp_p3, 0);
5436#else
5437 ref_costs_comp[LAST_FRAME] += vp10_cost_bit(ref_comp_p, 0);
5438 ref_costs_comp[GOLDEN_FRAME] += vp10_cost_bit(ref_comp_p, 1);
5439#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07005440 } else {
5441 ref_costs_comp[LAST_FRAME] = 512;
Zoe Liu3ec16012015-11-12 02:12:17 -08005442#if CONFIG_EXT_REFS
5443 ref_costs_comp[LAST2_FRAME] = 512;
5444 ref_costs_comp[LAST3_FRAME] = 512;
5445 ref_costs_comp[LAST4_FRAME] = 512;
5446#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07005447 ref_costs_comp[GOLDEN_FRAME] = 512;
5448 }
5449 }
5450}
5451
5452static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
5453 int mode_index,
5454 int64_t comp_pred_diff[REFERENCE_MODES],
Jingning Han3ee6db62015-08-05 19:00:31 -07005455 int skippable) {
5456 MACROBLOCKD *const xd = &x->e_mbd;
5457
5458 // Take a snapshot of the coding context so it can be
5459 // restored if we decide to encode this way
5460 ctx->skip = x->skip;
5461 ctx->skippable = skippable;
5462 ctx->best_mode_index = mode_index;
5463 ctx->mic = *xd->mi[0];
5464 ctx->mbmi_ext = *x->mbmi_ext;
5465 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
5466 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
5467 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
Jingning Han3ee6db62015-08-05 19:00:31 -07005468}
5469
Zoe Liu3ec16012015-11-12 02:12:17 -08005470static void setup_buffer_inter(
5471 VP10_COMP *cpi, MACROBLOCK *x,
5472 MV_REFERENCE_FRAME ref_frame,
5473 BLOCK_SIZE block_size,
5474 int mi_row, int mi_col,
5475 int_mv frame_nearest_mv[MAX_REF_FRAMES],
5476 int_mv frame_near_mv[MAX_REF_FRAMES],
5477 struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE]) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07005478 const VP10_COMMON *cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07005479 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
5480 MACROBLOCKD *const xd = &x->e_mbd;
5481 MODE_INFO *const mi = xd->mi[0];
5482 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
5483 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
5484 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
5485
5486 assert(yv12 != NULL);
5487
5488 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
5489 // use the UV scaling factors.
5490 vp10_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
5491
5492 // Gets an initial list of candidate vectors from neighbours and orders them
Jingning Hane5c57c52015-11-23 15:05:18 -08005493 vp10_find_mv_refs(cm, xd, mi, ref_frame,
5494#if CONFIG_REF_MV
5495 &mbmi_ext->ref_mv_count[ref_frame],
5496 mbmi_ext->ref_mv_stack[ref_frame],
Yue Chen968bbc72016-01-19 16:45:45 -08005497#if CONFIG_EXT_INTER
5498 mbmi_ext->compound_mode_context,
5499#endif // CONFIG_EXT_INTER
Jingning Hane5c57c52015-11-23 15:05:18 -08005500#endif
5501 candidates, mi_row, mi_col,
5502 NULL, NULL, mbmi_ext->mode_context);
Jingning Han3ee6db62015-08-05 19:00:31 -07005503
5504 // Candidate refinement carried out at encoder and decoder
Ronald S. Bultje5b4805d2015-10-02 11:51:54 -04005505 vp10_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
5506 &frame_nearest_mv[ref_frame],
5507 &frame_near_mv[ref_frame]);
Jingning Han3ee6db62015-08-05 19:00:31 -07005508
5509 // Further refinement that is encode side only to test the top few candidates
5510 // in full and choose the best as the centre point for subsequent searches.
5511 // The current implementation doesn't support scaling.
5512 if (!vp10_is_scaled(sf) && block_size >= BLOCK_8X8)
5513 vp10_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride,
5514 ref_frame, block_size);
5515}
5516
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005517static void single_motion_search(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07005518 BLOCK_SIZE bsize,
5519 int mi_row, int mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08005520#if CONFIG_EXT_INTER
5521 int ref_idx,
5522 int mv_idx,
5523#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005524 int_mv *tmp_mv, int *rate_mv) {
5525 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xufc7cbd12015-08-13 09:36:53 -07005526 const VP10_COMMON *cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07005527 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5528 struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0, 0}};
5529 int bestsme = INT_MAX;
5530 int step_param;
5531 int sadpb = x->sadperbit16;
5532 MV mvp_full;
Yue Chen1ac85872016-01-07 15:13:52 -08005533#if CONFIG_EXT_INTER
5534 int ref = mbmi->ref_frame[ref_idx];
5535 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
5536#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005537 int ref = mbmi->ref_frame[0];
5538 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08005539 int ref_idx = 0;
Yue Chen1ac85872016-01-07 15:13:52 -08005540#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005541
5542 int tmp_col_min = x->mv_col_min;
5543 int tmp_col_max = x->mv_col_max;
5544 int tmp_row_min = x->mv_row_min;
5545 int tmp_row_max = x->mv_row_max;
5546 int cost_list[5];
5547
5548 const YV12_BUFFER_CONFIG *scaled_ref_frame = vp10_get_scaled_ref_frame(cpi,
5549 ref);
5550
5551 MV pred_mv[3];
5552 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
5553 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
5554 pred_mv[2] = x->pred_mv[ref];
5555
Jingning Han03c01bc2016-02-19 10:41:04 -08005556#if CONFIG_REF_MV
5557 vp10_set_mvcost(x, ref);
5558#endif
5559
Jingning Han3ee6db62015-08-05 19:00:31 -07005560 if (scaled_ref_frame) {
5561 int i;
5562 // Swap out the reference frame for a version that's been scaled to
5563 // match the resolution of the current frame, allowing the existing
5564 // motion search code to be used without additional modifications.
5565 for (i = 0; i < MAX_MB_PLANE; i++)
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08005566 backup_yv12[i] = xd->plane[i].pre[ref_idx];
Jingning Han3ee6db62015-08-05 19:00:31 -07005567
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08005568 vp10_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Jingning Han3ee6db62015-08-05 19:00:31 -07005569 }
5570
5571 vp10_set_mv_search_range(x, &ref_mv);
5572
5573 // Work out the size of the first step in the mv step search.
James Zern5e16d392015-08-17 18:19:22 -07005574 // 0 here is maximum length first step. 1 is VPXMAX >> 1 etc.
Jingning Han3ee6db62015-08-05 19:00:31 -07005575 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
5576 // Take wtd average of the step_params based on the last frame's
5577 // max mv magnitude and that based on the best ref mvs of the current
5578 // block for the given reference.
5579 step_param = (vp10_init_search_range(x->max_mv_context[ref]) +
5580 cpi->mv_step_param) / 2;
5581 } else {
5582 step_param = cpi->mv_step_param;
5583 }
5584
5585 if (cpi->sf.adaptive_motion_search && bsize < BLOCK_64X64) {
James Zern5e16d392015-08-17 18:19:22 -07005586 int boffset =
5587 2 * (b_width_log2_lookup[BLOCK_64X64] -
5588 VPXMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
5589 step_param = VPXMAX(step_param, boffset);
Jingning Han3ee6db62015-08-05 19:00:31 -07005590 }
5591
5592 if (cpi->sf.adaptive_motion_search) {
5593 int bwl = b_width_log2_lookup[bsize];
5594 int bhl = b_height_log2_lookup[bsize];
5595 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
5596
5597 if (tlevel < 5)
5598 step_param += 2;
5599
5600 // prev_mv_sad is not setup for dynamically scaled frames.
5601 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
5602 int i;
5603 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
5604 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
5605 x->pred_mv[ref].row = 0;
5606 x->pred_mv[ref].col = 0;
5607 tmp_mv->as_int = INVALID_MV;
5608
5609 if (scaled_ref_frame) {
5610 int i;
5611 for (i = 0; i < MAX_MB_PLANE; ++i)
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08005612 xd->plane[i].pre[ref_idx] = backup_yv12[i];
Jingning Han3ee6db62015-08-05 19:00:31 -07005613 }
5614 return;
5615 }
5616 }
5617 }
5618 }
5619
5620 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
5621
5622 mvp_full.col >>= 3;
5623 mvp_full.row >>= 3;
5624
5625 bestsme = vp10_full_pixel_search(cpi, x, bsize, &mvp_full, step_param, sadpb,
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08005626 cond_cost_list(cpi, cost_list),
5627 &ref_mv, &tmp_mv->as_mv, INT_MAX, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07005628
5629 x->mv_col_min = tmp_col_min;
5630 x->mv_col_max = tmp_col_max;
5631 x->mv_row_min = tmp_row_min;
5632 x->mv_row_max = tmp_row_max;
5633
5634 if (bestsme < INT_MAX) {
5635 int dis; /* TODO: use dis in distortion calculation later. */
Yunqing Wange6e2d882016-03-10 11:07:50 -08005636 if (cpi->sf.use_upsampled_references) {
5637 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
5638 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
5639 // Use up-sampled reference frames.
5640 struct macroblockd_plane *const pd = &xd->plane[0];
5641 struct buf_2d backup_pred = pd->pre[ref_idx];
5642 const YV12_BUFFER_CONFIG *upsampled_ref = get_upsampled_ref(cpi, ref);
Yunqing Wang342a3682016-02-16 14:33:18 -08005643
Yunqing Wange6e2d882016-03-10 11:07:50 -08005644 // Set pred for Y plane
5645 setup_pred_plane(&pd->pre[ref_idx], upsampled_ref->y_buffer,
5646 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3),
5647 NULL, pd->subsampling_x, pd->subsampling_y);
Yunqing Wang342a3682016-02-16 14:33:18 -08005648
Yunqing Wange6e2d882016-03-10 11:07:50 -08005649 bestsme = cpi->find_fractional_mv_step(x, &tmp_mv->as_mv, &ref_mv,
5650 cm->allow_high_precision_mv,
5651 x->errorperbit,
5652 &cpi->fn_ptr[bsize],
5653 cpi->sf.mv.subpel_force_stop,
5654 cpi->sf.mv.subpel_iters_per_step,
5655 cond_cost_list(cpi, cost_list),
5656 x->nmvjointcost, x->mvcost,
5657 &dis, &x->pred_sse[ref], NULL,
5658 pw, ph, 1);
Yunqing Wang342a3682016-02-16 14:33:18 -08005659
Yunqing Wange6e2d882016-03-10 11:07:50 -08005660 // Restore the reference frames.
5661 pd->pre[ref_idx] = backup_pred;
5662 } else {
5663 cpi->find_fractional_mv_step(x, &tmp_mv->as_mv, &ref_mv,
5664 cm->allow_high_precision_mv,
5665 x->errorperbit,
5666 &cpi->fn_ptr[bsize],
5667 cpi->sf.mv.subpel_force_stop,
5668 cpi->sf.mv.subpel_iters_per_step,
5669 cond_cost_list(cpi, cost_list),
5670 x->nmvjointcost, x->mvcost,
5671 &dis, &x->pred_sse[ref], NULL, 0, 0, 0);
5672 }
Jingning Han3ee6db62015-08-05 19:00:31 -07005673 }
5674 *rate_mv = vp10_mv_bit_cost(&tmp_mv->as_mv, &ref_mv,
5675 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5676
5677 if (cpi->sf.adaptive_motion_search)
5678 x->pred_mv[ref] = tmp_mv->as_mv;
5679
5680 if (scaled_ref_frame) {
5681 int i;
5682 for (i = 0; i < MAX_MB_PLANE; i++)
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08005683 xd->plane[i].pre[ref_idx] = backup_yv12[i];
Jingning Han3ee6db62015-08-05 19:00:31 -07005684 }
5685}
5686
Jingning Han3ee6db62015-08-05 19:00:31 -07005687static INLINE void restore_dst_buf(MACROBLOCKD *xd,
5688 uint8_t *orig_dst[MAX_MB_PLANE],
5689 int orig_dst_stride[MAX_MB_PLANE]) {
5690 int i;
5691 for (i = 0; i < MAX_MB_PLANE; i++) {
5692 xd->plane[i].dst.buf = orig_dst[i];
5693 xd->plane[i].dst.stride = orig_dst_stride[i];
5694 }
5695}
5696
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08005697#if CONFIG_EXT_INTER
5698static void do_masked_motion_search(VP10_COMP *cpi, MACROBLOCK *x,
5699 const uint8_t *mask, int mask_stride,
5700 BLOCK_SIZE bsize,
5701 int mi_row, int mi_col,
5702 int_mv *tmp_mv, int *rate_mv,
5703 int ref_idx,
5704 int mv_idx) {
5705 MACROBLOCKD *xd = &x->e_mbd;
5706 const VP10_COMMON *cm = &cpi->common;
5707 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5708 struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0, 0}};
5709 int bestsme = INT_MAX;
5710 int step_param;
5711 int sadpb = x->sadperbit16;
5712 MV mvp_full;
5713 int ref = mbmi->ref_frame[ref_idx];
5714 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
5715
5716 int tmp_col_min = x->mv_col_min;
5717 int tmp_col_max = x->mv_col_max;
5718 int tmp_row_min = x->mv_row_min;
5719 int tmp_row_max = x->mv_row_max;
5720
5721 const YV12_BUFFER_CONFIG *scaled_ref_frame =
5722 vp10_get_scaled_ref_frame(cpi, ref);
5723
5724 MV pred_mv[3];
5725 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
5726 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
5727 pred_mv[2] = x->pred_mv[ref];
5728
5729#if CONFIG_REF_MV
5730 vp10_set_mvcost(x, ref);
5731#endif
5732
5733 if (scaled_ref_frame) {
5734 int i;
5735 // Swap out the reference frame for a version that's been scaled to
5736 // match the resolution of the current frame, allowing the existing
5737 // motion search code to be used without additional modifications.
5738 for (i = 0; i < MAX_MB_PLANE; i++)
5739 backup_yv12[i] = xd->plane[i].pre[ref_idx];
5740
5741 vp10_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
5742 }
5743
5744 vp10_set_mv_search_range(x, &ref_mv);
5745
5746 // Work out the size of the first step in the mv step search.
5747 // 0 here is maximum length first step. 1 is MAX >> 1 etc.
5748 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
5749 // Take wtd average of the step_params based on the last frame's
5750 // max mv magnitude and that based on the best ref mvs of the current
5751 // block for the given reference.
5752 step_param = (vp10_init_search_range(x->max_mv_context[ref]) +
5753 cpi->mv_step_param) / 2;
5754 } else {
5755 step_param = cpi->mv_step_param;
5756 }
5757
5758 // TODO(debargha): is show_frame needed here?
5759 if (cpi->sf.adaptive_motion_search && bsize < BLOCK_LARGEST &&
5760 cm->show_frame) {
5761 int boffset = 2 * (b_width_log2_lookup[BLOCK_LARGEST] -
5762 VPXMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
5763 step_param = VPXMAX(step_param, boffset);
5764 }
5765
5766 if (cpi->sf.adaptive_motion_search) {
5767 int bwl = b_width_log2_lookup[bsize];
5768 int bhl = b_height_log2_lookup[bsize];
5769 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
5770
5771 if (tlevel < 5)
5772 step_param += 2;
5773
5774 // prev_mv_sad is not setup for dynamically scaled frames.
5775 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
5776 int i;
5777 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
5778 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
5779 x->pred_mv[ref].row = 0;
5780 x->pred_mv[ref].col = 0;
5781 tmp_mv->as_int = INVALID_MV;
5782
5783 if (scaled_ref_frame) {
5784 int i;
5785 for (i = 0; i < MAX_MB_PLANE; ++i)
5786 xd->plane[i].pre[ref_idx] = backup_yv12[i];
5787 }
5788 return;
5789 }
5790 }
5791 }
5792 }
5793
5794 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
5795
5796 mvp_full.col >>= 3;
5797 mvp_full.row >>= 3;
5798
5799 bestsme = vp10_masked_full_pixel_diamond(cpi, x, mask, mask_stride,
5800 &mvp_full, step_param, sadpb,
5801 MAX_MVSEARCH_STEPS - 1 - step_param,
5802 1, &cpi->fn_ptr[bsize],
5803 &ref_mv, &tmp_mv->as_mv, ref_idx);
5804
5805 x->mv_col_min = tmp_col_min;
5806 x->mv_col_max = tmp_col_max;
5807 x->mv_row_min = tmp_row_min;
5808 x->mv_row_max = tmp_row_max;
5809
5810 if (bestsme < INT_MAX) {
5811 int dis; /* TODO: use dis in distortion calculation later. */
5812 vp10_find_best_masked_sub_pixel_tree(x, mask, mask_stride,
5813 &tmp_mv->as_mv, &ref_mv,
5814 cm->allow_high_precision_mv,
5815 x->errorperbit,
5816 &cpi->fn_ptr[bsize],
5817 cpi->sf.mv.subpel_force_stop,
5818 cpi->sf.mv.subpel_iters_per_step,
5819 x->nmvjointcost, x->mvcost,
5820 &dis, &x->pred_sse[ref], ref_idx);
5821 }
5822 *rate_mv = vp10_mv_bit_cost(&tmp_mv->as_mv, &ref_mv,
5823 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5824
5825 if (cpi->sf.adaptive_motion_search && cm->show_frame)
5826 x->pred_mv[ref] = tmp_mv->as_mv;
5827
5828 if (scaled_ref_frame) {
5829 int i;
5830 for (i = 0; i < MAX_MB_PLANE; i++)
5831 xd->plane[i].pre[ref_idx] = backup_yv12[i];
5832 }
5833}
5834
5835static void do_masked_motion_search_indexed(VP10_COMP *cpi, MACROBLOCK *x,
5836 int wedge_index,
5837 BLOCK_SIZE bsize,
5838 int mi_row, int mi_col,
5839 int_mv *tmp_mv, int *rate_mv,
5840 int mv_idx[2],
5841 int which) {
5842 // NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both
5843 MACROBLOCKD *xd = &x->e_mbd;
5844 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5845 BLOCK_SIZE sb_type = mbmi->sb_type;
5846 int w = (4 << b_width_log2_lookup[sb_type]);
5847 int h = (4 << b_height_log2_lookup[sb_type]);
5848 const uint8_t *mask;
5849 const int mask_stride = MASK_MASTER_STRIDE;
5850 mask = vp10_get_soft_mask(wedge_index, sb_type, h, w);
5851
5852 if (which == 0 || which == 2)
5853 do_masked_motion_search(cpi, x, mask, mask_stride, bsize,
5854 mi_row, mi_col, &tmp_mv[0], &rate_mv[0],
5855 0, mv_idx[0]);
5856
5857 if (which == 1 || which == 2) {
5858 // get the negative mask
5859 mask = vp10_get_soft_mask(wedge_index ^ 1, sb_type, h, w);
5860 do_masked_motion_search(cpi, x, mask, mask_stride, bsize,
5861 mi_row, mi_col, &tmp_mv[1], &rate_mv[1],
5862 1, mv_idx[1]);
5863 }
5864}
5865#endif // CONFIG_EXT_INTER
5866
Jingning Han3ee6db62015-08-05 19:00:31 -07005867// In some situations we want to discount tha pparent cost of a new motion
5868// vector. Where there is a subtle motion field and especially where there is
5869// low spatial complexity then it can be hard to cover the cost of a new motion
5870// vector in a single block, even if that motion vector reduces distortion.
5871// However, once established that vector may be usable through the nearest and
5872// near mv modes to reduce distortion in subsequent blocks and also improve
5873// visual quality.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005874static int discount_newmv_test(const VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07005875 int this_mode,
5876 int_mv this_mv,
5877 int_mv (*mode_mv)[MAX_REF_FRAMES],
5878 int ref_frame) {
5879 return (!cpi->rc.is_src_frame_alt_ref &&
5880 (this_mode == NEWMV) &&
5881 (this_mv.as_int != 0) &&
5882 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
5883 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
5884 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
5885 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
5886}
5887
Ronald S. Bultje5b4805d2015-10-02 11:51:54 -04005888#define LEFT_TOP_MARGIN ((VP9_ENC_BORDER_IN_PIXELS - VP9_INTERP_EXTEND) << 3)
5889#define RIGHT_BOTTOM_MARGIN ((VP9_ENC_BORDER_IN_PIXELS -\
5890 VP9_INTERP_EXTEND) << 3)
5891
5892// TODO(jingning): this mv clamping function should be block size dependent.
5893static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
5894 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
5895 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
5896 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
5897 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
5898}
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08005899
Angie Chiangc0035cc2016-02-10 14:20:56 -08005900static INTERP_FILTER predict_interp_filter(const VP10_COMP *cpi,
5901 const MACROBLOCK *x,
5902 const BLOCK_SIZE bsize,
5903 const int mi_row,
5904 const int mi_col,
5905 INTERP_FILTER
5906 (*single_filter)[MAX_REF_FRAMES]
5907 ) {
Jingning Han3ee6db62015-08-05 19:00:31 -07005908 INTERP_FILTER best_filter = SWITCHABLE;
Angie Chiangc0035cc2016-02-10 14:20:56 -08005909 const VP10_COMMON *cm = &cpi->common;
5910 const MACROBLOCKD *xd = &x->e_mbd;
Jingning Han3ee6db62015-08-05 19:00:31 -07005911 int bsl = mi_width_log2_lookup[bsize];
5912 int pred_filter_search = cpi->sf.cb_pred_filter_search ?
5913 (((mi_row + mi_col) >> bsl) +
Yue Chend1cad9c2016-01-27 14:18:53 -08005914 get_chessboard_index(cm->current_video_frame)) & 0x1 : 0;
Angie Chiangc0035cc2016-02-10 14:20:56 -08005915 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5916 const int is_comp_pred = has_second_ref(mbmi);
5917 const int this_mode = mbmi->mode;
5918 int refs[2] = { mbmi->ref_frame[0],
Yue Chend1cad9c2016-01-27 14:18:53 -08005919 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Jingning Han3ee6db62015-08-05 19:00:31 -07005920 if (pred_filter_search) {
5921 INTERP_FILTER af = SWITCHABLE, lf = SWITCHABLE;
5922 if (xd->up_available)
5923 af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
5924 if (xd->left_available)
5925 lf = xd->mi[-1]->mbmi.interp_filter;
5926
Yue Chen1ac85872016-01-07 15:13:52 -08005927#if CONFIG_EXT_INTER
Yue Chen968bbc72016-01-19 16:45:45 -08005928 if ((this_mode != NEWMV && this_mode != NEWFROMNEARMV &&
5929 this_mode != NEW_NEWMV) || (af == lf))
Yue Chen1ac85872016-01-07 15:13:52 -08005930#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005931 if ((this_mode != NEWMV) || (af == lf))
Yue Chen1ac85872016-01-07 15:13:52 -08005932#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005933 best_filter = af;
5934 }
Jingning Han3ee6db62015-08-05 19:00:31 -07005935 if (is_comp_pred) {
Jingning Han3ee6db62015-08-05 19:00:31 -07005936 if (cpi->sf.adaptive_mode_search) {
Yue Chen968bbc72016-01-19 16:45:45 -08005937#if CONFIG_EXT_INTER
5938 switch (this_mode) {
5939 case NEAREST_NEARESTMV:
5940 if (single_filter[NEARESTMV][refs[0]] ==
5941 single_filter[NEARESTMV][refs[1]])
5942 best_filter = single_filter[NEARESTMV][refs[0]];
5943 break;
5944 case NEAREST_NEARMV:
5945 if (single_filter[NEARESTMV][refs[0]] ==
5946 single_filter[NEARMV][refs[1]])
5947 best_filter = single_filter[NEARESTMV][refs[0]];
5948 break;
5949 case NEAR_NEARESTMV:
5950 if (single_filter[NEARMV][refs[0]] ==
5951 single_filter[NEARESTMV][refs[1]])
5952 best_filter = single_filter[NEARMV][refs[0]];
5953 break;
5954 case ZERO_ZEROMV:
5955 if (single_filter[ZEROMV][refs[0]] ==
5956 single_filter[ZEROMV][refs[1]])
5957 best_filter = single_filter[ZEROMV][refs[0]];
5958 break;
5959 case NEW_NEWMV:
5960 if (single_filter[NEWMV][refs[0]] ==
5961 single_filter[NEWMV][refs[1]])
5962 best_filter = single_filter[NEWMV][refs[0]];
5963 break;
5964 case NEAREST_NEWMV:
5965 if (single_filter[NEARESTMV][refs[0]] ==
5966 single_filter[NEWMV][refs[1]])
5967 best_filter = single_filter[NEARESTMV][refs[0]];
5968 break;
5969 case NEAR_NEWMV:
5970 if (single_filter[NEARMV][refs[0]] ==
5971 single_filter[NEWMV][refs[1]])
5972 best_filter = single_filter[NEARMV][refs[0]];
5973 break;
5974 case NEW_NEARESTMV:
5975 if (single_filter[NEWMV][refs[0]] ==
5976 single_filter[NEARESTMV][refs[1]])
5977 best_filter = single_filter[NEWMV][refs[0]];
5978 break;
5979 case NEW_NEARMV:
5980 if (single_filter[NEWMV][refs[0]] ==
5981 single_filter[NEARMV][refs[1]])
5982 best_filter = single_filter[NEWMV][refs[0]];
5983 break;
5984 default:
5985 if (single_filter[this_mode][refs[0]] ==
5986 single_filter[this_mode][refs[1]])
5987 best_filter = single_filter[this_mode][refs[0]];
5988 break;
5989 }
5990#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005991 if (single_filter[this_mode][refs[0]] ==
5992 single_filter[this_mode][refs[1]])
5993 best_filter = single_filter[this_mode][refs[0]];
Yue Chen968bbc72016-01-19 16:45:45 -08005994#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005995 }
5996 }
Angie Chiangc0035cc2016-02-10 14:20:56 -08005997 if (cm->interp_filter != BILINEAR) {
5998 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
Debargha Mukherjeebab29122016-02-26 00:18:03 -08005999 best_filter = EIGHTTAP_REGULAR;
Angie Chiangc0035cc2016-02-10 14:20:56 -08006000 }
6001#if CONFIG_EXT_INTERP
6002 else if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE) {
Debargha Mukherjeebab29122016-02-26 00:18:03 -08006003 best_filter = EIGHTTAP_REGULAR;
Angie Chiangc0035cc2016-02-10 14:20:56 -08006004 }
6005#endif
6006 }
6007 return best_filter;
6008}
6009
6010static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
6011 BLOCK_SIZE bsize,
6012 int *rate2, int64_t *distortion,
6013 int *skippable,
6014 int *rate_y, int *rate_uv,
6015 int *disable_skip,
6016 int_mv (*mode_mv)[MAX_REF_FRAMES],
6017 int mi_row, int mi_col,
Yue Chend1cad9c2016-01-27 14:18:53 -08006018#if CONFIG_OBMC
6019 uint8_t *dst_buf1[3],
6020 int dst_stride1[3],
6021 uint8_t *dst_buf2[3],
6022 int dst_stride2[3],
6023#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08006024#if CONFIG_EXT_INTER
6025 int_mv single_newmvs[2][MAX_REF_FRAMES],
Geza Lore7ded0382016-02-22 10:55:32 +00006026 int single_newmvs_rate[2][MAX_REF_FRAMES],
6027 int *compmode_interintra_cost,
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006028 int *compmode_wedge_cost,
Angie Chiangc0035cc2016-02-10 14:20:56 -08006029#else
6030 int_mv single_newmv[MAX_REF_FRAMES],
6031#endif // CONFIG_EXT_INTER
6032 INTERP_FILTER (*single_filter)[MAX_REF_FRAMES],
6033 int (*single_skippable)[MAX_REF_FRAMES],
6034 int64_t *psse,
Angie Chiangb6fef122016-03-11 16:01:46 -08006035 const int64_t ref_best_rd) {
Angie Chiangc0035cc2016-02-10 14:20:56 -08006036 VP10_COMMON *cm = &cpi->common;
6037 MACROBLOCKD *xd = &x->e_mbd;
6038 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6039 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6040 const int is_comp_pred = has_second_ref(mbmi);
6041 const int this_mode = mbmi->mode;
6042 int_mv *frame_mv = mode_mv[this_mode];
6043 int i;
6044 int refs[2] = { mbmi->ref_frame[0],
6045 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
6046 int_mv cur_mv[2];
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006047 int rate_mv = 0;
Angie Chiangc0035cc2016-02-10 14:20:56 -08006048#if CONFIG_EXT_INTER
6049 int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
6050 int_mv single_newmv[MAX_REF_FRAMES];
Geza Lore7ded0382016-02-22 10:55:32 +00006051 const int * const intra_mode_cost =
6052 cpi->mbmode_cost[size_group_lookup[bsize]];
6053 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006054 const int tmp_buf_sz = CU_SIZE * CU_SIZE;
Angie Chiangc0035cc2016-02-10 14:20:56 -08006055#if CONFIG_REF_MV
6056 uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
6057#endif
6058#endif // CONFIG_EXT_INTER
6059#if CONFIG_VP9_HIGHBITDEPTH
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006060 DECLARE_ALIGNED(16, uint16_t, tmp_buf16[MAX_MB_PLANE * CU_SIZE * CU_SIZE]);
Angie Chiangc0035cc2016-02-10 14:20:56 -08006061 uint8_t *tmp_buf;
6062#else
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006063 DECLARE_ALIGNED(16, uint8_t, tmp_buf[MAX_MB_PLANE * CU_SIZE * CU_SIZE]);
Angie Chiangc0035cc2016-02-10 14:20:56 -08006064#endif // CONFIG_VP9_HIGHBITDEPTH
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006065
Yue Chend1cad9c2016-01-27 14:18:53 -08006066#if CONFIG_OBMC
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006067 int allow_obmc =
6068#if CONFIG_EXT_INTER
6069 !is_comp_interintra_pred &&
6070#endif // CONFIG_EXT_INTER
6071 is_obmc_allowed(mbmi);
Yue Chena6142622016-02-18 12:35:14 -08006072 int rate2_nocoeff, best_rate2 = INT_MAX,
6073 best_skippable, best_xskip, best_disable_skip = 0;
6074#if CONFIG_SUPERTX
6075 int best_rate_y, best_rate_uv;
6076#endif // CONFIG_SUPERTX
6077#if CONFIG_VAR_TX
6078 uint8_t best_blk_skip[3][256];
6079#endif // CONFIG_VAR_TX
6080 int64_t best_distortion = INT64_MAX;
6081 unsigned int best_pred_var = UINT_MAX;
6082 MB_MODE_INFO best_mbmi;
Yue Chend1cad9c2016-01-27 14:18:53 -08006083#endif // CONFIG_OBMC
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006084
Angie Chiangc0035cc2016-02-10 14:20:56 -08006085 int pred_exists = 0;
6086 int intpel_mv;
6087 int64_t rd, tmp_rd, best_rd = INT64_MAX;
6088 int best_needs_copy = 0;
6089 uint8_t *orig_dst[MAX_MB_PLANE];
6090 int orig_dst_stride[MAX_MB_PLANE];
6091 int rs = 0;
6092 INTERP_FILTER best_filter = SWITCHABLE;
6093 uint8_t skip_txfm[MAX_MB_PLANE << 2] = {0};
6094 int64_t bsse[MAX_MB_PLANE << 2] = {0};
6095
6096 int skip_txfm_sb = 0;
6097 int64_t skip_sse_sb = INT64_MAX;
6098 int64_t distortion_y = 0, distortion_uv = 0;
6099 int16_t mode_ctx = mbmi_ext->mode_context[refs[0]];
6100
Geza Lore7ded0382016-02-22 10:55:32 +00006101#if CONFIG_EXT_INTER
6102 *compmode_interintra_cost = 0;
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006103 mbmi->use_wedge_interintra = 0;
6104 *compmode_wedge_cost = 0;
6105 mbmi->use_wedge_interinter = 0;
Geza Lore7ded0382016-02-22 10:55:32 +00006106
6107 // is_comp_interintra_pred implies !is_comp_pred
6108 assert(!is_comp_interintra_pred || (!is_comp_pred));
6109 // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
6110 assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
6111#endif // CONFIG_EXT_INTER
6112
Yue Chend1cad9c2016-01-27 14:18:53 -08006113#if CONFIG_OBMC
6114 tmp_rd = 0;
6115#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08006116#if CONFIG_REF_MV
6117#if CONFIG_EXT_INTER
6118 if (is_comp_pred)
6119 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
6120 else
6121#endif // CONFIG_EXT_INTER
6122 mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
6123 mbmi->ref_frame, bsize, -1);
6124#endif
6125
6126#if CONFIG_VP9_HIGHBITDEPTH
6127 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6128 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf16);
6129 } else {
6130 tmp_buf = (uint8_t *)tmp_buf16;
6131 }
6132#endif // CONFIG_VP9_HIGHBITDEPTH
6133
6134 if (is_comp_pred) {
6135 if (frame_mv[refs[0]].as_int == INVALID_MV ||
6136 frame_mv[refs[1]].as_int == INVALID_MV)
6137 return INT64_MAX;
6138 }
Jingning Han3ee6db62015-08-05 19:00:31 -07006139
Yue Chen1ac85872016-01-07 15:13:52 -08006140 if (have_newmv_in_inter_mode(this_mode)) {
Jingning Han3ee6db62015-08-05 19:00:31 -07006141 if (is_comp_pred) {
Yue Chen1ac85872016-01-07 15:13:52 -08006142#if CONFIG_EXT_INTER
6143 for (i = 0; i < 2; ++i) {
6144 single_newmv[refs[i]].as_int =
Yue Chen968bbc72016-01-19 16:45:45 -08006145 single_newmvs[mv_idx][refs[i]].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08006146 }
Yue Chen968bbc72016-01-19 16:45:45 -08006147
6148 if (this_mode == NEW_NEWMV) {
6149 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
6150 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
6151
6152 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
6153 joint_motion_search(cpi, x, bsize, frame_mv,
Yunqing Wang342a3682016-02-16 14:33:18 -08006154 mi_row, mi_col, NULL, single_newmv, &rate_mv, 0);
Yue Chen968bbc72016-01-19 16:45:45 -08006155 } else {
6156 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
6157 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
6158 x->nmvjointcost, x->mvcost,
6159 MV_COST_WEIGHT);
6160 rate_mv += vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
6161 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
6162 x->nmvjointcost, x->mvcost,
6163 MV_COST_WEIGHT);
6164 }
6165 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
6166 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
6167 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
6168 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
6169 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
6170 } else {
6171 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
6172 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
6173 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
6174 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
6175 }
6176#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006177 // Initialize mv using single prediction mode result.
6178 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
6179 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
6180
6181 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
6182 joint_motion_search(cpi, x, bsize, frame_mv,
Yue Chen1ac85872016-01-07 15:13:52 -08006183 mi_row, mi_col,
Yunqing Wang342a3682016-02-16 14:33:18 -08006184 single_newmv, &rate_mv, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07006185 } else {
6186 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
6187 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
6188 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
6189 rate_mv += vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
6190 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
6191 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
6192 }
Yue Chen968bbc72016-01-19 16:45:45 -08006193#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006194 } else {
6195 int_mv tmp_mv;
Geza Lore7ded0382016-02-22 10:55:32 +00006196
Yue Chen1ac85872016-01-07 15:13:52 -08006197#if CONFIG_EXT_INTER
Geza Lore7ded0382016-02-22 10:55:32 +00006198 if (is_comp_interintra_pred) {
6199 tmp_mv = single_newmvs[mv_idx][refs[0]];
6200 rate_mv = single_newmvs_rate[mv_idx][refs[0]];
6201 } else {
6202 single_motion_search(cpi, x, bsize, mi_row, mi_col,
6203 0, mv_idx, &tmp_mv, &rate_mv);
6204 single_newmvs[mv_idx][refs[0]] = tmp_mv;
6205 single_newmvs_rate[mv_idx][refs[0]] = rate_mv;
6206 }
6207#else
6208 single_motion_search(cpi, x, bsize, mi_row, mi_col, &tmp_mv, &rate_mv);
6209 single_newmv[refs[0]] = tmp_mv;
Yue Chen1ac85872016-01-07 15:13:52 -08006210#endif // CONFIG_EXT_INTER
Geza Lore7ded0382016-02-22 10:55:32 +00006211
Jingning Han3ee6db62015-08-05 19:00:31 -07006212 if (tmp_mv.as_int == INVALID_MV)
6213 return INT64_MAX;
6214
Geza Lore7ded0382016-02-22 10:55:32 +00006215 frame_mv[refs[0]] = tmp_mv;
6216 xd->mi[0]->bmi[0].as_mv[0] = tmp_mv;
Jingning Han3ee6db62015-08-05 19:00:31 -07006217
6218 // Estimate the rate implications of a new mv but discount this
6219 // under certain circumstances where we want to help initiate a weak
6220 // motion field, where the distortion gain for a single block may not
6221 // be enough to overcome the cost of a new mv.
6222 if (discount_newmv_test(cpi, this_mode, tmp_mv, mode_mv, refs[0])) {
Geza Lore7ded0382016-02-22 10:55:32 +00006223 rate_mv = VPXMAX((rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07006224 }
6225 }
Geza Lore7ded0382016-02-22 10:55:32 +00006226 *rate2 += rate_mv;
Jingning Han3ee6db62015-08-05 19:00:31 -07006227 }
6228
6229 for (i = 0; i < is_comp_pred + 1; ++i) {
6230 cur_mv[i] = frame_mv[refs[i]];
6231 // Clip "next_nearest" so that it does not extend to far out of image
Yue Chen1ac85872016-01-07 15:13:52 -08006232#if CONFIG_EXT_INTER
6233 if (this_mode != NEWMV && this_mode != NEWFROMNEARMV)
6234#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006235 if (this_mode != NEWMV)
Yue Chen1ac85872016-01-07 15:13:52 -08006236#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006237 clamp_mv2(&cur_mv[i].as_mv, xd);
6238
6239 if (mv_check_bounds(x, &cur_mv[i].as_mv))
6240 return INT64_MAX;
6241 mbmi->mv[i].as_int = cur_mv[i].as_int;
6242 }
6243
Jingning Han33cc1bd2016-01-12 15:06:59 -08006244#if CONFIG_REF_MV
Yue Chen968bbc72016-01-19 16:45:45 -08006245#if CONFIG_EXT_INTER
6246 if (this_mode == NEAREST_NEARESTMV) {
6247#else
Jingning Han33cc1bd2016-01-12 15:06:59 -08006248 if (this_mode == NEARESTMV && is_comp_pred) {
6249 uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
Yue Chen968bbc72016-01-19 16:45:45 -08006250#endif // CONFIG_EXT_INTER
Jingning Han3944cfb2016-01-13 09:03:15 -08006251 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
Jingning Han33cc1bd2016-01-12 15:06:59 -08006252 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
6253 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
6254
6255 for (i = 0; i < 2; ++i) {
6256 lower_mv_precision(&cur_mv[i].as_mv, cm->allow_high_precision_mv);
6257 clamp_mv2(&cur_mv[i].as_mv, xd);
6258 if (mv_check_bounds(x, &cur_mv[i].as_mv))
6259 return INT64_MAX;
6260 mbmi->mv[i].as_int = cur_mv[i].as_int;
6261 }
6262 }
6263 }
6264
Yue Chen968bbc72016-01-19 16:45:45 -08006265#if CONFIG_EXT_INTER
6266 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
6267 if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
6268 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
6269
6270 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
6271 clamp_mv2(&cur_mv[0].as_mv, xd);
6272 if (mv_check_bounds(x, &cur_mv[0].as_mv))
6273 return INT64_MAX;
6274 mbmi->mv[0].as_int = cur_mv[0].as_int;
6275 }
6276
6277 if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
6278 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
6279
6280 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
6281 clamp_mv2(&cur_mv[1].as_mv, xd);
6282 if (mv_check_bounds(x, &cur_mv[1].as_mv))
6283 return INT64_MAX;
6284 mbmi->mv[1].as_int = cur_mv[1].as_int;
6285 }
6286 }
6287
6288 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
6289 if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV) {
6290 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][1].this_mv;
6291
6292 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
6293 clamp_mv2(&cur_mv[0].as_mv, xd);
6294 if (mv_check_bounds(x, &cur_mv[0].as_mv))
6295 return INT64_MAX;
6296 mbmi->mv[0].as_int = cur_mv[0].as_int;
6297 }
6298
6299 if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV) {
6300 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][1].comp_mv;
6301
6302 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
6303 clamp_mv2(&cur_mv[1].as_mv, xd);
6304 if (mv_check_bounds(x, &cur_mv[1].as_mv))
6305 return INT64_MAX;
6306 mbmi->mv[1].as_int = cur_mv[1].as_int;
6307 }
6308 }
6309#else
Jingning Han33cc1bd2016-01-12 15:06:59 -08006310 if (this_mode == NEARMV && is_comp_pred) {
6311 uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
6312 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
Jingning Han95247be2016-02-17 09:27:08 -08006313 int ref_mv_idx = mbmi->ref_mv_idx + 1;
6314 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
6315 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
Jingning Han33cc1bd2016-01-12 15:06:59 -08006316
6317 for (i = 0; i < 2; ++i) {
6318 lower_mv_precision(&cur_mv[i].as_mv, cm->allow_high_precision_mv);
6319 clamp_mv2(&cur_mv[i].as_mv, xd);
6320 if (mv_check_bounds(x, &cur_mv[i].as_mv))
6321 return INT64_MAX;
6322 mbmi->mv[i].as_int = cur_mv[i].as_int;
6323 }
6324 }
6325 }
Yue Chen968bbc72016-01-19 16:45:45 -08006326#endif // CONFIG_EXT_INTER
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006327#endif // CONFIG_REF_MV
Jingning Han33cc1bd2016-01-12 15:06:59 -08006328
Jingning Han3ee6db62015-08-05 19:00:31 -07006329 // do first prediction into the destination buffer. Do the next
6330 // prediction into a temporary buffer. Then keep track of which one
6331 // of these currently holds the best predictor, and use the other
6332 // one for future predictions. In the end, copy from tmp_buf to
6333 // dst if necessary.
6334 for (i = 0; i < MAX_MB_PLANE; i++) {
6335 orig_dst[i] = xd->plane[i].dst.buf;
6336 orig_dst_stride[i] = xd->plane[i].dst.stride;
6337 }
6338
6339 // We don't include the cost of the second reference here, because there
6340 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
6341 // words if you present them in that order, the second one is always known
6342 // if the first is known.
6343 //
6344 // Under some circumstances we discount the cost of new mv mode to encourage
6345 // initiation of a motion field.
6346 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]],
6347 mode_mv, refs[0])) {
Yue Chen1ac85872016-01-07 15:13:52 -08006348#if CONFIG_REF_MV && CONFIG_EXT_INTER
6349 *rate2 += VPXMIN(cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx),
6350 cost_mv_ref(cpi, NEARESTMV, is_comp_pred, mode_ctx));
6351#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08006352 *rate2 += VPXMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
6353 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
Yue Chen1ac85872016-01-07 15:13:52 -08006354#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006355 } else {
Yue Chen1ac85872016-01-07 15:13:52 -08006356#if CONFIG_REF_MV && CONFIG_EXT_INTER
6357 *rate2 += cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx);
6358#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08006359 *rate2 += cost_mv_ref(cpi, this_mode, mode_ctx);
Yue Chen1ac85872016-01-07 15:13:52 -08006360#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006361 }
6362
6363 if (RDCOST(x->rdmult, x->rddiv, *rate2, 0) > ref_best_rd &&
Yue Chen968bbc72016-01-19 16:45:45 -08006364#if CONFIG_EXT_INTER
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006365 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV
Yue Chen968bbc72016-01-19 16:45:45 -08006366#else
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006367 mbmi->mode != NEARESTMV
Yue Chen968bbc72016-01-19 16:45:45 -08006368#endif // CONFIG_EXT_INTER
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006369 )
Jingning Han3ee6db62015-08-05 19:00:31 -07006370 return INT64_MAX;
6371
6372 pred_exists = 0;
6373 // Are all MVs integer pel for Y and UV
6374 intpel_mv = !mv_has_subpel(&mbmi->mv[0].as_mv);
6375 if (is_comp_pred)
6376 intpel_mv &= !mv_has_subpel(&mbmi->mv[1].as_mv);
6377
Angie Chiangc0035cc2016-02-10 14:20:56 -08006378 best_filter = predict_interp_filter(cpi, x, bsize, mi_row, mi_col,
6379 single_filter);
6380 if (cm->interp_filter != BILINEAR && best_filter == SWITCHABLE) {
6381 int newbest;
6382 int tmp_rate_sum = 0;
6383 int64_t tmp_dist_sum = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07006384
Angie Chiangc0035cc2016-02-10 14:20:56 -08006385 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
6386 int j;
6387 int64_t rs_rd;
6388 int tmp_skip_sb = 0;
6389 int64_t tmp_skip_sse = INT64_MAX;
Jingning Han3ee6db62015-08-05 19:00:31 -07006390
Angie Chiangc0035cc2016-02-10 14:20:56 -08006391 mbmi->interp_filter = i;
6392 rs = vp10_get_switchable_rate(cpi, xd);
6393 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07006394
Angie Chiangc0035cc2016-02-10 14:20:56 -08006395 if (i > 0 && intpel_mv && IsInterpolatingFilter(i)) {
6396 rd = RDCOST(x->rdmult, x->rddiv, tmp_rate_sum, tmp_dist_sum);
Angie Chiangc0035cc2016-02-10 14:20:56 -08006397 if (cm->interp_filter == SWITCHABLE)
6398 rd += rs_rd;
Angie Chiangc0035cc2016-02-10 14:20:56 -08006399 } else {
6400 int rate_sum = 0;
6401 int64_t dist_sum = 0;
Yue Chenb5f8b702016-03-14 12:05:27 -07006402
Angie Chiangc0035cc2016-02-10 14:20:56 -08006403 if (i > 0 && cpi->sf.adaptive_interp_filter_search &&
6404 (cpi->sf.interp_filter_search_mask & (1 << i))) {
6405 rate_sum = INT_MAX;
6406 dist_sum = INT64_MAX;
6407 continue;
Jingning Han3ee6db62015-08-05 19:00:31 -07006408 }
6409
Angie Chiangc0035cc2016-02-10 14:20:56 -08006410 if ((cm->interp_filter == SWITCHABLE &&
6411 (!i || best_needs_copy)) ||
Geza Lore7ded0382016-02-22 10:55:32 +00006412#if CONFIG_EXT_INTER
6413 is_comp_interintra_pred ||
6414#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006415 (cm->interp_filter != SWITCHABLE &&
Angie Chiangc0035cc2016-02-10 14:20:56 -08006416 (cm->interp_filter == mbmi->interp_filter ||
6417 (i == 0 && intpel_mv && IsInterpolatingFilter(i))))) {
6418 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6419 } else {
6420 for (j = 0; j < MAX_MB_PLANE; j++) {
6421 xd->plane[j].dst.buf = tmp_buf + j * 64 * 64;
6422 xd->plane[j].dst.stride = 64;
6423 }
6424 }
6425 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
6426 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6427 &tmp_skip_sb, &tmp_skip_sse);
Jingning Han3ee6db62015-08-05 19:00:31 -07006428
Angie Chiangc0035cc2016-02-10 14:20:56 -08006429 rd = RDCOST(x->rdmult, x->rddiv, rate_sum, dist_sum);
Angie Chiangc0035cc2016-02-10 14:20:56 -08006430 if (cm->interp_filter == SWITCHABLE)
6431 rd += rs_rd;
Angie Chiangc0035cc2016-02-10 14:20:56 -08006432
6433 if (i == 0 && intpel_mv && IsInterpolatingFilter(i)) {
6434 tmp_rate_sum = rate_sum;
6435 tmp_dist_sum = dist_sum;
Jingning Han3ee6db62015-08-05 19:00:31 -07006436 }
6437 }
Angie Chiangc0035cc2016-02-10 14:20:56 -08006438
6439 if (i == 0 && cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
6440 if (rd / 2 > ref_best_rd) {
6441 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6442 return INT64_MAX;
6443 }
6444 }
6445 newbest = i == 0 || rd < best_rd;
6446
6447 if (newbest) {
6448 best_rd = rd;
6449 best_filter = mbmi->interp_filter;
6450 if (cm->interp_filter == SWITCHABLE && i &&
6451 !(intpel_mv && IsInterpolatingFilter(i)))
6452 best_needs_copy = !best_needs_copy;
6453 }
6454
6455 if ((cm->interp_filter == SWITCHABLE && newbest) ||
6456 (cm->interp_filter != SWITCHABLE &&
6457 cm->interp_filter == mbmi->interp_filter)) {
6458 pred_exists = 1;
6459 tmp_rd = best_rd;
6460
6461 skip_txfm_sb = tmp_skip_sb;
6462 skip_sse_sb = tmp_skip_sse;
6463 memcpy(skip_txfm, x->skip_txfm, sizeof(skip_txfm));
6464 memcpy(bsse, x->bsse, sizeof(bsse));
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006465 } else {
6466 pred_exists = 0;
Angie Chiangc0035cc2016-02-10 14:20:56 -08006467 }
Jingning Han3ee6db62015-08-05 19:00:31 -07006468 }
Angie Chiangc0035cc2016-02-10 14:20:56 -08006469 restore_dst_buf(xd, orig_dst, orig_dst_stride);
Jingning Han3ee6db62015-08-05 19:00:31 -07006470 }
Debargha Mukherjee85514c42015-10-30 09:19:36 -07006471
Jingning Han3ee6db62015-08-05 19:00:31 -07006472 // Set the appropriate filter
6473 mbmi->interp_filter = cm->interp_filter != SWITCHABLE ?
6474 cm->interp_filter : best_filter;
6475 rs = cm->interp_filter == SWITCHABLE ? vp10_get_switchable_rate(cpi, xd) : 0;
Geza Lore7ded0382016-02-22 10:55:32 +00006476
6477#if CONFIG_EXT_INTER
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006478 if (is_comp_pred && get_wedge_bits(bsize)) {
6479 int wedge_index, best_wedge_index = WEDGE_NONE, rs;
6480 int rate_sum;
6481 int64_t dist_sum;
6482 int64_t best_rd_nowedge = INT64_MAX;
6483 int64_t best_rd_wedge = INT64_MAX;
6484 int wedge_types;
6485 int tmp_skip_txfm_sb;
6486 int64_t tmp_skip_sse_sb;
6487 rs = vp10_cost_bit(cm->fc->wedge_interinter_prob[bsize], 0);
6488 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
6489 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6490 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
6491 rd = RDCOST(x->rdmult, x->rddiv, rs + rate_mv + rate_sum, dist_sum);
6492 best_rd_nowedge = rd;
6493 mbmi->use_wedge_interinter = 1;
6494 rs = get_wedge_bits(bsize) * 256 +
6495 vp10_cost_bit(cm->fc->wedge_interinter_prob[bsize], 1);
6496 wedge_types = (1 << get_wedge_bits(bsize));
6497 if (have_newmv_in_inter_mode(this_mode)) {
6498 int_mv tmp_mv[2];
6499 int rate_mvs[2], tmp_rate_mv = 0;
6500 uint8_t pred0[2 * CU_SIZE * CU_SIZE * 3];
6501 uint8_t pred1[2 * CU_SIZE * CU_SIZE * 3];
6502 uint8_t *preds0[3] = {pred0,
6503 pred0 + 2 * CU_SIZE * CU_SIZE,
6504 pred0 + 4 * CU_SIZE * CU_SIZE};
6505 uint8_t *preds1[3] = {pred1,
6506 pred1 + 2 * CU_SIZE * CU_SIZE,
6507 pred1 + 4 * CU_SIZE * CU_SIZE};
6508 int strides[3] = {CU_SIZE, CU_SIZE, CU_SIZE};
6509 vp10_build_inter_predictors_for_planes_single_buf(
6510 xd, bsize, mi_row, mi_col, 0, preds0, strides);
6511 vp10_build_inter_predictors_for_planes_single_buf(
6512 xd, bsize, mi_row, mi_col, 1, preds1, strides);
6513
6514 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
6515 mbmi->interinter_wedge_index = wedge_index;
6516 vp10_build_wedge_inter_predictor_from_buf(xd, bsize, mi_row, mi_col,
6517 preds0, strides,
6518 preds1, strides);
6519 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6520 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
6521 rd = RDCOST(x->rdmult, x->rddiv, rs + rate_mv + rate_sum, dist_sum);
6522 if (rd < best_rd_wedge) {
6523 best_wedge_index = wedge_index;
6524 best_rd_wedge = rd;
6525 }
6526 }
6527 mbmi->interinter_wedge_index = best_wedge_index;
6528 if (this_mode == NEW_NEWMV) {
6529 int mv_idxs[2] = {0, 0};
6530 do_masked_motion_search_indexed(cpi, x, mbmi->interinter_wedge_index,
6531 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
6532 mv_idxs, 2);
6533 tmp_rate_mv = rate_mvs[0] + rate_mvs[1];
6534 mbmi->mv[0].as_int = tmp_mv[0].as_int;
6535 mbmi->mv[1].as_int = tmp_mv[1].as_int;
6536 } else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
6537 int mv_idxs[2] = {0, 0};
6538 do_masked_motion_search_indexed(cpi, x, mbmi->interinter_wedge_index,
6539 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
6540 mv_idxs, 0);
6541 tmp_rate_mv = rate_mvs[0];
6542 mbmi->mv[0].as_int = tmp_mv[0].as_int;
6543 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
6544 int mv_idxs[2] = {0, 0};
6545 do_masked_motion_search_indexed(cpi, x, mbmi->interinter_wedge_index,
6546 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
6547 mv_idxs, 1);
6548 tmp_rate_mv = rate_mvs[1];
6549 mbmi->mv[1].as_int = tmp_mv[1].as_int;
6550 }
6551 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
6552 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6553 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
6554 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate_mv + rate_sum, dist_sum);
6555 if (rd < best_rd_wedge) {
6556 best_rd_wedge = rd;
6557 } else {
6558 mbmi->mv[0].as_int = cur_mv[0].as_int;
6559 mbmi->mv[1].as_int = cur_mv[1].as_int;
6560 tmp_rate_mv = rate_mv;
6561 }
6562 if (best_rd_wedge < best_rd_nowedge) {
6563 mbmi->use_wedge_interinter = 1;
6564 mbmi->interinter_wedge_index = best_wedge_index;
6565 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
6566 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
6567 *rate2 += tmp_rate_mv - rate_mv;
6568 rate_mv = tmp_rate_mv;
6569 } else {
6570 mbmi->use_wedge_interinter = 0;
6571 mbmi->mv[0].as_int = cur_mv[0].as_int;
6572 mbmi->mv[1].as_int = cur_mv[1].as_int;
6573 }
6574 } else {
6575 uint8_t pred0[2 * CU_SIZE * CU_SIZE * 3];
6576 uint8_t pred1[2 * CU_SIZE * CU_SIZE * 3];
6577 uint8_t *preds0[3] = {pred0,
6578 pred0 + 2 * CU_SIZE * CU_SIZE,
6579 pred0 + 4 * CU_SIZE * CU_SIZE};
6580 uint8_t *preds1[3] = {pred1,
6581 pred1 + 2 * CU_SIZE * CU_SIZE,
6582 pred1 + 4 * CU_SIZE * CU_SIZE};
6583 int strides[3] = {CU_SIZE, CU_SIZE, CU_SIZE};
6584 vp10_build_inter_predictors_for_planes_single_buf(
6585 xd, bsize, mi_row, mi_col, 0, preds0, strides);
6586 vp10_build_inter_predictors_for_planes_single_buf(
6587 xd, bsize, mi_row, mi_col, 1, preds1, strides);
6588 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
6589 mbmi->interinter_wedge_index = wedge_index;
6590 // vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
6591 vp10_build_wedge_inter_predictor_from_buf(xd, bsize, mi_row, mi_col,
6592 preds0, strides,
6593 preds1, strides);
6594 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6595 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
6596 rd = RDCOST(x->rdmult, x->rddiv, rs + rate_mv + rate_sum, dist_sum);
6597 if (rd < best_rd_wedge) {
6598 best_wedge_index = wedge_index;
6599 best_rd_wedge = rd;
6600 }
6601 }
6602 if (best_rd_wedge < best_rd_nowedge) {
6603 mbmi->use_wedge_interinter = 1;
6604 mbmi->interinter_wedge_index = best_wedge_index;
6605 } else {
6606 mbmi->use_wedge_interinter = 0;
6607 }
6608 }
6609#if CONFIG_OBMC
6610 if (mbmi->use_wedge_interinter)
6611 allow_obmc = 0;
6612#endif // CONFIG_OBMC
6613 if (ref_best_rd < INT64_MAX &&
6614 VPXMIN(best_rd_wedge, best_rd_nowedge) / 2 > ref_best_rd)
6615 return INT64_MAX;
6616
6617 pred_exists = 0;
6618 tmp_rd = VPXMIN(best_rd_wedge, best_rd_nowedge);
6619 if (mbmi->use_wedge_interinter)
6620 *compmode_wedge_cost = get_wedge_bits(bsize) * 256 +
6621 vp10_cost_bit(cm->fc->wedge_interinter_prob[bsize], 1);
6622 else
6623 *compmode_wedge_cost =
6624 vp10_cost_bit(cm->fc->wedge_interinter_prob[bsize], 0);
6625 }
6626
Geza Lore7ded0382016-02-22 10:55:32 +00006627 if (is_comp_interintra_pred) {
6628 PREDICTION_MODE interintra_mode, best_interintra_mode = DC_PRED;
6629 int64_t best_interintra_rd = INT64_MAX;
6630 int rmode, rate_sum;
6631 int64_t dist_sum;
6632 int j;
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006633 int wedge_bits, wedge_types, wedge_index, best_wedge_index = -1;
6634 int64_t best_interintra_rd_nowedge = INT64_MAX;
6635 int64_t best_interintra_rd_wedge = INT64_MAX;
6636 int rwedge;
6637 int bw = 4 << b_width_log2_lookup[mbmi->sb_type],
6638 bh = 4 << b_height_log2_lookup[mbmi->sb_type];
6639 int_mv tmp_mv;
6640 int tmp_rate_mv = 0;
Geza Lore7ded0382016-02-22 10:55:32 +00006641 mbmi->ref_frame[1] = NONE;
6642 for (j = 0; j < MAX_MB_PLANE; j++) {
6643 xd->plane[j].dst.buf = tmp_buf + j * tmp_buf_sz;
6644 xd->plane[j].dst.stride = CU_SIZE;
6645 }
6646 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
6647 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6648 mbmi->ref_frame[1] = INTRA_FRAME;
6649
6650 for (interintra_mode = DC_PRED; interintra_mode <= TM_PRED;
6651 ++interintra_mode) {
6652 mbmi->interintra_mode = interintra_mode;
6653 mbmi->interintra_uv_mode = interintra_mode;
6654 rmode = intra_mode_cost[mbmi->interintra_mode];
6655 vp10_build_interintra_predictors(xd,
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006656 tmp_buf,
6657 tmp_buf + tmp_buf_sz,
6658 tmp_buf + 2 * tmp_buf_sz,
6659 CU_SIZE,
6660 CU_SIZE,
6661 CU_SIZE,
6662 bsize);
Geza Lore7ded0382016-02-22 10:55:32 +00006663 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6664 &skip_txfm_sb, &skip_sse_sb);
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006665 rd = RDCOST(x->rdmult, x->rddiv, rate_mv + rmode + rate_sum, dist_sum);
Geza Lore7ded0382016-02-22 10:55:32 +00006666 if (rd < best_interintra_rd) {
6667 best_interintra_rd = rd;
6668 best_interintra_mode = interintra_mode;
6669 }
6670 }
6671 mbmi->interintra_mode = best_interintra_mode;
6672 mbmi->interintra_uv_mode = best_interintra_mode;
6673 if (ref_best_rd < INT64_MAX &&
6674 best_interintra_rd / 2 > ref_best_rd) {
6675 return INT64_MAX;
6676 }
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006677 wedge_bits = get_wedge_bits(bsize);
6678 rmode = intra_mode_cost[mbmi->interintra_mode];
6679 if (wedge_bits) {
6680 vp10_build_interintra_predictors(xd,
6681 tmp_buf,
6682 tmp_buf + tmp_buf_sz,
6683 tmp_buf + 2 * tmp_buf_sz,
6684 CU_SIZE,
6685 CU_SIZE,
6686 CU_SIZE,
6687 bsize);
6688 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6689 &skip_txfm_sb, &skip_sse_sb);
6690 rwedge = vp10_cost_bit(cm->fc->wedge_interintra_prob[bsize], 0);
6691 rd = RDCOST(x->rdmult, x->rddiv,
6692 rmode + rate_mv + rwedge + rate_sum, dist_sum);
6693 best_interintra_rd_nowedge = rd;
6694
6695 mbmi->use_wedge_interintra = 1;
6696 rwedge = wedge_bits * 256 +
6697 vp10_cost_bit(cm->fc->wedge_interintra_prob[bsize], 1);
6698 wedge_types = (1 << wedge_bits);
6699 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
6700 mbmi->interintra_wedge_index = wedge_index;
6701 mbmi->interintra_uv_wedge_index = wedge_index;
6702 vp10_build_interintra_predictors(xd,
6703 tmp_buf,
6704 tmp_buf + tmp_buf_sz,
6705 tmp_buf + 2 * tmp_buf_sz,
6706 CU_SIZE,
6707 CU_SIZE,
6708 CU_SIZE,
6709 bsize);
6710 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6711 &skip_txfm_sb, &skip_sse_sb);
6712 rd = RDCOST(x->rdmult, x->rddiv,
6713 rmode + rate_mv + rwedge + rate_sum, dist_sum);
6714 if (rd < best_interintra_rd_wedge) {
6715 best_interintra_rd_wedge = rd;
6716 best_wedge_index = wedge_index;
6717 }
6718 }
6719 // Refine motion vector.
6720 if (have_newmv_in_inter_mode(this_mode)) {
6721 // get negative of mask
6722 const uint8_t* mask = vp10_get_soft_mask(
6723 best_wedge_index ^ 1, bsize, bh, bw);
6724 mbmi->interintra_wedge_index = best_wedge_index;
6725 mbmi->interintra_uv_wedge_index = best_wedge_index;
6726 do_masked_motion_search(cpi, x, mask, MASK_MASTER_STRIDE, bsize,
6727 mi_row, mi_col, &tmp_mv, &tmp_rate_mv,
6728 0, mv_idx);
6729 mbmi->mv[0].as_int = tmp_mv.as_int;
6730 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
6731 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6732 &skip_txfm_sb, &skip_sse_sb);
6733 rd = RDCOST(x->rdmult, x->rddiv,
6734 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
6735 if (rd < best_interintra_rd_wedge) {
6736 best_interintra_rd_wedge = rd;
6737 } else {
6738 tmp_mv.as_int = cur_mv[0].as_int;
6739 tmp_rate_mv = rate_mv;
6740 }
6741 } else {
6742 tmp_mv.as_int = cur_mv[0].as_int;
6743 tmp_rate_mv = rate_mv;
6744 }
6745 if (best_interintra_rd_wedge < best_interintra_rd_nowedge) {
6746 mbmi->use_wedge_interintra = 1;
6747 mbmi->interintra_wedge_index = best_wedge_index;
6748 mbmi->interintra_uv_wedge_index = best_wedge_index;
6749 best_interintra_rd = best_interintra_rd_wedge;
6750 mbmi->mv[0].as_int = tmp_mv.as_int;
6751 *rate2 += tmp_rate_mv - rate_mv;
6752 rate_mv = tmp_rate_mv;
6753 } else {
6754 mbmi->use_wedge_interintra = 0;
6755 best_interintra_rd = best_interintra_rd_nowedge;
6756 mbmi->mv[0].as_int = cur_mv[0].as_int;
6757 }
6758 }
Geza Lore7ded0382016-02-22 10:55:32 +00006759
6760 pred_exists = 0;
6761 tmp_rd = best_interintra_rd;
Geza Lore7ded0382016-02-22 10:55:32 +00006762 *compmode_interintra_cost =
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006763 vp10_cost_bit(cm->fc->interintra_prob[bsize], 1);
Geza Lore7ded0382016-02-22 10:55:32 +00006764 *compmode_interintra_cost += intra_mode_cost[mbmi->interintra_mode];
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006765 if (get_wedge_bits(bsize)) {
6766 *compmode_interintra_cost += vp10_cost_bit(
6767 cm->fc->wedge_interintra_prob[bsize], mbmi->use_wedge_interintra);
6768 if (mbmi->use_wedge_interintra) {
6769 *compmode_interintra_cost += get_wedge_bits(bsize) * 256;
6770 }
6771 }
Geza Lore7ded0382016-02-22 10:55:32 +00006772 } else if (is_interintra_allowed(mbmi)) {
6773 *compmode_interintra_cost =
6774 vp10_cost_bit(cm->fc->interintra_prob[bsize], 0);
6775 }
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08006776
6777#if CONFIG_EXT_INTERP
6778 if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE) {
6779 mbmi->interp_filter = EIGHTTAP_REGULAR;
6780 pred_exists = 0;
6781 }
6782#endif // CONFIG_EXT_INTERP
Geza Lore7ded0382016-02-22 10:55:32 +00006783#endif // CONFIG_EXT_INTER
6784
Jingning Han3ee6db62015-08-05 19:00:31 -07006785 if (pred_exists) {
6786 if (best_needs_copy) {
6787 // again temporarily set the buffers to local memory to prevent a memcpy
6788 for (i = 0; i < MAX_MB_PLANE; i++) {
6789 xd->plane[i].dst.buf = tmp_buf + i * 64 * 64;
6790 xd->plane[i].dst.stride = 64;
6791 }
6792 }
Yue Chenb5f8b702016-03-14 12:05:27 -07006793 rd = tmp_rd;
Jingning Han3ee6db62015-08-05 19:00:31 -07006794 } else {
6795 int tmp_rate;
6796 int64_t tmp_dist;
Yue Chenb5f8b702016-03-14 12:05:27 -07006797
Jingning Han3ee6db62015-08-05 19:00:31 -07006798 // Handles the special case when a filter that is not in the
6799 // switchable list (ex. bilinear) is indicated at the frame level, or
6800 // skip condition holds.
6801 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
6802 model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist,
6803 &skip_txfm_sb, &skip_sse_sb);
6804 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
6805 memcpy(skip_txfm, x->skip_txfm, sizeof(skip_txfm));
6806 memcpy(bsse, x->bsse, sizeof(bsse));
6807 }
6808
6809 if (!is_comp_pred)
6810 single_filter[this_mode][refs[0]] = mbmi->interp_filter;
6811
6812 if (cpi->sf.adaptive_mode_search)
6813 if (is_comp_pred)
Yue Chen968bbc72016-01-19 16:45:45 -08006814#if CONFIG_EXT_INTER
6815 switch (this_mode) {
6816 case NEAREST_NEARESTMV:
6817 if (single_skippable[NEARESTMV][refs[0]] &&
6818 single_skippable[NEARESTMV][refs[1]])
6819 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6820 break;
6821 case ZERO_ZEROMV:
6822 if (single_skippable[ZEROMV][refs[0]] &&
6823 single_skippable[ZEROMV][refs[1]])
6824 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6825 break;
6826 case NEW_NEWMV:
6827 if (single_skippable[NEWMV][refs[0]] &&
6828 single_skippable[NEWMV][refs[1]])
6829 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6830 break;
6831 case NEAREST_NEWMV:
6832 if (single_skippable[NEARESTMV][refs[0]] &&
6833 single_skippable[NEWMV][refs[1]])
6834 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6835 break;
6836 case NEAR_NEWMV:
6837 if (single_skippable[NEARMV][refs[0]] &&
6838 single_skippable[NEWMV][refs[1]])
6839 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6840 break;
6841 case NEW_NEARESTMV:
6842 if (single_skippable[NEWMV][refs[0]] &&
6843 single_skippable[NEARESTMV][refs[1]])
6844 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6845 break;
6846 case NEW_NEARMV:
6847 if (single_skippable[NEWMV][refs[0]] &&
6848 single_skippable[NEARMV][refs[1]])
6849 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6850 break;
6851 case NEAREST_NEARMV:
6852 if (single_skippable[NEARESTMV][refs[0]] &&
6853 single_skippable[NEARMV][refs[1]])
6854 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6855 break;
6856 case NEAR_NEARESTMV:
6857 if (single_skippable[NEARMV][refs[0]] &&
6858 single_skippable[NEARESTMV][refs[1]])
6859 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6860 break;
6861 default:
6862 if (single_skippable[this_mode][refs[0]] &&
6863 single_skippable[this_mode][refs[1]])
6864 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6865 break;
6866 }
6867#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006868 if (single_skippable[this_mode][refs[0]] &&
6869 single_skippable[this_mode][refs[1]])
6870 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
Yue Chen968bbc72016-01-19 16:45:45 -08006871#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006872
6873 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
6874 // if current pred_error modeled rd is substantially more than the best
6875 // so far, do not bother doing full rd
6876 if (rd / 2 > ref_best_rd) {
6877 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6878 return INT64_MAX;
6879 }
6880 }
6881
6882 if (cm->interp_filter == SWITCHABLE)
6883 *rate2 += rs;
Yue Chend1cad9c2016-01-27 14:18:53 -08006884#if CONFIG_OBMC
Yue Chena6142622016-02-18 12:35:14 -08006885 rate2_nocoeff = *rate2;
Yue Chend1cad9c2016-01-27 14:18:53 -08006886#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006887
6888 memcpy(x->skip_txfm, skip_txfm, sizeof(skip_txfm));
6889 memcpy(x->bsse, bsse, sizeof(bsse));
6890
Yue Chena6142622016-02-18 12:35:14 -08006891
6892#if CONFIG_OBMC
6893 best_rd = INT64_MAX;
6894 for (mbmi->obmc = 0; mbmi->obmc <= allow_obmc; mbmi->obmc++) {
Yue Chenb5f8b702016-03-14 12:05:27 -07006895 int64_t tmp_rd, tmp_dist;
6896 int tmp_rate;
Yue Chena6142622016-02-18 12:35:14 -08006897
Yue Chenb5f8b702016-03-14 12:05:27 -07006898 if (mbmi->obmc) {
6899 vp10_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, 0,
6900 NULL, NULL,
6901 dst_buf1, dst_stride1,
6902 dst_buf2, dst_stride2);
6903 model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist,
6904 &skip_txfm_sb, &skip_sse_sb);
Yue Chena6142622016-02-18 12:35:14 -08006905 }
6906#if CONFIG_VP9_HIGHBITDEPTH
6907 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6908 x->pred_variance = vp10_high_get_sby_perpixel_variance(cpi,
6909 &xd->plane[0].dst, bsize, xd->bd);
6910 } else {
6911 x->pred_variance =
6912 vp10_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
6913 }
6914#else
6915 x->pred_variance =
6916 vp10_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
6917#endif // CONFIG_VP9_HIGHBITDEPTH
6918
Yue Chena6142622016-02-18 12:35:14 -08006919 x->skip = 0;
6920
6921 *rate2 = rate2_nocoeff;
6922 *distortion = 0;
6923 if (allow_obmc)
6924 *rate2 += cpi->obmc_cost[bsize][mbmi->obmc];
6925#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006926 if (!skip_txfm_sb) {
6927 int skippable_y, skippable_uv;
6928 int64_t sseuv = INT64_MAX;
6929 int64_t rdcosty = INT64_MAX;
6930
6931 // Y cost and distortion
6932 vp10_subtract_plane(x, bsize, 0);
Jingning Han2cdc1272015-10-09 09:57:42 -07006933#if CONFIG_VAR_TX
Jingning Hanf0dee772015-10-26 12:32:30 -07006934 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
Jingning Han4b594d32015-11-02 12:05:47 -08006935 select_tx_type_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
6936 bsize, ref_best_rd);
Jingning Han2cdc1272015-10-09 09:57:42 -07006937 } else {
Jingning Han0f34e352015-11-15 20:52:51 -08006938 int idx, idy;
Jingning Han2cdc1272015-10-09 09:57:42 -07006939 super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
6940 bsize, ref_best_rd);
Jingning Han0f34e352015-11-15 20:52:51 -08006941 for (idy = 0; idy < xd->n8_h; ++idy)
6942 for (idx = 0; idx < xd->n8_w; ++idx)
6943 mbmi->inter_tx_size[idy * 8 + idx] = mbmi->tx_size;
Jingning Han2cdc1272015-10-09 09:57:42 -07006944 }
6945#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006946 super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
6947 bsize, ref_best_rd);
Debargha Mukherjee9a8a6a12016-01-22 14:52:38 -08006948#endif // CONFIG_VAR_TX
Jingning Han704985e2015-10-08 12:05:03 -07006949
Jingning Han3ee6db62015-08-05 19:00:31 -07006950 if (*rate_y == INT_MAX) {
6951 *rate2 = INT_MAX;
6952 *distortion = INT64_MAX;
Yue Chena6142622016-02-18 12:35:14 -08006953#if CONFIG_OBMC
6954 continue;
6955#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006956 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6957 return INT64_MAX;
Yue Chena6142622016-02-18 12:35:14 -08006958#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006959 }
6960
6961 *rate2 += *rate_y;
6962 *distortion += distortion_y;
6963
6964 rdcosty = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
James Zern5e16d392015-08-17 18:19:22 -07006965 rdcosty = VPXMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, *psse));
Jingning Han3ee6db62015-08-05 19:00:31 -07006966
Jingning Hana8dad552015-10-08 16:46:10 -07006967#if CONFIG_VAR_TX
6968 if (!inter_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv,
6969 &sseuv, bsize, ref_best_rd - rdcosty)) {
6970#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006971 if (!super_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv,
6972 &sseuv, bsize, ref_best_rd - rdcosty)) {
Debargha Mukherjee9a8a6a12016-01-22 14:52:38 -08006973#endif // CONFIG_VAR_TX
Jingning Han3ee6db62015-08-05 19:00:31 -07006974 *rate2 = INT_MAX;
6975 *distortion = INT64_MAX;
Yue Chena6142622016-02-18 12:35:14 -08006976#if CONFIG_OBMC
6977 continue;
6978#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006979 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6980 return INT64_MAX;
Yue Chena6142622016-02-18 12:35:14 -08006981#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006982 }
6983
6984 *psse += sseuv;
6985 *rate2 += *rate_uv;
6986 *distortion += distortion_uv;
6987 *skippable = skippable_y && skippable_uv;
Yue Chena6142622016-02-18 12:35:14 -08006988#if CONFIG_OBMC
6989 if (*skippable) {
6990 *rate2 -= *rate_uv + *rate_y;
6991 *rate_y = 0;
6992 *rate_uv = 0;
6993 *rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
6994 mbmi->skip = 0;
6995 // here mbmi->skip temporarily plays a role as what this_skip2 does
6996 } else if (!xd->lossless[mbmi->segment_id] &&
6997 (RDCOST(x->rdmult, x->rddiv, *rate_y + *rate_uv +
6998 vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0), *distortion) >=
6999 RDCOST(x->rdmult, x->rddiv,
7000 vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1), *psse))) {
7001 *rate2 -= *rate_uv + *rate_y;
7002 *rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
7003 *distortion = *psse;
7004 *rate_y = 0;
7005 *rate_uv = 0;
7006 mbmi->skip = 1;
7007 } else {
7008 *rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
7009 mbmi->skip = 0;
7010 }
7011 *disable_skip = 0;
7012#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007013 } else {
7014 x->skip = 1;
7015 *disable_skip = 1;
7016
7017 // The cost of skip bit needs to be added.
Yue Chena6142622016-02-18 12:35:14 -08007018#if CONFIG_OBMC
Yue Chenb5f8b702016-03-14 12:05:27 -07007019 mbmi->skip = 0;
Yue Chena6142622016-02-18 12:35:14 -08007020#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007021 *rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
7022
7023 *distortion = skip_sse_sb;
7024 }
Yue Chena6142622016-02-18 12:35:14 -08007025#if CONFIG_OBMC
7026 tmp_rd = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
7027 if (mbmi->obmc == 0 || (tmp_rd < best_rd)) {
7028 best_mbmi = *mbmi;
7029 best_rd = tmp_rd;
7030 best_rate2 = *rate2;
7031#if CONFIG_SUPERTX
7032 best_rate_y = *rate_y;
7033 best_rate_uv = *rate_uv;
7034#endif // CONFIG_SUPERTX
7035#if CONFIG_VAR_TX
7036 for (i = 0; i < MAX_MB_PLANE; ++i)
7037 memcpy(best_blk_skip[i], x->blk_skip[i],
7038 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7039#endif // CONFIG_VAR_TX
7040 best_distortion = *distortion;
7041 best_skippable = *skippable;
7042 best_xskip = x->skip;
7043 best_disable_skip = *disable_skip;
7044 best_pred_var = x->pred_variance;
7045 }
7046 }
7047
7048 if (best_rd == INT64_MAX) {
7049 *rate2 = INT_MAX;
7050 *distortion = INT64_MAX;
7051 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7052 return INT64_MAX;
7053 }
7054 *mbmi = best_mbmi;
7055 *rate2 = best_rate2;
7056#if CONFIG_SUPERTX
7057 *rate_y = best_rate_y;
7058 *rate_uv = best_rate_uv;
7059#endif // CONFIG_SUPERTX
7060#if CONFIG_VAR_TX
7061 for (i = 0; i < MAX_MB_PLANE; ++i)
7062 memcpy(x->blk_skip[i], best_blk_skip[i],
7063 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7064#endif // CONFIG_VAR_TX
7065 *distortion = best_distortion;
7066 *skippable = best_skippable;
7067 x->skip = best_xskip;
7068 *disable_skip = best_disable_skip;
7069 x->pred_variance = best_pred_var;
7070#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007071
7072 if (!is_comp_pred)
7073 single_skippable[this_mode][refs[0]] = *skippable;
7074
7075 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7076 return 0; // The rate-distortion cost will be re-calculated by caller.
7077}
7078
Yaowu Xu26a9afc2015-08-13 09:42:27 -07007079void vp10_rd_pick_intra_mode_sb(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07007080 RD_COST *rd_cost, BLOCK_SIZE bsize,
7081 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07007082 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07007083 MACROBLOCKD *const xd = &x->e_mbd;
7084 struct macroblockd_plane *const pd = xd->plane;
7085 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
7086 int y_skip = 0, uv_skip = 0;
7087 int64_t dist_y = 0, dist_uv = 0;
7088 TX_SIZE max_uv_tx_size;
Jingning Han3ee6db62015-08-05 19:00:31 -07007089 ctx->skip = 0;
7090 xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
7091 xd->mi[0]->mbmi.ref_frame[1] = NONE;
7092
7093 if (bsize >= BLOCK_8X8) {
7094 if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly,
7095 &dist_y, &y_skip, bsize,
7096 best_rd) >= best_rd) {
7097 rd_cost->rate = INT_MAX;
7098 return;
7099 }
7100 } else {
7101 y_skip = 0;
7102 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
7103 &dist_y, best_rd) >= best_rd) {
7104 rd_cost->rate = INT_MAX;
7105 return;
7106 }
7107 }
7108 max_uv_tx_size = get_uv_tx_size_impl(xd->mi[0]->mbmi.tx_size, bsize,
7109 pd[1].subsampling_x,
7110 pd[1].subsampling_y);
7111 rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv, &rate_uv_tokenonly,
James Zern5e16d392015-08-17 18:19:22 -07007112 &dist_uv, &uv_skip, VPXMAX(BLOCK_8X8, bsize),
Jingning Han3ee6db62015-08-05 19:00:31 -07007113 max_uv_tx_size);
7114
7115 if (y_skip && uv_skip) {
7116 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
7117 vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
7118 rd_cost->dist = dist_y + dist_uv;
7119 } else {
7120 rd_cost->rate = rate_y + rate_uv +
7121 vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
7122 rd_cost->dist = dist_y + dist_uv;
7123 }
7124
7125 ctx->mic = *xd->mi[0];
7126 ctx->mbmi_ext = *x->mbmi_ext;
7127 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
7128}
7129
7130// This function is designed to apply a bias or adjustment to an rd value based
7131// on the relative variance of the source and reconstruction.
7132#define LOW_VAR_THRESH 16
7133#define VLOW_ADJ_MAX 25
7134#define VHIGH_ADJ_MAX 8
Yaowu Xu26a9afc2015-08-13 09:42:27 -07007135static void rd_variance_adjustment(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07007136 MACROBLOCK *x,
7137 BLOCK_SIZE bsize,
7138 int64_t *this_rd,
7139 MV_REFERENCE_FRAME ref_frame,
Yue Chena6142622016-02-18 12:35:14 -08007140#if CONFIG_OBMC
7141 int is_pred_var_available,
7142#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007143 unsigned int source_variance) {
7144 MACROBLOCKD *const xd = &x->e_mbd;
7145 unsigned int recon_variance;
7146 unsigned int absvar_diff = 0;
7147 int64_t var_error = 0;
7148 int64_t var_factor = 0;
7149
7150 if (*this_rd == INT64_MAX)
7151 return;
7152
Yue Chena6142622016-02-18 12:35:14 -08007153#if CONFIG_OBMC
7154 if (is_pred_var_available) {
7155 recon_variance = x->pred_variance;
7156 } else {
7157#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007158#if CONFIG_VP9_HIGHBITDEPTH
7159 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
7160 recon_variance =
7161 vp10_high_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize, xd->bd);
7162 } else {
7163 recon_variance =
7164 vp10_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
7165 }
7166#else
7167 recon_variance =
7168 vp10_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
7169#endif // CONFIG_VP9_HIGHBITDEPTH
Yue Chena6142622016-02-18 12:35:14 -08007170#if CONFIG_OBMC
7171 }
7172#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007173
7174 if ((source_variance + recon_variance) > LOW_VAR_THRESH) {
7175 absvar_diff = (source_variance > recon_variance)
7176 ? (source_variance - recon_variance)
7177 : (recon_variance - source_variance);
7178
Alex Converseb1fcd172015-11-19 14:53:51 -08007179 var_error = ((int64_t)200 * source_variance * recon_variance) /
7180 (((int64_t)source_variance * source_variance) +
7181 ((int64_t)recon_variance * recon_variance));
Jingning Han3ee6db62015-08-05 19:00:31 -07007182 var_error = 100 - var_error;
7183 }
7184
7185 // Source variance above a threshold and ref frame is intra.
7186 // This case is targeted mainly at discouraging intra modes that give rise
7187 // to a predictor with a low spatial complexity compared to the source.
7188 if ((source_variance > LOW_VAR_THRESH) && (ref_frame == INTRA_FRAME) &&
7189 (source_variance > recon_variance)) {
James Zern5e16d392015-08-17 18:19:22 -07007190 var_factor = VPXMIN(absvar_diff, VPXMIN(VLOW_ADJ_MAX, var_error));
Jingning Han3ee6db62015-08-05 19:00:31 -07007191 // A second possible case of interest is where the source variance
7192 // is very low and we wish to discourage false texture or motion trails.
7193 } else if ((source_variance < (LOW_VAR_THRESH >> 1)) &&
7194 (recon_variance > source_variance)) {
James Zern5e16d392015-08-17 18:19:22 -07007195 var_factor = VPXMIN(absvar_diff, VPXMIN(VHIGH_ADJ_MAX, var_error));
Jingning Han3ee6db62015-08-05 19:00:31 -07007196 }
7197 *this_rd += (*this_rd * var_factor) / 100;
7198}
7199
7200
7201// Do we have an internal image edge (e.g. formatting bars).
Yaowu Xu26a9afc2015-08-13 09:42:27 -07007202int vp10_internal_image_edge(VP10_COMP *cpi) {
Jingning Han3ee6db62015-08-05 19:00:31 -07007203 return (cpi->oxcf.pass == 2) &&
7204 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
7205 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
7206}
7207
7208// Checks to see if a super block is on a horizontal image edge.
7209// In most cases this is the "real" edge unless there are formatting
7210// bars embedded in the stream.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07007211int vp10_active_h_edge(VP10_COMP *cpi, int mi_row, int mi_step) {
Jingning Han3ee6db62015-08-05 19:00:31 -07007212 int top_edge = 0;
7213 int bottom_edge = cpi->common.mi_rows;
7214 int is_active_h_edge = 0;
7215
7216 // For two pass account for any formatting bars detected.
7217 if (cpi->oxcf.pass == 2) {
7218 TWO_PASS *twopass = &cpi->twopass;
7219
7220 // The inactive region is specified in MBs not mi units.
7221 // The image edge is in the following MB row.
7222 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
7223
7224 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
James Zern5e16d392015-08-17 18:19:22 -07007225 bottom_edge = VPXMAX(top_edge, bottom_edge);
Jingning Han3ee6db62015-08-05 19:00:31 -07007226 }
7227
7228 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
7229 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
7230 is_active_h_edge = 1;
7231 }
7232 return is_active_h_edge;
7233}
7234
7235// Checks to see if a super block is on a vertical image edge.
7236// In most cases this is the "real" edge unless there are formatting
7237// bars embedded in the stream.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07007238int vp10_active_v_edge(VP10_COMP *cpi, int mi_col, int mi_step) {
Jingning Han3ee6db62015-08-05 19:00:31 -07007239 int left_edge = 0;
7240 int right_edge = cpi->common.mi_cols;
7241 int is_active_v_edge = 0;
7242
7243 // For two pass account for any formatting bars detected.
7244 if (cpi->oxcf.pass == 2) {
7245 TWO_PASS *twopass = &cpi->twopass;
7246
7247 // The inactive region is specified in MBs not mi units.
7248 // The image edge is in the following MB row.
7249 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
7250
7251 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
James Zern5e16d392015-08-17 18:19:22 -07007252 right_edge = VPXMAX(left_edge, right_edge);
Jingning Han3ee6db62015-08-05 19:00:31 -07007253 }
7254
7255 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
7256 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
7257 is_active_v_edge = 1;
7258 }
7259 return is_active_v_edge;
7260}
7261
7262// Checks to see if a super block is at the edge of the active image.
7263// In most cases this is the "real" edge unless there are formatting
7264// bars embedded in the stream.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07007265int vp10_active_edge_sb(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07007266 int mi_row, int mi_col) {
7267 return vp10_active_h_edge(cpi, mi_row, MI_BLOCK_SIZE) ||
7268 vp10_active_v_edge(cpi, mi_col, MI_BLOCK_SIZE);
7269}
7270
hui su78b0bd02016-02-23 15:22:25 -08007271static void restore_uv_color_map(VP10_COMP *cpi, MACROBLOCK *x) {
7272 MACROBLOCKD *const xd = &x->e_mbd;
7273 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7274 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
7275 const BLOCK_SIZE bsize = mbmi->sb_type;
7276 const int rows = (4 * num_4x4_blocks_high_lookup[bsize]) >>
7277 (xd->plane[1].subsampling_y);
7278 const int cols = (4 * num_4x4_blocks_wide_lookup[bsize]) >>
7279 (xd->plane[1].subsampling_x);
7280 int src_stride = x->plane[1].src.stride;
7281 const uint8_t *const src_u = x->plane[1].src.buf;
7282 const uint8_t *const src_v = x->plane[2].src.buf;
7283 double *const data = x->palette_buffer->kmeans_data_buf;
7284 uint8_t *const indices = x->palette_buffer->kmeans_indices_buf;
7285 double centroids[2 * PALETTE_MAX_SIZE];
7286 uint8_t *const color_map = xd->plane[1].color_index_map;
7287 int r, c;
7288#if CONFIG_VP9_HIGHBITDEPTH
7289 const uint16_t *const src_u16 = CONVERT_TO_SHORTPTR(src_u);
7290 const uint16_t *const src_v16 = CONVERT_TO_SHORTPTR(src_v);
7291#endif // CONFIG_VP9_HIGHBITDEPTH
7292 (void)cpi;
7293
7294 for (r = 0; r < rows; ++r) {
7295 for (c = 0; c < cols; ++c) {
7296#if CONFIG_VP9_HIGHBITDEPTH
7297 if (cpi->common.use_highbitdepth) {
7298 data[(r * cols + c) * 2 ] =
7299 src_u16[r * src_stride + c];
7300 data[(r * cols + c) * 2 + 1] =
7301 src_v16[r * src_stride + c];
7302 } else {
7303#endif // CONFIG_VP9_HIGHBITDEPTH
7304 data[(r * cols + c) * 2 ] =
7305 src_u[r * src_stride + c];
7306 data[(r * cols + c) * 2 + 1] =
7307 src_v[r * src_stride + c];
7308#if CONFIG_VP9_HIGHBITDEPTH
7309 }
7310#endif // CONFIG_VP9_HIGHBITDEPTH
7311 }
7312 }
7313
7314 for (r = 1; r < 3; ++r) {
7315 for (c = 0; c < pmi->palette_size[1]; ++c) {
7316 centroids[c * 2 + r - 1] = pmi->palette_colors[r * PALETTE_MAX_SIZE + c];
7317 }
7318 }
7319
7320 vp10_calc_indices(data, centroids, indices, rows * cols,
7321 pmi->palette_size[1], 2);
7322
7323 for (r = 0; r < rows; ++r)
7324 for (c = 0; c < cols; ++c)
7325 color_map[r * cols + c] = indices[r * cols + c];
7326}
7327
Yaowu Xu26a9afc2015-08-13 09:42:27 -07007328void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
Jingning Han4fa8e732015-09-10 12:24:06 -07007329 TileDataEnc *tile_data,
7330 MACROBLOCK *x,
7331 int mi_row, int mi_col,
Debargha Mukherjee3787b172015-11-19 16:51:16 -08007332 RD_COST *rd_cost,
7333#if CONFIG_SUPERTX
7334 int *returnrate_nocoef,
7335#endif // CONFIG_SUPERTX
7336 BLOCK_SIZE bsize,
Jingning Han4fa8e732015-09-10 12:24:06 -07007337 PICK_MODE_CONTEXT *ctx,
7338 int64_t best_rd_so_far) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07007339 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07007340 RD_OPT *const rd_opt = &cpi->rd;
7341 SPEED_FEATURES *const sf = &cpi->sf;
7342 MACROBLOCKD *const xd = &x->e_mbd;
7343 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
hui su78b0bd02016-02-23 15:22:25 -08007344 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Jingning Han3ee6db62015-08-05 19:00:31 -07007345 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
7346 const struct segmentation *const seg = &cm->seg;
7347 PREDICTION_MODE this_mode;
7348 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
7349 unsigned char segment_id = mbmi->segment_id;
7350 int comp_pred, i, k;
7351 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
Zoe Liu3ec16012015-11-12 02:12:17 -08007352 struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE];
Yue Chen1ac85872016-01-07 15:13:52 -08007353#if CONFIG_EXT_INTER
7354 int_mv single_newmvs[2][MAX_REF_FRAMES] = { { { 0 } }, { { 0 } } };
Geza Lore7ded0382016-02-22 10:55:32 +00007355 int single_newmvs_rate[2][MAX_REF_FRAMES] = { { 0 }, { 0 } };
Yue Chen1ac85872016-01-07 15:13:52 -08007356#else
Jingning Han3ee6db62015-08-05 19:00:31 -07007357 int_mv single_newmv[MAX_REF_FRAMES] = { { 0 } };
Yue Chen1ac85872016-01-07 15:13:52 -08007358#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007359 INTERP_FILTER single_inter_filter[MB_MODE_COUNT][MAX_REF_FRAMES];
7360 int single_skippable[MB_MODE_COUNT][MAX_REF_FRAMES];
Zoe Liu3ec16012015-11-12 02:12:17 -08007361 static const int flag_list[REFS_PER_FRAME + 1] = {
7362 0,
7363 VP9_LAST_FLAG,
7364#if CONFIG_EXT_REFS
7365 VP9_LAST2_FLAG,
7366 VP9_LAST3_FLAG,
7367 VP9_LAST4_FLAG,
7368#endif // CONFIG_EXT_REFS
7369 VP9_GOLD_FLAG,
7370 VP9_ALT_FLAG
7371 };
Jingning Han3ee6db62015-08-05 19:00:31 -07007372 int64_t best_rd = best_rd_so_far;
7373 int64_t best_pred_diff[REFERENCE_MODES];
7374 int64_t best_pred_rd[REFERENCE_MODES];
Jingning Han3ee6db62015-08-05 19:00:31 -07007375 MB_MODE_INFO best_mbmode;
7376 int best_mode_skippable = 0;
7377 int midx, best_mode_index = -1;
7378 unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
7379 vpx_prob comp_mode_p;
7380 int64_t best_intra_rd = INT64_MAX;
7381 unsigned int best_pred_sse = UINT_MAX;
7382 PREDICTION_MODE best_intra_mode = DC_PRED;
7383 int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES];
7384 int64_t dist_uv[TX_SIZES];
7385 int skip_uv[TX_SIZES];
7386 PREDICTION_MODE mode_uv[TX_SIZES];
hui su78b0bd02016-02-23 15:22:25 -08007387 PALETTE_MODE_INFO pmi_uv[TX_SIZES];
hui sube3559b2015-10-07 09:29:02 -07007388#if CONFIG_EXT_INTRA
7389 EXT_INTRA_MODE_INFO ext_intra_mode_info_uv[TX_SIZES];
hui su4aa50c12015-11-10 12:09:59 -08007390 int8_t uv_angle_delta[TX_SIZES];
hui sud7c8bc72015-11-12 19:18:32 -08007391 int is_directional_mode, angle_stats_ready = 0;
hui su4aa50c12015-11-10 12:09:59 -08007392 int rate_overhead, rate_dummy;
hui sud7c8bc72015-11-12 19:18:32 -08007393 uint8_t directional_mode_skip_mask[INTRA_MODES];
hui sube3559b2015-10-07 09:29:02 -07007394#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07007395 const int intra_cost_penalty = vp10_get_intra_cost_penalty(
7396 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
hui su1559afd2015-12-30 10:27:19 -08007397 const int * const intra_mode_cost =
7398 cpi->mbmode_cost[size_group_lookup[bsize]];
Jingning Han3ee6db62015-08-05 19:00:31 -07007399 int best_skip2 = 0;
7400 uint8_t ref_frame_skip_mask[2] = { 0 };
Yue Chen1ac85872016-01-07 15:13:52 -08007401#if CONFIG_EXT_INTER
7402 uint32_t mode_skip_mask[MAX_REF_FRAMES] = { 0 };
7403#else
Jingning Han3ee6db62015-08-05 19:00:31 -07007404 uint16_t mode_skip_mask[MAX_REF_FRAMES] = { 0 };
Yue Chen1ac85872016-01-07 15:13:52 -08007405#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007406 int mode_skip_start = sf->mode_skip_start + 1;
7407 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
7408 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
7409 int64_t mode_threshold[MAX_MODES];
7410 int *mode_map = tile_data->mode_map[bsize];
7411 const int mode_search_skip_flags = sf->mode_search_skip_flags;
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08007412 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
hui su78b0bd02016-02-23 15:22:25 -08007413 int palette_ctx = 0;
7414 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
7415 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
7416 const MODE_INFO *above_mi = xd->above_mi;
7417 const MODE_INFO *left_mi = xd->left_mi;
Yue Chend1cad9c2016-01-27 14:18:53 -08007418#if CONFIG_OBMC
7419#if CONFIG_VP9_HIGHBITDEPTH
7420 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * 64 * 64]);
7421 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * 64 * 64]);
7422#else
7423 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * 64 * 64]);
7424 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * 64 * 64]);
7425#endif // CONFIG_VP9_HIGHBITDEPTH
7426 uint8_t *dst_buf1[3], *dst_buf2[3];
7427 int dst_stride1[3] = {64, 64, 64};
7428 int dst_stride2[3] = {64, 64, 64};
7429
7430#if CONFIG_VP9_HIGHBITDEPTH
7431 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
7432 int len = sizeof(uint16_t);
7433 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
7434 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + 4096 * len);
7435 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 8192 * len);
7436 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
7437 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + 4096 * len);
7438 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 8192 * len);
7439 } else {
7440#endif // CONFIG_VP9_HIGHBITDEPTH
7441 dst_buf1[0] = tmp_buf1;
7442 dst_buf1[1] = tmp_buf1 + 4096;
7443 dst_buf1[2] = tmp_buf1 + 8192;
7444 dst_buf2[0] = tmp_buf2;
7445 dst_buf2[1] = tmp_buf2 + 4096;
7446 dst_buf2[2] = tmp_buf2 + 8192;
7447#if CONFIG_VP9_HIGHBITDEPTH
7448 }
7449#endif // CONFIG_VP9_HIGHBITDEPTH
7450#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007451
7452 vp10_zero(best_mbmode);
hui su78b0bd02016-02-23 15:22:25 -08007453 vp10_zero(pmi_uv);
7454
7455 if (cm->allow_screen_content_tools) {
7456 if (above_mi)
7457 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
7458 if (left_mi)
7459 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
7460 }
Jingning Han3ee6db62015-08-05 19:00:31 -07007461
hui sud7c8bc72015-11-12 19:18:32 -08007462#if CONFIG_EXT_INTRA
7463 memset(directional_mode_skip_mask, 0,
7464 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
7465#endif // CONFIG_EXT_INTRA
7466
Jingning Han3ee6db62015-08-05 19:00:31 -07007467 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
7468 &comp_mode_p);
7469
7470 for (i = 0; i < REFERENCE_MODES; ++i)
7471 best_pred_rd[i] = INT64_MAX;
Jingning Han3ee6db62015-08-05 19:00:31 -07007472 for (i = 0; i < TX_SIZES; i++)
7473 rate_uv_intra[i] = INT_MAX;
7474 for (i = 0; i < MAX_REF_FRAMES; ++i)
7475 x->pred_sse[i] = INT_MAX;
7476 for (i = 0; i < MB_MODE_COUNT; ++i) {
7477 for (k = 0; k < MAX_REF_FRAMES; ++k) {
7478 single_inter_filter[i][k] = SWITCHABLE;
7479 single_skippable[i][k] = 0;
7480 }
7481 }
7482
7483 rd_cost->rate = INT_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08007484#if CONFIG_SUPERTX
7485 *returnrate_nocoef = INT_MAX;
7486#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07007487
7488 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
7489 x->pred_mv_sad[ref_frame] = INT_MAX;
Jingning Han387a10e2015-12-09 09:07:39 -08007490 x->mbmi_ext->mode_context[ref_frame] = 0;
Yue Chen968bbc72016-01-19 16:45:45 -08007491#if CONFIG_REF_MV && CONFIG_EXT_INTER
7492 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
7493#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007494 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
7495 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
7496 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
7497 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
7498 }
7499 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
7500 frame_mv[ZEROMV][ref_frame].as_int = 0;
Yue Chen1ac85872016-01-07 15:13:52 -08007501#if CONFIG_EXT_INTER
7502 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
Yue Chen968bbc72016-01-19 16:45:45 -08007503 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
7504 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
Yue Chen1ac85872016-01-07 15:13:52 -08007505#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007506 }
7507
Jingning Han33cc1bd2016-01-12 15:06:59 -08007508#if CONFIG_REF_MV
7509 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
7510 MODE_INFO *const mi = xd->mi[0];
7511 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
7512 x->mbmi_ext->mode_context[ref_frame] = 0;
7513 vp10_find_mv_refs(cm, xd, mi, ref_frame,
Jingning Han33cc1bd2016-01-12 15:06:59 -08007514 &mbmi_ext->ref_mv_count[ref_frame],
7515 mbmi_ext->ref_mv_stack[ref_frame],
Yue Chen968bbc72016-01-19 16:45:45 -08007516#if CONFIG_EXT_INTER
7517 mbmi_ext->compound_mode_context,
7518#endif // CONFIG_EXT_INTER
Jingning Han33cc1bd2016-01-12 15:06:59 -08007519 candidates, mi_row, mi_col,
7520 NULL, NULL, mbmi_ext->mode_context);
7521 }
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08007522#endif // CONFIG_REF_MV
Jingning Han33cc1bd2016-01-12 15:06:59 -08007523
Yue Chend1cad9c2016-01-27 14:18:53 -08007524#if CONFIG_OBMC
7525 vp10_build_prediction_by_above_preds(cpi, xd, mi_row, mi_col, dst_buf1,
7526 dst_stride1);
7527 vp10_build_prediction_by_left_preds(cpi, xd, mi_row, mi_col, dst_buf2,
7528 dst_stride2);
7529 vp10_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
7530#endif // CONFIG_OBMC
7531
Jingning Han3ee6db62015-08-05 19:00:31 -07007532 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
7533 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
7534 // Skip checking missing references in both single and compound reference
7535 // modes. Note that a mode will be skipped iff both reference frames
7536 // are masked out.
7537 ref_frame_skip_mask[0] |= (1 << ref_frame);
7538 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
Jingning Han1eb760e2015-09-10 12:56:41 -07007539 } else {
Jingning Han3ee6db62015-08-05 19:00:31 -07007540 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
7541 // Skip fixed mv modes for poor references
7542 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
7543 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
7544 break;
7545 }
7546 }
7547 }
7548 // If the segment reference frame feature is enabled....
7549 // then do nothing if the current ref frame is not allowed..
7550 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
7551 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
7552 ref_frame_skip_mask[0] |= (1 << ref_frame);
7553 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7554 }
7555 }
7556
7557 // Disable this drop out case if the ref frame
7558 // segment level feature is enabled for this segment. This is to
7559 // prevent the possibility that we end up unable to pick any mode.
7560 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
7561 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
7562 // unless ARNR filtering is enabled in which case we want
7563 // an unfiltered alternative. We allow near/nearest as well
7564 // because they may result in zero-zero MVs but be cheaper.
7565 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Zoe Liu3ec16012015-11-12 02:12:17 -08007566 ref_frame_skip_mask[0] =
7567 (1 << LAST_FRAME) |
7568#if CONFIG_EXT_REFS
7569 (1 << LAST2_FRAME) |
7570 (1 << LAST3_FRAME) |
7571 (1 << LAST4_FRAME) |
7572#endif // CONFIG_EXT_REFS
7573 (1 << GOLDEN_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07007574 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
7575 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
7576 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != 0)
7577 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
7578 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != 0)
7579 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
Yue Chen968bbc72016-01-19 16:45:45 -08007580#if CONFIG_EXT_INTER
7581 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != 0)
7582 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
7583 if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != 0)
7584 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
7585 if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != 0)
7586 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
7587#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007588 }
7589 }
7590
7591 if (cpi->rc.is_src_frame_alt_ref) {
7592 if (sf->alt_ref_search_fp) {
7593 mode_skip_mask[ALTREF_FRAME] = 0;
7594 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
7595 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
7596 }
7597 }
7598
7599 if (sf->alt_ref_search_fp)
7600 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
7601 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
7602 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
7603
7604 if (sf->adaptive_mode_search) {
7605 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
7606 cpi->rc.frames_since_golden >= 3)
7607 if (x->pred_mv_sad[GOLDEN_FRAME] > (x->pred_mv_sad[LAST_FRAME] << 1))
7608 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
7609 }
7610
7611 if (bsize > sf->max_intra_bsize) {
7612 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
7613 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
7614 }
7615
7616 mode_skip_mask[INTRA_FRAME] |=
7617 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
7618
7619 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i)
7620 mode_threshold[i] = 0;
7621 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
7622 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
7623
7624 midx = sf->schedule_mode_search ? mode_skip_start : 0;
7625 while (midx > 4) {
7626 uint8_t end_pos = 0;
7627 for (i = 5; i < midx; ++i) {
7628 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
7629 uint8_t tmp = mode_map[i];
7630 mode_map[i] = mode_map[i - 1];
7631 mode_map[i - 1] = tmp;
7632 end_pos = i;
7633 }
7634 }
7635 midx = end_pos;
7636 }
7637
7638 for (midx = 0; midx < MAX_MODES; ++midx) {
7639 int mode_index = mode_map[midx];
7640 int mode_excluded = 0;
7641 int64_t this_rd = INT64_MAX;
7642 int disable_skip = 0;
7643 int compmode_cost = 0;
Geza Lore7ded0382016-02-22 10:55:32 +00007644#if CONFIG_EXT_INTER
7645 int compmode_interintra_cost = 0;
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08007646 int compmode_wedge_cost = 0;
Geza Lore7ded0382016-02-22 10:55:32 +00007647#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007648 int rate2 = 0, rate_y = 0, rate_uv = 0;
7649 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
7650 int skippable = 0;
7651 int this_skip2 = 0;
7652 int64_t total_sse = INT64_MAX;
7653 int early_term = 0;
Jingning Han28e03932016-01-20 17:40:47 -08007654#if CONFIG_REF_MV
7655 uint8_t ref_frame_type;
7656#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07007657
7658 this_mode = vp10_mode_order[mode_index].mode;
7659 ref_frame = vp10_mode_order[mode_index].ref_frame[0];
7660 second_ref_frame = vp10_mode_order[mode_index].ref_frame[1];
7661
Yue Chen968bbc72016-01-19 16:45:45 -08007662#if CONFIG_EXT_INTER
Geza Lore7ded0382016-02-22 10:55:32 +00007663 if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
7664 // Mode must by compatible
7665 assert(is_interintra_allowed_mode(this_mode));
7666
7667 if (!is_interintra_allowed_bsize(bsize))
7668 continue;
7669 }
7670
Yue Chen968bbc72016-01-19 16:45:45 -08007671 if (this_mode == NEAREST_NEARESTMV) {
7672 frame_mv[NEAREST_NEARESTMV][ref_frame].as_int =
7673 frame_mv[NEARESTMV][ref_frame].as_int;
7674 frame_mv[NEAREST_NEARESTMV][second_ref_frame].as_int =
7675 frame_mv[NEARESTMV][second_ref_frame].as_int;
7676 } else if (this_mode == NEAREST_NEARMV) {
7677 frame_mv[NEAREST_NEARMV][ref_frame].as_int =
7678 frame_mv[NEARESTMV][ref_frame].as_int;
7679 frame_mv[NEAREST_NEARMV][second_ref_frame].as_int =
7680 frame_mv[NEARMV][second_ref_frame].as_int;
7681 } else if (this_mode == NEAR_NEARESTMV) {
7682 frame_mv[NEAR_NEARESTMV][ref_frame].as_int =
7683 frame_mv[NEARMV][ref_frame].as_int;
7684 frame_mv[NEAR_NEARESTMV][second_ref_frame].as_int =
7685 frame_mv[NEARESTMV][second_ref_frame].as_int;
7686 } else if (this_mode == NEAREST_NEWMV) {
7687 frame_mv[NEAREST_NEWMV][ref_frame].as_int =
7688 frame_mv[NEARESTMV][ref_frame].as_int;
7689 frame_mv[NEAREST_NEWMV][second_ref_frame].as_int =
7690 frame_mv[NEWMV][second_ref_frame].as_int;
7691 } else if (this_mode == NEW_NEARESTMV) {
7692 frame_mv[NEW_NEARESTMV][ref_frame].as_int =
7693 frame_mv[NEWMV][ref_frame].as_int;
7694 frame_mv[NEW_NEARESTMV][second_ref_frame].as_int =
7695 frame_mv[NEARESTMV][second_ref_frame].as_int;
7696 } else if (this_mode == NEAR_NEWMV) {
7697 frame_mv[NEAR_NEWMV][ref_frame].as_int =
7698 frame_mv[NEARMV][ref_frame].as_int;
7699 frame_mv[NEAR_NEWMV][second_ref_frame].as_int =
7700 frame_mv[NEWMV][second_ref_frame].as_int;
7701 } else if (this_mode == NEW_NEARMV) {
7702 frame_mv[NEW_NEARMV][ref_frame].as_int =
7703 frame_mv[NEWMV][ref_frame].as_int;
7704 frame_mv[NEW_NEARMV][second_ref_frame].as_int =
7705 frame_mv[NEARMV][second_ref_frame].as_int;
7706 } else if (this_mode == NEW_NEWMV) {
7707 frame_mv[NEW_NEWMV][ref_frame].as_int =
7708 frame_mv[NEWMV][ref_frame].as_int;
7709 frame_mv[NEW_NEWMV][second_ref_frame].as_int =
7710 frame_mv[NEWMV][second_ref_frame].as_int;
7711 }
7712#endif // CONFIG_EXT_INTER
7713
Jingning Han3ee6db62015-08-05 19:00:31 -07007714 // Look at the reference frame of the best mode so far and set the
7715 // skip mask to look at a subset of the remaining modes.
7716 if (midx == mode_skip_start && best_mode_index >= 0) {
7717 switch (best_mbmode.ref_frame[0]) {
7718 case INTRA_FRAME:
7719 break;
7720 case LAST_FRAME:
7721 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
7722 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7723 break;
Zoe Liu3ec16012015-11-12 02:12:17 -08007724#if CONFIG_EXT_REFS
7725 case LAST2_FRAME:
7726 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
7727 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7728 break;
7729 case LAST3_FRAME:
7730 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
7731 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7732 break;
7733 case LAST4_FRAME:
7734 ref_frame_skip_mask[0] |= LAST4_FRAME_MODE_MASK;
7735 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7736 break;
7737#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07007738 case GOLDEN_FRAME:
7739 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
7740 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7741 break;
7742 case ALTREF_FRAME:
7743 ref_frame_skip_mask[0] |= ALT_REF_MODE_MASK;
7744 break;
7745 case NONE:
7746 case MAX_REF_FRAMES:
7747 assert(0 && "Invalid Reference frame");
7748 break;
7749 }
7750 }
7751
7752 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
James Zern5e16d392015-08-17 18:19:22 -07007753 (ref_frame_skip_mask[1] & (1 << VPXMAX(0, second_ref_frame))))
Jingning Han3ee6db62015-08-05 19:00:31 -07007754 continue;
7755
7756 if (mode_skip_mask[ref_frame] & (1 << this_mode))
7757 continue;
7758
7759 // Test best rd so far against threshold for trying this mode.
7760 if (best_mode_skippable && sf->schedule_mode_search)
7761 mode_threshold[mode_index] <<= 1;
7762
7763 if (best_rd < mode_threshold[mode_index])
7764 continue;
7765
Jingning Han3ee6db62015-08-05 19:00:31 -07007766 comp_pred = second_ref_frame > INTRA_FRAME;
7767 if (comp_pred) {
7768 if (!cpi->allow_comp_inter_inter)
7769 continue;
7770
7771 // Skip compound inter modes if ARF is not available.
7772 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
7773 continue;
7774
7775 // Do not allow compound prediction if the segment level reference frame
7776 // feature is in use as in this case there can only be one reference.
7777 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
7778 continue;
7779
7780 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
7781 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
7782 continue;
7783
7784 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
7785 } else {
7786 if (ref_frame != INTRA_FRAME)
7787 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
7788 }
7789
7790 if (ref_frame == INTRA_FRAME) {
7791 if (sf->adaptive_mode_search)
7792 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
7793 continue;
7794
7795 if (this_mode != DC_PRED) {
7796 // Disable intra modes other than DC_PRED for blocks with low variance
7797 // Threshold for intra skipping based on source variance
7798 // TODO(debargha): Specialize the threshold for super block sizes
7799 const unsigned int skip_intra_var_thresh = 64;
7800 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
7801 x->source_variance < skip_intra_var_thresh)
7802 continue;
7803 // Only search the oblique modes if the best so far is
7804 // one of the neighboring directional modes
7805 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
7806 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
7807 if (best_mode_index >= 0 &&
7808 best_mbmode.ref_frame[0] > INTRA_FRAME)
7809 continue;
7810 }
7811 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
7812 if (conditional_skipintra(this_mode, best_intra_mode))
7813 continue;
7814 }
7815 }
7816 } else {
7817 const MV_REFERENCE_FRAME ref_frames[2] = {ref_frame, second_ref_frame};
Yue Chen968bbc72016-01-19 16:45:45 -08007818 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
7819#if CONFIG_REF_MV && CONFIG_EXT_INTER
7820 mbmi_ext->compound_mode_context,
7821#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
7822 frame_mv,
Jingning Han387a10e2015-12-09 09:07:39 -08007823 this_mode, ref_frames, bsize, -1))
Jingning Han3ee6db62015-08-05 19:00:31 -07007824 continue;
7825 }
7826
7827 mbmi->mode = this_mode;
7828 mbmi->uv_mode = DC_PRED;
7829 mbmi->ref_frame[0] = ref_frame;
7830 mbmi->ref_frame[1] = second_ref_frame;
hui su78b0bd02016-02-23 15:22:25 -08007831 pmi->palette_size[0] = 0;
7832 pmi->palette_size[1] = 0;
hui sube3559b2015-10-07 09:29:02 -07007833#if CONFIG_EXT_INTRA
7834 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
7835 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
7836#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07007837 // Evaluate all sub-pel filters irrespective of whether we can use
7838 // them for this frame.
Debargha Mukherjeebab29122016-02-26 00:18:03 -08007839 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
Jingning Han3ee6db62015-08-05 19:00:31 -07007840 : cm->interp_filter;
7841 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chend1cad9c2016-01-27 14:18:53 -08007842#if CONFIG_OBMC
7843 mbmi->obmc = 0;
7844#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007845
7846 x->skip = 0;
7847 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
7848
7849 // Select prediction reference frames.
7850 for (i = 0; i < MAX_MB_PLANE; i++) {
7851 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
7852 if (comp_pred)
7853 xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
7854 }
7855
Geza Lore7ded0382016-02-22 10:55:32 +00007856#if CONFIG_EXT_INTER
7857 mbmi->interintra_mode = (PREDICTION_MODE)(DC_PRED - 1);
7858 mbmi->interintra_uv_mode = (PREDICTION_MODE)(DC_PRED - 1);
7859#endif // CONFIG_EXT_INTER
7860
Jingning Han3ee6db62015-08-05 19:00:31 -07007861 if (ref_frame == INTRA_FRAME) {
7862 TX_SIZE uv_tx;
7863 struct macroblockd_plane *const pd = &xd->plane[1];
7864 memset(x->skip_txfm, 0, sizeof(x->skip_txfm));
hui sube3559b2015-10-07 09:29:02 -07007865#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08007866 is_directional_mode = (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED);
7867 if (is_directional_mode) {
hui sud7c8bc72015-11-12 19:18:32 -08007868 if (!angle_stats_ready) {
7869 const int src_stride = x->plane[0].src.stride;
7870 const uint8_t *src = x->plane[0].src.buf;
7871 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
7872 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
7873 double hist[DIRECTIONAL_MODES];
7874 PREDICTION_MODE mode;
7875
7876#if CONFIG_VP9_HIGHBITDEPTH
7877 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
7878 highbd_angle_estimation(src, src_stride, rows, cols, hist);
7879 else
7880#endif
7881 angle_estimation(src, src_stride, rows, cols, hist);
7882 for (mode = 0; mode < INTRA_MODES; ++mode) {
7883 if (mode != DC_PRED && mode != TM_PRED) {
7884 int index = get_angle_index((double)mode_to_angle_map[mode]);
7885 double score, weight = 1.0;
7886 score = hist[index];
7887 if (index > 0) {
7888 score += hist[index - 1] * 0.5;
7889 weight += 0.5;
7890 }
7891 if (index < DIRECTIONAL_MODES - 1) {
7892 score += hist[index + 1] * 0.5;
7893 weight += 0.5;
7894 }
7895 score /= weight;
7896 if (score < ANGLE_SKIP_THRESH)
7897 directional_mode_skip_mask[mode] = 1;
7898 }
7899 }
7900 angle_stats_ready = 1;
7901 }
7902 if (directional_mode_skip_mask[mbmi->mode])
7903 continue;
hui su4aa50c12015-11-10 12:09:59 -08007904 rate_overhead = write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0) +
hui su1559afd2015-12-30 10:27:19 -08007905 intra_mode_cost[mbmi->mode];
hui su4aa50c12015-11-10 12:09:59 -08007906 rate_y = INT_MAX;
7907 this_rd =
7908 rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
7909 &skippable, bsize, rate_overhead, best_rd);
7910 } else {
7911 mbmi->angle_delta[0] = 0;
7912 super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
7913 NULL, bsize, best_rd);
7914 }
7915
hui sube3559b2015-10-07 09:29:02 -07007916 // TODO(huisu): ext-intra is turned off in lossless mode for now to
7917 // avoid a unit test failure
hui su4aa50c12015-11-10 12:09:59 -08007918 if (mbmi->mode == DC_PRED && !xd->lossless[mbmi->segment_id] &&
7919 ALLOW_FILTER_INTRA_MODES) {
hui sube3559b2015-10-07 09:29:02 -07007920 MB_MODE_INFO mbmi_copy = *mbmi;
hui sube3559b2015-10-07 09:29:02 -07007921
7922 if (rate_y != INT_MAX) {
hui su1559afd2015-12-30 10:27:19 -08007923 int this_rate = rate_y + intra_mode_cost[mbmi->mode] +
hui sube3559b2015-10-07 09:29:02 -07007924 vp10_cost_bit(cm->fc->ext_intra_probs[0], 0);
7925 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, distortion_y);
7926 } else {
7927 this_rd = best_rd;
7928 }
7929
7930 if (!rd_pick_ext_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
7931 &skippable, bsize,
hui su1559afd2015-12-30 10:27:19 -08007932 intra_mode_cost[mbmi->mode], &this_rd))
hui sube3559b2015-10-07 09:29:02 -07007933 *mbmi = mbmi_copy;
7934 }
hui su4aa50c12015-11-10 12:09:59 -08007935#else
7936 super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
7937 NULL, bsize, best_rd);
hui sube3559b2015-10-07 09:29:02 -07007938#endif // CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08007939
Jingning Han3ee6db62015-08-05 19:00:31 -07007940 if (rate_y == INT_MAX)
7941 continue;
Jingning Han3ee6db62015-08-05 19:00:31 -07007942 uv_tx = get_uv_tx_size_impl(mbmi->tx_size, bsize, pd->subsampling_x,
7943 pd->subsampling_y);
7944 if (rate_uv_intra[uv_tx] == INT_MAX) {
7945 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx,
7946 &rate_uv_intra[uv_tx], &rate_uv_tokenonly[uv_tx],
7947 &dist_uv[uv_tx], &skip_uv[uv_tx], &mode_uv[uv_tx]);
hui su78b0bd02016-02-23 15:22:25 -08007948 if (cm->allow_screen_content_tools)
7949 pmi_uv[uv_tx] = *pmi;
hui sube3559b2015-10-07 09:29:02 -07007950#if CONFIG_EXT_INTRA
7951 ext_intra_mode_info_uv[uv_tx] = mbmi->ext_intra_mode_info;
hui su4aa50c12015-11-10 12:09:59 -08007952 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui sube3559b2015-10-07 09:29:02 -07007953#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07007954 }
7955
7956 rate_uv = rate_uv_tokenonly[uv_tx];
7957 distortion_uv = dist_uv[uv_tx];
7958 skippable = skippable && skip_uv[uv_tx];
7959 mbmi->uv_mode = mode_uv[uv_tx];
hui su78b0bd02016-02-23 15:22:25 -08007960 if (cm->allow_screen_content_tools) {
7961 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
7962 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
7963 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
7964 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
7965 }
hui sube3559b2015-10-07 09:29:02 -07007966#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08007967 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui sube3559b2015-10-07 09:29:02 -07007968 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
7969 ext_intra_mode_info_uv[uv_tx].use_ext_intra_mode[1];
7970 if (ext_intra_mode_info_uv[uv_tx].use_ext_intra_mode[1]) {
7971 mbmi->ext_intra_mode_info.ext_intra_mode[1] =
7972 ext_intra_mode_info_uv[uv_tx].ext_intra_mode[1];
hui sube3559b2015-10-07 09:29:02 -07007973 }
7974#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07007975
hui su1559afd2015-12-30 10:27:19 -08007976 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv_intra[uv_tx];
hui su78b0bd02016-02-23 15:22:25 -08007977 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
7978 rate2 +=
7979 vp10_cost_bit(vp10_default_palette_y_mode_prob[bsize - BLOCK_8X8]
7980 [palette_ctx], 0);
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08007981
7982 if (!xd->lossless[mbmi->segment_id]) {
7983 // super_block_yrd above includes the cost of the tx_size in the
7984 // tokenonly rate, but for intra blocks, tx_size is always coded
7985 // (prediction granularity), so we account for it in the full rate,
7986 // not the tokenonly rate.
hui su954e5602016-03-07 15:25:50 -08007987 rate_y -=
7988 cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
7989 [mbmi->tx_size];
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08007990 }
hui sube3559b2015-10-07 09:29:02 -07007991#if CONFIG_EXT_INTRA
hui su3b1c7662016-01-12 16:38:58 -08007992 if (is_directional_mode) {
7993 int p_angle;
7994 const int intra_filter_ctx = vp10_get_pred_context_intra_interp(xd);
hui su4aa50c12015-11-10 12:09:59 -08007995 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
7996 MAX_ANGLE_DELTAS +
7997 mbmi->angle_delta[0]);
hui su3b1c7662016-01-12 16:38:58 -08007998 p_angle = mode_to_angle_map[mbmi->mode] +
7999 mbmi->angle_delta[0] * ANGLE_STEP;
8000 if (pick_intra_filter(p_angle))
8001 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
8002 }
hui su4aa50c12015-11-10 12:09:59 -08008003
8004 if (mbmi->mode == DC_PRED && ALLOW_FILTER_INTRA_MODES) {
hui sube3559b2015-10-07 09:29:02 -07008005 rate2 += vp10_cost_bit(cm->fc->ext_intra_probs[0],
8006 mbmi->ext_intra_mode_info.use_ext_intra_mode[0]);
8007 if (mbmi->ext_intra_mode_info.use_ext_intra_mode[0]) {
8008 EXT_INTRA_MODE ext_intra_mode =
8009 mbmi->ext_intra_mode_info.ext_intra_mode[0];
hui su4aa50c12015-11-10 12:09:59 -08008010 rate2 += write_uniform_cost(FILTER_INTRA_MODES, ext_intra_mode);
hui sube3559b2015-10-07 09:29:02 -07008011 }
8012 }
8013#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07008014 if (this_mode != DC_PRED && this_mode != TM_PRED)
8015 rate2 += intra_cost_penalty;
8016 distortion2 = distortion_y + distortion_uv;
8017 } else {
Geza Lore7ded0382016-02-22 10:55:32 +00008018#if CONFIG_EXT_INTER
8019 if (second_ref_frame == INTRA_FRAME) {
8020 mbmi->interintra_mode = best_intra_mode;
8021 mbmi->interintra_uv_mode = best_intra_mode;
8022#if CONFIG_EXT_INTRA
8023 // TODO(debargha|geza.lore):
8024 // Should we use ext_intra modes for interintra?
8025 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
8026 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
8027 mbmi->angle_delta[0] = 0;
8028 mbmi->angle_delta[1] = 0;
8029 mbmi->intra_filter = INTRA_FILTER_LINEAR;
8030#endif // CONFIG_EXT_INTRA
8031 }
8032#endif // CONFIG_EXT_INTER
Jingning Han28e03932016-01-20 17:40:47 -08008033#if CONFIG_REF_MV
8034 mbmi->ref_mv_idx = 0;
8035 ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
8036#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07008037 this_rd = handle_inter_mode(cpi, x, bsize,
8038 &rate2, &distortion2, &skippable,
8039 &rate_y, &rate_uv,
8040 &disable_skip, frame_mv,
8041 mi_row, mi_col,
Yue Chend1cad9c2016-01-27 14:18:53 -08008042#if CONFIG_OBMC
8043 dst_buf1, dst_stride1,
8044 dst_buf2, dst_stride2,
8045#endif // CONFIG_OBMC
Yue Chen1ac85872016-01-07 15:13:52 -08008046#if CONFIG_EXT_INTER
8047 single_newmvs,
Geza Lore7ded0382016-02-22 10:55:32 +00008048 single_newmvs_rate,
8049 &compmode_interintra_cost,
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08008050 &compmode_wedge_cost,
Yue Chen1ac85872016-01-07 15:13:52 -08008051#else
8052 single_newmv,
8053#endif // CONFIG_EXT_INTER
8054 single_inter_filter,
Geza Lore7ded0382016-02-22 10:55:32 +00008055 single_skippable,
Angie Chiangb6fef122016-03-11 16:01:46 -08008056 &total_sse, best_rd);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07008057
Jingning Han67cf8902016-01-15 09:05:51 -08008058#if CONFIG_REF_MV
Jingning Han4fb8b212016-01-19 16:36:25 -08008059 // TODO(jingning): This needs some refactoring to improve code quality
8060 // and reduce redundant steps.
Jingning Han28e03932016-01-20 17:40:47 -08008061 if (mbmi->mode == NEARMV &&
8062 mbmi_ext->ref_mv_count[ref_frame_type] > 2) {
Jingning Han67cf8902016-01-15 09:05:51 -08008063 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
8064 int_mv cur_mv = mbmi_ext->ref_mv_stack[ref_frame][2].this_mv;
8065 MB_MODE_INFO backup_mbmi = *mbmi;
Yaowu Xu4fcc4f82016-03-16 15:05:04 -07008066 int backup_skip = x->skip;
Jingning Han67cf8902016-01-15 09:05:51 -08008067
Jingning Han4fb8b212016-01-19 16:36:25 -08008068 int64_t tmp_ref_rd = this_rd;
8069 int ref_idx;
Jingning Han28e03932016-01-20 17:40:47 -08008070 int ref_set = VPXMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 2);
8071
Jingning Han49589872016-01-21 18:07:31 -08008072 uint8_t drl0_ctx =
Jingning Hana39e83d2016-02-11 16:38:13 -08008073 vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 1);
Jingning Han49589872016-01-21 18:07:31 -08008074 rate2 += cpi->drl_mode_cost0[drl0_ctx][0];
Jingning Han67cf8902016-01-15 09:05:51 -08008075
Jingning Han590265e2016-01-15 11:33:40 -08008076 if (this_rd < INT64_MAX) {
8077 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
8078 RDCOST(x->rdmult, x->rddiv, 0, total_sse))
8079 tmp_ref_rd = RDCOST(x->rdmult, x->rddiv,
8080 rate2 + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0),
8081 distortion2);
8082 else
8083 tmp_ref_rd = RDCOST(x->rdmult, x->rddiv,
8084 rate2 + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1) -
8085 rate_y - rate_uv,
8086 total_sse);
8087 }
Jingning Han7174d632016-03-03 09:20:10 -08008088#if CONFIG_VAR_TX
8089 for (i = 0; i < MAX_MB_PLANE; ++i)
8090 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
8091 sizeof(uint8_t) * ctx->num_4x4_blk);
8092#endif
Jingning Han590265e2016-01-15 11:33:40 -08008093
Jingning Han4fb8b212016-01-19 16:36:25 -08008094 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
8095 int64_t tmp_alt_rd = INT64_MAX;
8096 int tmp_rate = 0, tmp_rate_y = 0, tmp_rate_uv = 0;
8097 int tmp_skip = 1;
8098 int64_t tmp_dist = 0, tmp_sse = 0;
Yaowu Xu4fcc4f82016-03-16 15:05:04 -07008099 int dummy_disable_skip = 0;
Jingning Han590265e2016-01-15 11:33:40 -08008100
Jingning Han4fb8b212016-01-19 16:36:25 -08008101 cur_mv = mbmi_ext->ref_mv_stack[ref_frame][2 + ref_idx].this_mv;
8102 lower_mv_precision(&cur_mv.as_mv, cm->allow_high_precision_mv);
8103 clamp_mv2(&cur_mv.as_mv, xd);
8104
8105 if (!mv_check_bounds(x, &cur_mv.as_mv)) {
Jingning Han4fb8b212016-01-19 16:36:25 -08008106 INTERP_FILTER dummy_single_inter_filter[MB_MODE_COUNT]
8107 [MAX_REF_FRAMES];
8108 int dummy_single_skippable[MB_MODE_COUNT][MAX_REF_FRAMES];
8109 int dummy_disable_skip = 0;
Jingning Han4fb8b212016-01-19 16:36:25 -08008110#if CONFIG_EXT_INTER
8111 int_mv dummy_single_newmvs[2][MAX_REF_FRAMES] =
8112 { { { 0 } }, { { 0 } } };
Geza Lore7ded0382016-02-22 10:55:32 +00008113 int dummy_single_newmvs_rate[2][MAX_REF_FRAMES] =
8114 { { 0 }, { 0 } };
8115 int dummy_compmode_interintra_cost = 0;
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08008116 int dummy_compmode_wedge_cost = 0;
Jingning Han4fb8b212016-01-19 16:36:25 -08008117#else
8118 int_mv dummy_single_newmv[MAX_REF_FRAMES] = { { 0 } };
8119#endif
Jingning Han28e03932016-01-20 17:40:47 -08008120 mbmi->ref_mv_idx = 1 + ref_idx;
8121
Jingning Han4fb8b212016-01-19 16:36:25 -08008122 frame_mv[NEARMV][ref_frame] = cur_mv;
8123 tmp_alt_rd = handle_inter_mode(cpi, x, bsize,
8124 &tmp_rate, &tmp_dist, &tmp_skip,
8125 &tmp_rate_y, &tmp_rate_uv,
8126 &dummy_disable_skip, frame_mv,
8127 mi_row, mi_col,
Yue Chend1cad9c2016-01-27 14:18:53 -08008128#if CONFIG_OBMC
8129 dst_buf1, dst_stride1,
8130 dst_buf2, dst_stride2,
8131#endif // CONFIG_OBMC
Jingning Han4fb8b212016-01-19 16:36:25 -08008132#if CONFIG_EXT_INTER
8133 dummy_single_newmvs,
Geza Lore7ded0382016-02-22 10:55:32 +00008134 dummy_single_newmvs_rate,
8135 &dummy_compmode_interintra_cost,
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08008136 &dummy_compmode_wedge_cost,
Jingning Han4fb8b212016-01-19 16:36:25 -08008137#else
8138 dummy_single_newmv,
8139#endif
8140 dummy_single_inter_filter,
8141 dummy_single_skippable,
Angie Chiangb6fef122016-03-11 16:01:46 -08008142 &tmp_sse, best_rd);
Jingning Han4fb8b212016-01-19 16:36:25 -08008143 }
8144
Jingning Han49589872016-01-21 18:07:31 -08008145 tmp_rate += cpi->drl_mode_cost0[drl0_ctx][1];
8146
8147 if (mbmi_ext->ref_mv_count[ref_frame_type] > 3) {
8148 uint8_t drl1_ctx =
Jingning Hana39e83d2016-02-11 16:38:13 -08008149 vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 2);
Jingning Han49589872016-01-21 18:07:31 -08008150 tmp_rate += cpi->drl_mode_cost1[drl1_ctx][ref_idx];
8151 }
Jingning Han4fb8b212016-01-19 16:36:25 -08008152
8153 if (tmp_alt_rd < INT64_MAX) {
Yue Chena6142622016-02-18 12:35:14 -08008154#if CONFIG_OBMC
8155 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv, tmp_rate, tmp_dist);
8156#else
Jingning Han4fb8b212016-01-19 16:36:25 -08008157 if (RDCOST(x->rdmult, x->rddiv,
8158 tmp_rate_y + tmp_rate_uv, tmp_dist) <
8159 RDCOST(x->rdmult, x->rddiv, 0, tmp_sse))
8160 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv,
8161 tmp_rate + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0),
8162 tmp_dist);
8163 else
8164 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv,
8165 tmp_rate + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1) -
8166 tmp_rate_y - tmp_rate_uv,
8167 tmp_sse);
Yue Chena6142622016-02-18 12:35:14 -08008168#endif // CONFIG_OBMC
Jingning Han4fb8b212016-01-19 16:36:25 -08008169 }
8170
8171 if (tmp_ref_rd > tmp_alt_rd) {
8172 rate2 = tmp_rate;
Yaowu Xu4fcc4f82016-03-16 15:05:04 -07008173 disable_skip = dummy_disable_skip;
Jingning Han4fb8b212016-01-19 16:36:25 -08008174 distortion2 = tmp_dist;
8175 skippable = tmp_skip;
8176 rate_y = tmp_rate_y;
8177 rate_uv = tmp_rate_uv;
8178 total_sse = tmp_sse;
8179 this_rd = tmp_alt_rd;
Jingning Han4fb8b212016-01-19 16:36:25 -08008180 tmp_ref_rd = tmp_alt_rd;
8181 backup_mbmi = *mbmi;
Yaowu Xu4fcc4f82016-03-16 15:05:04 -07008182 backup_skip = x->skip;
Jingning Han7174d632016-03-03 09:20:10 -08008183#if CONFIG_VAR_TX
8184 for (i = 0; i < MAX_MB_PLANE; ++i)
8185 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
8186 sizeof(uint8_t) * ctx->num_4x4_blk);
8187#endif
Jingning Han4fb8b212016-01-19 16:36:25 -08008188 } else {
8189 *mbmi = backup_mbmi;
Yaowu Xu4fcc4f82016-03-16 15:05:04 -07008190 x->skip = backup_skip;
Jingning Han4fb8b212016-01-19 16:36:25 -08008191 }
Jingning Han67cf8902016-01-15 09:05:51 -08008192 }
8193
8194 frame_mv[NEARMV][ref_frame] = backup_mv;
Jingning Han7174d632016-03-03 09:20:10 -08008195#if CONFIG_VAR_TX
8196 for (i = 0; i < MAX_MB_PLANE; ++i)
8197 memcpy(x->blk_skip[i], x->blk_skip_drl[i],
8198 sizeof(uint8_t) * ctx->num_4x4_blk);
8199#endif
Jingning Han67cf8902016-01-15 09:05:51 -08008200 }
Geza Lore7ded0382016-02-22 10:55:32 +00008201#endif // CONFIG_REF_MV
Jingning Han67cf8902016-01-15 09:05:51 -08008202
Jingning Han3ee6db62015-08-05 19:00:31 -07008203 if (this_rd == INT64_MAX)
8204 continue;
8205
8206 compmode_cost = vp10_cost_bit(comp_mode_p, comp_pred);
8207
8208 if (cm->reference_mode == REFERENCE_MODE_SELECT)
8209 rate2 += compmode_cost;
8210 }
8211
Geza Lore7ded0382016-02-22 10:55:32 +00008212#if CONFIG_EXT_INTER
8213 rate2 += compmode_interintra_cost;
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08008214 if (cm->reference_mode != SINGLE_REFERENCE && comp_pred)
8215 rate2 += compmode_wedge_cost;
Geza Lore7ded0382016-02-22 10:55:32 +00008216#endif // CONFIG_EXT_INTER
8217
Jingning Han3ee6db62015-08-05 19:00:31 -07008218 // Estimate the reference frame signaling cost and add it
8219 // to the rolling cost variable.
8220 if (comp_pred) {
8221 rate2 += ref_costs_comp[ref_frame];
8222 } else {
8223 rate2 += ref_costs_single[ref_frame];
8224 }
8225
Yue Chena6142622016-02-18 12:35:14 -08008226#if CONFIG_OBMC
8227 if (ref_frame == INTRA_FRAME) {
8228#else
Jingning Han3ee6db62015-08-05 19:00:31 -07008229 if (!disable_skip) {
Yue Chena6142622016-02-18 12:35:14 -08008230#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07008231 if (skippable) {
8232 // Back out the coefficient coding costs
8233 rate2 -= (rate_y + rate_uv);
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008234 rate_y = 0;
8235 rate_uv = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07008236 // Cost the skip mb case
8237 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04008238 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Jingning Han3ee6db62015-08-05 19:00:31 -07008239 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
8240 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
8241 // Add in the cost of the no skip flag.
8242 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
8243 } else {
8244 // FIXME(rbultje) make this work for splitmv also
8245 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
8246 distortion2 = total_sse;
8247 assert(total_sse >= 0);
8248 rate2 -= (rate_y + rate_uv);
8249 this_skip2 = 1;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008250 rate_y = 0;
8251 rate_uv = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07008252 }
8253 } else {
8254 // Add in the cost of the no skip flag.
8255 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
8256 }
8257
8258 // Calculate the final RD estimate for this mode.
8259 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yue Chena6142622016-02-18 12:35:14 -08008260#if CONFIG_OBMC
8261 } else {
8262 this_skip2 = mbmi->skip;
8263 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
8264#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07008265 }
8266
Yue Chena6142622016-02-18 12:35:14 -08008267
Jingning Han3ee6db62015-08-05 19:00:31 -07008268 // Apply an adjustment to the rd value based on the similarity of the
8269 // source variance and reconstructed variance.
Yue Chena6142622016-02-18 12:35:14 -08008270 rd_variance_adjustment(cpi, x, bsize, &this_rd, ref_frame,
8271#if CONFIG_OBMC
8272 is_inter_block(mbmi),
8273#endif // CONFIG_OBMC
8274 x->source_variance);
Jingning Han3ee6db62015-08-05 19:00:31 -07008275
8276 if (ref_frame == INTRA_FRAME) {
8277 // Keep record of best intra rd
8278 if (this_rd < best_intra_rd) {
8279 best_intra_rd = this_rd;
8280 best_intra_mode = mbmi->mode;
8281 }
8282 }
8283
8284 if (!disable_skip && ref_frame == INTRA_FRAME) {
8285 for (i = 0; i < REFERENCE_MODES; ++i)
James Zern5e16d392015-08-17 18:19:22 -07008286 best_pred_rd[i] = VPXMIN(best_pred_rd[i], this_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07008287 }
8288
8289 // Did this mode help.. i.e. is it the new best mode
8290 if (this_rd < best_rd || x->skip) {
8291 int max_plane = MAX_MB_PLANE;
8292 if (!mode_excluded) {
8293 // Note index of best mode so far
8294 best_mode_index = mode_index;
8295
8296 if (ref_frame == INTRA_FRAME) {
8297 /* required for left and above block mv */
8298 mbmi->mv[0].as_int = 0;
8299 max_plane = 1;
8300 } else {
8301 best_pred_sse = x->pred_sse[ref_frame];
8302 }
8303
8304 rd_cost->rate = rate2;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008305#if CONFIG_SUPERTX
Yaowu Xu2becffa2016-03-15 12:36:21 -07008306 if (x->skip && rate_y == INT_MAX)
8307 *returnrate_nocoef = rate2;
8308 else
8309 *returnrate_nocoef = rate2 - rate_y - rate_uv;
8310 *returnrate_nocoef -= vp10_cost_bit(vp10_get_skip_prob(cm, xd),
8311 disable_skip || skippable || this_skip2);
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008312 *returnrate_nocoef -= vp10_cost_bit(vp10_get_intra_inter_prob(cm, xd),
8313 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chend1cad9c2016-01-27 14:18:53 -08008314#if CONFIG_OBMC
8315 if (is_inter_block(mbmi) && is_obmc_allowed(mbmi))
8316 *returnrate_nocoef -= cpi->obmc_cost[bsize][mbmi->obmc];
8317#endif // CONFIG_OBMC
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008318#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07008319 rd_cost->dist = distortion2;
8320 rd_cost->rdcost = this_rd;
8321 best_rd = this_rd;
8322 best_mbmode = *mbmi;
8323 best_skip2 = this_skip2;
8324 best_mode_skippable = skippable;
8325
8326 if (!x->select_tx_size)
8327 swap_block_ptr(x, ctx, 1, 0, 0, max_plane);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07008328
8329#if CONFIG_VAR_TX
8330 for (i = 0; i < MAX_MB_PLANE; ++i)
8331 memcpy(ctx->blk_skip[i], x->blk_skip[i],
8332 sizeof(uint8_t) * ctx->num_4x4_blk);
8333#else
Jingning Han3ee6db62015-08-05 19:00:31 -07008334 memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
hui su088b05f2015-08-12 10:41:51 -07008335 sizeof(ctx->zcoeff_blk[0]) * ctx->num_4x4_blk);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07008336#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07008337
8338 // TODO(debargha): enhance this test with a better distortion prediction
8339 // based on qp, activity mask and history
8340 if ((mode_search_skip_flags & FLAG_EARLY_TERMINATE) &&
8341 (mode_index > MIN_EARLY_TERM_INDEX)) {
8342 int qstep = xd->plane[0].dequant[1];
8343 // TODO(debargha): Enhance this by specializing for each mode_index
8344 int scale = 4;
8345#if CONFIG_VP9_HIGHBITDEPTH
8346 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
8347 qstep >>= (xd->bd - 8);
8348 }
8349#endif // CONFIG_VP9_HIGHBITDEPTH
8350 if (x->source_variance < UINT_MAX) {
8351 const int var_adjust = (x->source_variance < 16);
8352 scale -= var_adjust;
8353 }
8354 if (ref_frame > INTRA_FRAME &&
8355 distortion2 * scale < qstep * qstep) {
8356 early_term = 1;
8357 }
8358 }
8359 }
8360 }
8361
8362 /* keep record of best compound/single-only prediction */
8363 if (!disable_skip && ref_frame != INTRA_FRAME) {
8364 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
8365
8366 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
8367 single_rate = rate2 - compmode_cost;
8368 hybrid_rate = rate2;
8369 } else {
8370 single_rate = rate2;
8371 hybrid_rate = rate2 + compmode_cost;
8372 }
8373
8374 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
8375 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
8376
8377 if (!comp_pred) {
8378 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
8379 best_pred_rd[SINGLE_REFERENCE] = single_rd;
8380 } else {
8381 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
8382 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
8383 }
8384 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
8385 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
Jingning Han3ee6db62015-08-05 19:00:31 -07008386 }
8387
8388 if (early_term)
8389 break;
8390
8391 if (x->skip && !comp_pred)
8392 break;
8393 }
8394
hui su78b0bd02016-02-23 15:22:25 -08008395 // Only try palette mode when the best mode so far is an intra mode.
8396 if (cm->allow_screen_content_tools && !is_inter_mode(best_mbmode.mode)) {
8397 PREDICTION_MODE mode_selected;
8398 int rate2 = 0, rate_y = 0;
8399 int64_t distortion2 = 0, distortion_y = 0, dummy_rd = best_rd, this_rd;
8400 int skippable = 0, rate_overhead = 0;
8401 TX_SIZE best_tx_size, uv_tx;
8402 PALETTE_MODE_INFO palette_mode_info;
8403 uint8_t *const best_palette_color_map =
8404 x->palette_buffer->best_palette_color_map;
8405 uint8_t *const color_map = xd->plane[0].color_index_map;
8406
8407 mbmi->mode = DC_PRED;
8408 mbmi->uv_mode = DC_PRED;
8409 mbmi->ref_frame[0] = INTRA_FRAME;
8410 mbmi->ref_frame[1] = NONE;
8411 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
8412 palette_mode_info.palette_size[0] = 0;
8413 rate_overhead =
8414 rd_pick_palette_intra_sby(cpi, x, bsize, palette_ctx,
8415 intra_mode_cost[DC_PRED],
8416 &palette_mode_info, best_palette_color_map,
8417 &best_tx_size, &mode_selected, &dummy_rd);
8418 if (palette_mode_info.palette_size[0] == 0)
8419 goto PALETTE_EXIT;
8420
8421 pmi->palette_size[0] =
8422 palette_mode_info.palette_size[0];
8423 if (palette_mode_info.palette_size[0] > 0) {
8424 memcpy(pmi->palette_colors, palette_mode_info.palette_colors,
8425 PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
8426 memcpy(color_map, best_palette_color_map,
8427 rows * cols * sizeof(best_palette_color_map[0]));
8428 }
8429 super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
8430 NULL, bsize, best_rd);
8431 if (rate_y == INT_MAX)
8432 goto PALETTE_EXIT;
8433 uv_tx = get_uv_tx_size_impl(mbmi->tx_size, bsize,
8434 xd->plane[1].subsampling_x,
8435 xd->plane[1].subsampling_y);
8436 if (rate_uv_intra[uv_tx] == INT_MAX) {
8437 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx,
8438 &rate_uv_intra[uv_tx], &rate_uv_tokenonly[uv_tx],
8439 &dist_uv[uv_tx], &skip_uv[uv_tx], &mode_uv[uv_tx]);
8440 pmi_uv[uv_tx] = *pmi;
8441#if CONFIG_EXT_INTRA
8442 ext_intra_mode_info_uv[uv_tx] = mbmi->ext_intra_mode_info;
8443 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
8444#endif // CONFIG_EXT_INTRA
8445 }
8446 mbmi->uv_mode = mode_uv[uv_tx];
8447 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
8448 if (pmi->palette_size[1] > 0)
8449 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
8450 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
8451 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
8452#if CONFIG_EXT_INTRA
8453 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
8454 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
8455 ext_intra_mode_info_uv[uv_tx].use_ext_intra_mode[1];
8456 if (ext_intra_mode_info_uv[uv_tx].use_ext_intra_mode[1]) {
8457 mbmi->ext_intra_mode_info.ext_intra_mode[1] =
8458 ext_intra_mode_info_uv[uv_tx].ext_intra_mode[1];
8459 }
8460#endif // CONFIG_EXT_INTRA
8461 skippable = skippable && skip_uv[uv_tx];
8462 distortion2 = distortion_y + dist_uv[uv_tx];
8463 rate2 = rate_y + rate_overhead + rate_uv_intra[uv_tx];
8464 rate2 += ref_costs_single[INTRA_FRAME];
8465
8466 if (skippable) {
8467 rate2 -= (rate_y + rate_uv_tokenonly[uv_tx]);
8468 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
8469 } else {
8470 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
8471 }
8472 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
8473 if (this_rd < best_rd) {
8474 int max_plane = MAX_MB_PLANE;
8475 best_mode_index = 3;
8476 mbmi->mv[0].as_int = 0;
8477 max_plane = 1;
8478 rd_cost->rate = rate2;
8479 rd_cost->dist = distortion2;
8480 rd_cost->rdcost = this_rd;
8481 best_rd = this_rd;
8482 best_mbmode = *mbmi;
8483 best_skip2 = 0;
8484 best_mode_skippable = skippable;
8485 if (!x->select_tx_size)
8486 swap_block_ptr(x, ctx, 1, 0, 0, max_plane);
8487 memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
8488 sizeof(ctx->zcoeff_blk[0]) * ctx->num_4x4_blk);
8489 }
8490 }
8491 PALETTE_EXIT:
8492
Jingning Han3ee6db62015-08-05 19:00:31 -07008493 // The inter modes' rate costs are not calculated precisely in some cases.
8494 // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
8495 // ZEROMV. Here, checks are added for those cases, and the mode decisions
8496 // are corrected.
Yue Chen1ac85872016-01-07 15:13:52 -08008497 if (best_mbmode.mode == NEWMV
8498#if CONFIG_EXT_INTER
8499 || best_mbmode.mode == NEWFROMNEARMV
Yue Chen968bbc72016-01-19 16:45:45 -08008500 || best_mbmode.mode == NEW_NEWMV
Yue Chen1ac85872016-01-07 15:13:52 -08008501#endif // CONFIG_EXT_INTER
8502 ) {
Jingning Han3ee6db62015-08-05 19:00:31 -07008503 const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0],
8504 best_mbmode.ref_frame[1]};
8505 int comp_pred_mode = refs[1] > INTRA_FRAME;
Jingning Han33cc1bd2016-01-12 15:06:59 -08008506#if CONFIG_REF_MV
Geza Lore7ded0382016-02-22 10:55:32 +00008507 const uint8_t rf_type = vp10_ref_frame_type(best_mbmode.ref_frame);
Jingning Han33cc1bd2016-01-12 15:06:59 -08008508 if (!comp_pred_mode) {
Geza Lore7ded0382016-02-22 10:55:32 +00008509 if (best_mbmode.ref_mv_idx > 0 && refs[1] == NONE) {
8510 int idx = best_mbmode.ref_mv_idx + 1;
8511 int_mv cur_mv = mbmi_ext->ref_mv_stack[refs[0]][idx].this_mv;
Jingning Han67cf8902016-01-15 09:05:51 -08008512 lower_mv_precision(&cur_mv.as_mv, cm->allow_high_precision_mv);
8513 frame_mv[NEARMV][refs[0]] = cur_mv;
8514 }
8515
Jingning Han33cc1bd2016-01-12 15:06:59 -08008516 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
8517 best_mbmode.mode = NEARESTMV;
8518 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
8519 best_mbmode.mode = NEARMV;
8520 else if (best_mbmode.mv[0].as_int == 0)
8521 best_mbmode.mode = ZEROMV;
8522 } else {
Jingning Han3944cfb2016-01-13 09:03:15 -08008523 int i;
8524 const int allow_hp = cm->allow_high_precision_mv;
8525 int_mv nearestmv[2] = { frame_mv[NEARESTMV][refs[0]],
8526 frame_mv[NEARESTMV][refs[1]] };
Jingning Han3ee6db62015-08-05 19:00:31 -07008527
Jingning Han3944cfb2016-01-13 09:03:15 -08008528 int_mv nearmv[2] = { frame_mv[NEARMV][refs[0]],
8529 frame_mv[NEARMV][refs[1]] };
8530
8531 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
Jingning Han33cc1bd2016-01-12 15:06:59 -08008532 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
8533 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
Jingning Han3944cfb2016-01-13 09:03:15 -08008534 }
8535
8536 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
Geza Lore7ded0382016-02-22 10:55:32 +00008537 int ref_mv_idx = best_mbmode.ref_mv_idx + 1;
Jingning Han28e03932016-01-20 17:40:47 -08008538 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][ref_mv_idx].this_mv;
8539 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][ref_mv_idx].comp_mv;
Jingning Han33cc1bd2016-01-12 15:06:59 -08008540 }
Jingning Han3944cfb2016-01-13 09:03:15 -08008541
8542 for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
8543 lower_mv_precision(&nearestmv[i].as_mv, allow_hp);
8544 lower_mv_precision(&nearmv[i].as_mv, allow_hp);
8545 }
8546
8547 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
8548 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
Yue Chen968bbc72016-01-19 16:45:45 -08008549#if CONFIG_EXT_INTER
8550 best_mbmode.mode = NEAREST_NEARESTMV;
8551 else if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
8552 nearmv[1].as_int == best_mbmode.mv[1].as_int)
8553 best_mbmode.mode = NEAREST_NEARMV;
8554 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
8555 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
8556 best_mbmode.mode = NEAR_NEARESTMV;
8557 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
8558 best_mbmode.mode = ZERO_ZEROMV;
8559#else
Jingning Han3944cfb2016-01-13 09:03:15 -08008560 best_mbmode.mode = NEARESTMV;
8561 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
8562 nearmv[1].as_int == best_mbmode.mv[1].as_int)
8563 best_mbmode.mode = NEARMV;
8564 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
8565 best_mbmode.mode = ZEROMV;
Yue Chen968bbc72016-01-19 16:45:45 -08008566#endif // CONFIG_EXT_INTER
Jingning Han33cc1bd2016-01-12 15:06:59 -08008567 }
8568#else
Yue Chen968bbc72016-01-19 16:45:45 -08008569#if CONFIG_EXT_INTER
8570 if (!comp_pred_mode) {
8571#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07008572 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
8573 ((comp_pred_mode && frame_mv[NEARESTMV][refs[1]].as_int ==
8574 best_mbmode.mv[1].as_int) || !comp_pred_mode))
8575 best_mbmode.mode = NEARESTMV;
8576 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
8577 ((comp_pred_mode && frame_mv[NEARMV][refs[1]].as_int ==
8578 best_mbmode.mv[1].as_int) || !comp_pred_mode))
8579 best_mbmode.mode = NEARMV;
8580 else if (best_mbmode.mv[0].as_int == 0 &&
8581 ((comp_pred_mode && best_mbmode.mv[1].as_int == 0) || !comp_pred_mode))
8582 best_mbmode.mode = ZEROMV;
Yue Chen968bbc72016-01-19 16:45:45 -08008583#if CONFIG_EXT_INTER
8584 } else {
8585 const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0],
8586 best_mbmode.ref_frame[1]};
8587
8588 if (frame_mv[NEAREST_NEARESTMV][refs[0]].as_int ==
8589 best_mbmode.mv[0].as_int &&
8590 frame_mv[NEAREST_NEARESTMV][refs[1]].as_int ==
8591 best_mbmode.mv[1].as_int)
8592 best_mbmode.mode = NEAREST_NEARESTMV;
8593 else if (frame_mv[NEAREST_NEARMV][refs[0]].as_int ==
8594 best_mbmode.mv[0].as_int &&
8595 frame_mv[NEAREST_NEARMV][refs[1]].as_int ==
8596 best_mbmode.mv[1].as_int)
8597 best_mbmode.mode = NEAREST_NEARMV;
8598 else if (frame_mv[NEAR_NEARESTMV][refs[0]].as_int ==
8599 best_mbmode.mv[0].as_int &&
8600 frame_mv[NEAR_NEARESTMV][refs[1]].as_int ==
8601 best_mbmode.mv[1].as_int)
8602 best_mbmode.mode = NEAR_NEARESTMV;
8603 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
8604 best_mbmode.mode = ZERO_ZEROMV;
8605 }
8606#endif // CONFIG_EXT_INTER
Jingning Han33cc1bd2016-01-12 15:06:59 -08008607#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07008608 }
8609
Jingning Hanaa5d53e2015-12-07 15:54:59 -08008610#if CONFIG_REF_MV
8611 if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
8612 best_mbmode.mv[0].as_int == 0 &&
Yue Chen968bbc72016-01-19 16:45:45 -08008613#if CONFIG_EXT_INTER
Geza Lore7ded0382016-02-22 10:55:32 +00008614 (best_mbmode.ref_frame[1] <= INTRA_FRAME)
Yue Chen968bbc72016-01-19 16:45:45 -08008615#else
Geza Lore7ded0382016-02-22 10:55:32 +00008616 (best_mbmode.ref_frame[1] == NONE || best_mbmode.mv[1].as_int == 0)
Yue Chen968bbc72016-01-19 16:45:45 -08008617#endif // CONFIG_EXT_INTER
Geza Lore7ded0382016-02-22 10:55:32 +00008618 ) {
Jingning Hanaa5d53e2015-12-07 15:54:59 -08008619 int16_t mode_ctx = mbmi_ext->mode_context[best_mbmode.ref_frame[0]];
Yue Chen968bbc72016-01-19 16:45:45 -08008620#if !CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08008621 if (best_mbmode.ref_frame[1] > NONE)
8622 mode_ctx &= (mbmi_ext->mode_context[best_mbmode.ref_frame[1]] | 0x00ff);
Yue Chen968bbc72016-01-19 16:45:45 -08008623#endif // !CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08008624
8625 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET))
8626 best_mbmode.mode = ZEROMV;
8627 }
8628#endif
8629
Jingning Han3ee6db62015-08-05 19:00:31 -07008630 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
8631 rd_cost->rate = INT_MAX;
8632 rd_cost->rdcost = INT64_MAX;
8633 return;
8634 }
8635
8636 // If we used an estimate for the uv intra rd in the loop above...
8637 if (sf->use_uv_intra_rd_estimate) {
8638 // Do Intra UV best rd mode selection if best mode choice above was intra.
8639 if (best_mbmode.ref_frame[0] == INTRA_FRAME) {
8640 TX_SIZE uv_tx_size;
8641 *mbmi = best_mbmode;
8642 uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
8643 rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra[uv_tx_size],
8644 &rate_uv_tokenonly[uv_tx_size],
8645 &dist_uv[uv_tx_size],
8646 &skip_uv[uv_tx_size],
8647 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize,
8648 uv_tx_size);
8649 }
8650 }
8651
8652 assert((cm->interp_filter == SWITCHABLE) ||
8653 (cm->interp_filter == best_mbmode.interp_filter) ||
8654 !is_inter_block(&best_mbmode));
8655
8656 if (!cpi->rc.is_src_frame_alt_ref)
8657 vp10_update_rd_thresh_fact(tile_data->thresh_freq_fact,
8658 sf->adaptive_rd_thresh, bsize, best_mode_index);
8659
8660 // macroblock modes
8661 *mbmi = best_mbmode;
8662 x->skip |= best_skip2;
8663
Jingning Handf59bb82016-02-18 11:57:44 -08008664#if CONFIG_REF_MV
8665 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
8666 if (mbmi->mode != NEWMV)
8667 mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
8668 else
8669 mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
8670 }
8671#endif
8672
Jingning Han3ee6db62015-08-05 19:00:31 -07008673 for (i = 0; i < REFERENCE_MODES; ++i) {
8674 if (best_pred_rd[i] == INT64_MAX)
8675 best_pred_diff[i] = INT_MIN;
8676 else
8677 best_pred_diff[i] = best_rd - best_pred_rd[i];
8678 }
8679
Jingning Han3ee6db62015-08-05 19:00:31 -07008680 x->skip |= best_mode_skippable;
8681
8682 if (!x->skip && !x->select_tx_size) {
8683 int has_high_freq_coeff = 0;
8684 int plane;
8685 int max_plane = is_inter_block(&xd->mi[0]->mbmi)
8686 ? MAX_MB_PLANE : 1;
8687 for (plane = 0; plane < max_plane; ++plane) {
8688 x->plane[plane].eobs = ctx->eobs_pbuf[plane][1];
8689 has_high_freq_coeff |= vp10_has_high_freq_in_plane(x, bsize, plane);
8690 }
8691
8692 for (plane = max_plane; plane < MAX_MB_PLANE; ++plane) {
8693 x->plane[plane].eobs = ctx->eobs_pbuf[plane][2];
8694 has_high_freq_coeff |= vp10_has_high_freq_in_plane(x, bsize, plane);
8695 }
8696
8697 best_mode_skippable |= !has_high_freq_coeff;
8698 }
8699
8700 assert(best_mode_index >= 0);
8701
8702 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
Angie Chiangb6fef122016-03-11 16:01:46 -08008703 best_mode_skippable);
hui su78b0bd02016-02-23 15:22:25 -08008704
8705 if (cm->allow_screen_content_tools && pmi->palette_size[1] > 0) {
8706 restore_uv_color_map(cpi, x);
8707 }
Jingning Han3ee6db62015-08-05 19:00:31 -07008708}
8709
Yaowu Xu26a9afc2015-08-13 09:42:27 -07008710void vp10_rd_pick_inter_mode_sb_seg_skip(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07008711 TileDataEnc *tile_data,
8712 MACROBLOCK *x,
8713 RD_COST *rd_cost,
8714 BLOCK_SIZE bsize,
8715 PICK_MODE_CONTEXT *ctx,
8716 int64_t best_rd_so_far) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07008717 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07008718 MACROBLOCKD *const xd = &x->e_mbd;
8719 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
8720 unsigned char segment_id = mbmi->segment_id;
8721 const int comp_pred = 0;
8722 int i;
8723 int64_t best_pred_diff[REFERENCE_MODES];
Jingning Han3ee6db62015-08-05 19:00:31 -07008724 unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
8725 vpx_prob comp_mode_p;
8726 INTERP_FILTER best_filter = SWITCHABLE;
8727 int64_t this_rd = INT64_MAX;
8728 int rate2 = 0;
8729 const int64_t distortion2 = 0;
8730
Jingning Han3ee6db62015-08-05 19:00:31 -07008731 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
8732 &comp_mode_p);
8733
8734 for (i = 0; i < MAX_REF_FRAMES; ++i)
8735 x->pred_sse[i] = INT_MAX;
8736 for (i = LAST_FRAME; i < MAX_REF_FRAMES; ++i)
8737 x->pred_mv_sad[i] = INT_MAX;
8738
8739 rd_cost->rate = INT_MAX;
8740
8741 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
8742
hui suc93e5cc2015-12-07 18:18:57 -08008743 mbmi->palette_mode_info.palette_size[0] = 0;
8744 mbmi->palette_mode_info.palette_size[1] = 0;
hui sube3559b2015-10-07 09:29:02 -07008745#if CONFIG_EXT_INTRA
8746 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
8747 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
8748#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07008749 mbmi->mode = ZEROMV;
8750 mbmi->uv_mode = DC_PRED;
8751 mbmi->ref_frame[0] = LAST_FRAME;
8752 mbmi->ref_frame[1] = NONE;
8753 mbmi->mv[0].as_int = 0;
8754 x->skip = 1;
8755
8756 if (cm->interp_filter != BILINEAR) {
Debargha Mukherjeebab29122016-02-26 00:18:03 -08008757 best_filter = EIGHTTAP_REGULAR;
Jingning Han3ee6db62015-08-05 19:00:31 -07008758 if (cm->interp_filter == SWITCHABLE &&
Debargha Mukherjee85514c42015-10-30 09:19:36 -07008759#if CONFIG_EXT_INTERP
8760 vp10_is_interp_needed(xd) &&
8761#endif // CONFIG_EXT_INTERP
Jingning Han3ee6db62015-08-05 19:00:31 -07008762 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
8763 int rs;
8764 int best_rs = INT_MAX;
8765 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
8766 mbmi->interp_filter = i;
8767 rs = vp10_get_switchable_rate(cpi, xd);
8768 if (rs < best_rs) {
8769 best_rs = rs;
8770 best_filter = mbmi->interp_filter;
8771 }
8772 }
8773 }
8774 }
8775 // Set the appropriate filter
8776 if (cm->interp_filter == SWITCHABLE) {
8777 mbmi->interp_filter = best_filter;
8778 rate2 += vp10_get_switchable_rate(cpi, xd);
8779 } else {
8780 mbmi->interp_filter = cm->interp_filter;
8781 }
8782
8783 if (cm->reference_mode == REFERENCE_MODE_SELECT)
8784 rate2 += vp10_cost_bit(comp_mode_p, comp_pred);
8785
8786 // Estimate the reference frame signaling cost and add it
8787 // to the rolling cost variable.
8788 rate2 += ref_costs_single[LAST_FRAME];
8789 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
8790
8791 rd_cost->rate = rate2;
8792 rd_cost->dist = distortion2;
8793 rd_cost->rdcost = this_rd;
8794
8795 if (this_rd >= best_rd_so_far) {
8796 rd_cost->rate = INT_MAX;
8797 rd_cost->rdcost = INT64_MAX;
8798 return;
8799 }
8800
8801 assert((cm->interp_filter == SWITCHABLE) ||
8802 (cm->interp_filter == mbmi->interp_filter));
8803
8804 vp10_update_rd_thresh_fact(tile_data->thresh_freq_fact,
8805 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
8806
8807 vp10_zero(best_pred_diff);
Jingning Han3ee6db62015-08-05 19:00:31 -07008808
8809 if (!x->select_tx_size)
8810 swap_block_ptr(x, ctx, 1, 0, 0, MAX_MB_PLANE);
8811 store_coding_context(x, ctx, THR_ZEROMV,
Angie Chiangb6fef122016-03-11 16:01:46 -08008812 best_pred_diff, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07008813}
8814
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008815void vp10_rd_pick_inter_mode_sub8x8(struct VP10_COMP *cpi,
8816 TileDataEnc *tile_data,
8817 struct macroblock *x,
8818 int mi_row, int mi_col,
8819 struct RD_COST *rd_cost,
8820#if CONFIG_SUPERTX
8821 int *returnrate_nocoef,
8822#endif // CONFIG_SUPERTX
8823 BLOCK_SIZE bsize,
8824 PICK_MODE_CONTEXT *ctx,
8825 int64_t best_rd_so_far) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07008826 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07008827 RD_OPT *const rd_opt = &cpi->rd;
8828 SPEED_FEATURES *const sf = &cpi->sf;
8829 MACROBLOCKD *const xd = &x->e_mbd;
8830 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
8831 const struct segmentation *const seg = &cm->seg;
8832 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
8833 unsigned char segment_id = mbmi->segment_id;
8834 int comp_pred, i;
8835 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
Zoe Liu3ec16012015-11-12 02:12:17 -08008836 struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE];
8837 static const int flag_list[REFS_PER_FRAME + 1] = {
8838 0,
8839 VP9_LAST_FLAG,
8840#if CONFIG_EXT_REFS
8841 VP9_LAST2_FLAG,
8842 VP9_LAST3_FLAG,
8843 VP9_LAST4_FLAG,
8844#endif // CONFIG_EXT_REFS
8845 VP9_GOLD_FLAG,
8846 VP9_ALT_FLAG
8847 };
Jingning Han3ee6db62015-08-05 19:00:31 -07008848 int64_t best_rd = best_rd_so_far;
8849 int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
8850 int64_t best_pred_diff[REFERENCE_MODES];
8851 int64_t best_pred_rd[REFERENCE_MODES];
Jingning Han3ee6db62015-08-05 19:00:31 -07008852 MB_MODE_INFO best_mbmode;
8853 int ref_index, best_ref_index = 0;
8854 unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
8855 vpx_prob comp_mode_p;
8856 INTERP_FILTER tmp_best_filter = SWITCHABLE;
8857 int rate_uv_intra, rate_uv_tokenonly;
8858 int64_t dist_uv;
8859 int skip_uv;
8860 PREDICTION_MODE mode_uv = DC_PRED;
8861 const int intra_cost_penalty = vp10_get_intra_cost_penalty(
8862 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
Yue Chen1ac85872016-01-07 15:13:52 -08008863#if CONFIG_EXT_INTER
8864 int_mv seg_mvs[4][2][MAX_REF_FRAMES];
8865#else
Jingning Han3ee6db62015-08-05 19:00:31 -07008866 int_mv seg_mvs[4][MAX_REF_FRAMES];
Yue Chen1ac85872016-01-07 15:13:52 -08008867#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07008868 b_mode_info best_bmodes[4];
8869 int best_skip2 = 0;
8870 int ref_frame_skip_mask[2] = { 0 };
Jingning Han3ee6db62015-08-05 19:00:31 -07008871 int internal_active_edge =
8872 vp10_active_edge_sb(cpi, mi_row, mi_col) && vp10_internal_image_edge(cpi);
8873
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008874#if CONFIG_SUPERTX
8875 best_rd_so_far = INT64_MAX;
8876 best_rd = best_rd_so_far;
8877 best_yrd = best_rd_so_far;
8878#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07008879 memset(x->zcoeff_blk[TX_4X4], 0, 4);
8880 vp10_zero(best_mbmode);
8881
hui sube3559b2015-10-07 09:29:02 -07008882#if CONFIG_EXT_INTRA
8883 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
8884 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
8885#endif // CONFIG_EXT_INTRA
Yue Chend1cad9c2016-01-27 14:18:53 -08008886#if CONFIG_OBMC
8887 mbmi->obmc = 0;
8888#endif // CONFIG_OBMC
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08008889#if CONFIG_EXT_INTER
8890 mbmi->use_wedge_interinter = 0;
8891 mbmi->use_wedge_interintra = 0;
8892#endif // CONFIG_EXT_INTER
hui sube3559b2015-10-07 09:29:02 -07008893
Jingning Han3ee6db62015-08-05 19:00:31 -07008894 for (i = 0; i < 4; i++) {
8895 int j;
Yue Chen1ac85872016-01-07 15:13:52 -08008896#if CONFIG_EXT_INTER
8897 int k;
8898
8899 for (k = 0; k < 2; k++)
8900 for (j = 0; j < MAX_REF_FRAMES; j++)
8901 seg_mvs[i][k][j].as_int = INVALID_MV;
8902#else
Jingning Han3ee6db62015-08-05 19:00:31 -07008903 for (j = 0; j < MAX_REF_FRAMES; j++)
8904 seg_mvs[i][j].as_int = INVALID_MV;
Yue Chen1ac85872016-01-07 15:13:52 -08008905#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07008906 }
8907
8908 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
8909 &comp_mode_p);
8910
8911 for (i = 0; i < REFERENCE_MODES; ++i)
8912 best_pred_rd[i] = INT64_MAX;
Jingning Han3ee6db62015-08-05 19:00:31 -07008913 rate_uv_intra = INT_MAX;
8914
8915 rd_cost->rate = INT_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008916#if CONFIG_SUPERTX
8917 *returnrate_nocoef = INT_MAX;
8918#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07008919
8920 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
Jingning Han387a10e2015-12-09 09:07:39 -08008921 x->mbmi_ext->mode_context[ref_frame] = 0;
Yue Chen968bbc72016-01-19 16:45:45 -08008922#if CONFIG_REF_MV && CONFIG_EXT_INTER
8923 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
8924#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07008925 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
8926 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
8927 frame_mv[NEARESTMV], frame_mv[NEARMV],
8928 yv12_mb);
8929 } else {
8930 ref_frame_skip_mask[0] |= (1 << ref_frame);
8931 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8932 }
8933 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Yue Chen1ac85872016-01-07 15:13:52 -08008934#if CONFIG_EXT_INTER
8935 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
8936#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07008937 frame_mv[ZEROMV][ref_frame].as_int = 0;
8938 }
8939
hui suc93e5cc2015-12-07 18:18:57 -08008940 mbmi->palette_mode_info.palette_size[0] = 0;
8941 mbmi->palette_mode_info.palette_size[1] = 0;
8942
Jingning Han3ee6db62015-08-05 19:00:31 -07008943 for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
8944 int mode_excluded = 0;
8945 int64_t this_rd = INT64_MAX;
8946 int disable_skip = 0;
8947 int compmode_cost = 0;
8948 int rate2 = 0, rate_y = 0, rate_uv = 0;
8949 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
8950 int skippable = 0;
8951 int i;
8952 int this_skip2 = 0;
8953 int64_t total_sse = INT_MAX;
8954 int early_term = 0;
8955
8956 ref_frame = vp10_ref_order[ref_index].ref_frame[0];
8957 second_ref_frame = vp10_ref_order[ref_index].ref_frame[1];
8958
8959 // Look at the reference frame of the best mode so far and set the
8960 // skip mask to look at a subset of the remaining modes.
8961 if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
8962 if (ref_index == 3) {
8963 switch (best_mbmode.ref_frame[0]) {
8964 case INTRA_FRAME:
8965 break;
8966 case LAST_FRAME:
Zoe Liu3ec16012015-11-12 02:12:17 -08008967 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
8968#if CONFIG_EXT_REFS
8969 (1 << LAST2_FRAME) |
8970 (1 << LAST3_FRAME) |
8971 (1 << LAST4_FRAME) |
8972#endif // CONFIG_EXT_REFS
8973 (1 << ALTREF_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07008974 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8975 break;
Zoe Liu3ec16012015-11-12 02:12:17 -08008976#if CONFIG_EXT_REFS
8977 case LAST2_FRAME:
8978 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
8979 (1 << LAST3_FRAME) |
8980 (1 << LAST4_FRAME) |
8981 (1 << GOLDEN_FRAME) |
8982 (1 << ALTREF_FRAME);
8983 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8984 break;
8985 case LAST3_FRAME:
8986 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
8987 (1 << LAST2_FRAME) |
8988 (1 << LAST4_FRAME) |
8989 (1 << GOLDEN_FRAME) |
8990 (1 << ALTREF_FRAME);
8991 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8992 break;
8993 case LAST4_FRAME:
8994 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
8995 (1 << LAST2_FRAME) |
8996 (1 << LAST3_FRAME) |
8997 (1 << GOLDEN_FRAME) |
8998 (1 << ALTREF_FRAME);
8999 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9000 break;
9001#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07009002 case GOLDEN_FRAME:
Zoe Liu3ec16012015-11-12 02:12:17 -08009003 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
9004#if CONFIG_EXT_REFS
9005 (1 << LAST2_FRAME) |
9006 (1 << LAST3_FRAME) |
9007 (1 << LAST4_FRAME) |
9008#endif // CONFIG_EXT_REFS
9009 (1 << ALTREF_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07009010 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9011 break;
9012 case ALTREF_FRAME:
Zoe Liu3ec16012015-11-12 02:12:17 -08009013 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
9014#if CONFIG_EXT_REFS
9015 (1 << LAST2_FRAME) |
9016 (1 << LAST3_FRAME) |
9017 (1 << LAST4_FRAME) |
9018#endif // CONFIG_EXT_REFS
9019 (1 << LAST_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07009020 break;
9021 case NONE:
9022 case MAX_REF_FRAMES:
9023 assert(0 && "Invalid Reference frame");
9024 break;
9025 }
9026 }
9027 }
9028
9029 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
James Zern5e16d392015-08-17 18:19:22 -07009030 (ref_frame_skip_mask[1] & (1 << VPXMAX(0, second_ref_frame))))
Jingning Han3ee6db62015-08-05 19:00:31 -07009031 continue;
9032
9033 // Test best rd so far against threshold for trying this mode.
9034 if (!internal_active_edge &&
9035 rd_less_than_thresh(best_rd,
9036 rd_opt->threshes[segment_id][bsize][ref_index],
9037 tile_data->thresh_freq_fact[bsize][ref_index]))
9038 continue;
9039
9040 comp_pred = second_ref_frame > INTRA_FRAME;
9041 if (comp_pred) {
9042 if (!cpi->allow_comp_inter_inter)
9043 continue;
9044 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
9045 continue;
9046 // Do not allow compound prediction if the segment level reference frame
9047 // feature is in use as in this case there can only be one reference.
9048 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
9049 continue;
9050
9051 if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
9052 best_mbmode.ref_frame[0] == INTRA_FRAME)
9053 continue;
9054 }
9055
9056 // TODO(jingning, jkoleszar): scaling reference frame not supported for
9057 // sub8x8 blocks.
9058 if (ref_frame > INTRA_FRAME &&
9059 vp10_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
9060 continue;
9061
9062 if (second_ref_frame > INTRA_FRAME &&
9063 vp10_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
9064 continue;
9065
9066 if (comp_pred)
9067 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
9068 else if (ref_frame != INTRA_FRAME)
9069 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
9070
9071 // If the segment reference frame feature is enabled....
9072 // then do nothing if the current ref frame is not allowed..
9073 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
9074 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
9075 continue;
9076 // Disable this drop out case if the ref frame
9077 // segment level feature is enabled for this segment. This is to
9078 // prevent the possibility that we end up unable to pick any mode.
9079 } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
9080 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
9081 // unless ARNR filtering is enabled in which case we want
9082 // an unfiltered alternative. We allow near/nearest as well
9083 // because they may result in zero-zero MVs but be cheaper.
9084 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
9085 continue;
9086 }
9087
9088 mbmi->tx_size = TX_4X4;
9089 mbmi->uv_mode = DC_PRED;
9090 mbmi->ref_frame[0] = ref_frame;
9091 mbmi->ref_frame[1] = second_ref_frame;
9092 // Evaluate all sub-pel filters irrespective of whether we can use
9093 // them for this frame.
Debargha Mukherjeebab29122016-02-26 00:18:03 -08009094 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
Jingning Han3ee6db62015-08-05 19:00:31 -07009095 : cm->interp_filter;
9096 x->skip = 0;
9097 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
9098
9099 // Select prediction reference frames.
9100 for (i = 0; i < MAX_MB_PLANE; i++) {
9101 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
9102 if (comp_pred)
9103 xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
9104 }
9105
Jingning Han704985e2015-10-08 12:05:03 -07009106#if CONFIG_VAR_TX
Jingning Han0f34e352015-11-15 20:52:51 -08009107 mbmi->inter_tx_size[0] = mbmi->tx_size;
Jingning Han704985e2015-10-08 12:05:03 -07009108#endif
9109
Jingning Han3ee6db62015-08-05 19:00:31 -07009110 if (ref_frame == INTRA_FRAME) {
9111 int rate;
9112 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y,
9113 &distortion_y, best_rd) >= best_rd)
9114 continue;
9115 rate2 += rate;
9116 rate2 += intra_cost_penalty;
9117 distortion2 += distortion_y;
9118
9119 if (rate_uv_intra == INT_MAX) {
9120 choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4,
9121 &rate_uv_intra,
9122 &rate_uv_tokenonly,
9123 &dist_uv, &skip_uv,
9124 &mode_uv);
9125 }
9126 rate2 += rate_uv_intra;
9127 rate_uv = rate_uv_tokenonly;
9128 distortion2 += dist_uv;
9129 distortion_uv = dist_uv;
9130 mbmi->uv_mode = mode_uv;
9131 } else {
9132 int rate;
9133 int64_t distortion;
9134 int64_t this_rd_thresh;
9135 int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
9136 int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
9137 int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
9138 int tmp_best_skippable = 0;
9139 int switchable_filter_index;
9140 int_mv *second_ref = comp_pred ?
9141 &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL;
9142 b_mode_info tmp_best_bmodes[16];
9143 MB_MODE_INFO tmp_best_mbmode;
9144 BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
9145 int pred_exists = 0;
9146 int uv_skippable;
Yue Chen1ac85872016-01-07 15:13:52 -08009147#if CONFIG_EXT_INTER
9148 int_mv compound_seg_newmvs[4][2];
9149 int i;
9150
9151 for (i = 0; i < 4; i++) {
9152 compound_seg_newmvs[i][0].as_int = INVALID_MV;
9153 compound_seg_newmvs[i][1].as_int = INVALID_MV;
9154 }
9155#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07009156
9157 this_rd_thresh = (ref_frame == LAST_FRAME) ?
9158 rd_opt->threshes[segment_id][bsize][THR_LAST] :
9159 rd_opt->threshes[segment_id][bsize][THR_ALTR];
Zoe Liu3ec16012015-11-12 02:12:17 -08009160#if CONFIG_EXT_REFS
9161 this_rd_thresh = (ref_frame == LAST2_FRAME) ?
9162 rd_opt->threshes[segment_id][bsize][THR_LAST2] : this_rd_thresh;
9163 this_rd_thresh = (ref_frame == LAST3_FRAME) ?
9164 rd_opt->threshes[segment_id][bsize][THR_LAST3] : this_rd_thresh;
9165 this_rd_thresh = (ref_frame == LAST4_FRAME) ?
9166 rd_opt->threshes[segment_id][bsize][THR_LAST4] : this_rd_thresh;
9167#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07009168 this_rd_thresh = (ref_frame == GOLDEN_FRAME) ?
Zoe Liu3ec16012015-11-12 02:12:17 -08009169 rd_opt->threshes[segment_id][bsize][THR_GOLD] : this_rd_thresh;
Jingning Han3ee6db62015-08-05 19:00:31 -07009170
Debargha Mukherjeed46c1f22016-02-08 15:59:17 -08009171 // TODO(any): Add search of the tx_type to improve rd performance at the
9172 // expense of speed.
9173 mbmi->tx_type = DCT_DCT;
9174
Jingning Han3ee6db62015-08-05 19:00:31 -07009175 if (cm->interp_filter != BILINEAR) {
Debargha Mukherjeebab29122016-02-26 00:18:03 -08009176 tmp_best_filter = EIGHTTAP_REGULAR;
Jingning Han3ee6db62015-08-05 19:00:31 -07009177 if (x->source_variance < sf->disable_filter_search_var_thresh) {
Debargha Mukherjeebab29122016-02-26 00:18:03 -08009178 tmp_best_filter = EIGHTTAP_REGULAR;
Jingning Han3ee6db62015-08-05 19:00:31 -07009179 } else if (sf->adaptive_pred_interp_filter == 1 &&
9180 ctx->pred_interp_filter < SWITCHABLE) {
9181 tmp_best_filter = ctx->pred_interp_filter;
9182 } else if (sf->adaptive_pred_interp_filter == 2) {
9183 tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE ?
9184 ctx->pred_interp_filter : 0;
9185 } else {
9186 for (switchable_filter_index = 0;
9187 switchable_filter_index < SWITCHABLE_FILTERS;
9188 ++switchable_filter_index) {
9189 int newbest, rs;
9190 int64_t rs_rd;
9191 MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
9192 mbmi->interp_filter = switchable_filter_index;
9193 tmp_rd = rd_pick_best_sub8x8_mode(cpi, x,
9194 &mbmi_ext->ref_mvs[ref_frame][0],
9195 second_ref, best_yrd, &rate,
9196 &rate_y, &distortion,
9197 &skippable, &total_sse,
9198 (int) this_rd_thresh, seg_mvs,
Yue Chen1ac85872016-01-07 15:13:52 -08009199#if CONFIG_EXT_INTER
9200 compound_seg_newmvs,
9201#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07009202 bsi, switchable_filter_index,
9203 mi_row, mi_col);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07009204#if CONFIG_EXT_INTERP
9205 if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Debargha Mukherjeebab29122016-02-26 00:18:03 -08009206 mbmi->interp_filter != EIGHTTAP_REGULAR) // invalid config
Debargha Mukherjee85514c42015-10-30 09:19:36 -07009207 continue;
9208#endif // CONFIG_EXT_INTERP
Jingning Han3ee6db62015-08-05 19:00:31 -07009209 if (tmp_rd == INT64_MAX)
9210 continue;
9211 rs = vp10_get_switchable_rate(cpi, xd);
9212 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07009213 if (cm->interp_filter == SWITCHABLE)
9214 tmp_rd += rs_rd;
9215
Jingning Han3ee6db62015-08-05 19:00:31 -07009216 newbest = (tmp_rd < tmp_best_rd);
9217 if (newbest) {
9218 tmp_best_filter = mbmi->interp_filter;
9219 tmp_best_rd = tmp_rd;
9220 }
9221 if ((newbest && cm->interp_filter == SWITCHABLE) ||
9222 (mbmi->interp_filter == cm->interp_filter &&
9223 cm->interp_filter != SWITCHABLE)) {
9224 tmp_best_rdu = tmp_rd;
9225 tmp_best_rate = rate;
9226 tmp_best_ratey = rate_y;
9227 tmp_best_distortion = distortion;
9228 tmp_best_sse = total_sse;
9229 tmp_best_skippable = skippable;
9230 tmp_best_mbmode = *mbmi;
9231 for (i = 0; i < 4; i++) {
9232 tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
9233 x->zcoeff_blk[TX_4X4][i] = !x->plane[0].eobs[i];
9234 }
9235 pred_exists = 1;
9236 if (switchable_filter_index == 0 &&
9237 sf->use_rd_breakout &&
9238 best_rd < INT64_MAX) {
9239 if (tmp_best_rdu / 2 > best_rd) {
9240 // skip searching the other filters if the first is
9241 // already substantially larger than the best so far
9242 tmp_best_filter = mbmi->interp_filter;
9243 tmp_best_rdu = INT64_MAX;
9244 break;
9245 }
9246 }
9247 }
9248 } // switchable_filter_index loop
9249 }
9250 }
9251
9252 if (tmp_best_rdu == INT64_MAX && pred_exists)
9253 continue;
9254
9255 mbmi->interp_filter = (cm->interp_filter == SWITCHABLE ?
9256 tmp_best_filter : cm->interp_filter);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07009257
Jingning Han3ee6db62015-08-05 19:00:31 -07009258 if (!pred_exists) {
9259 // Handles the special case when a filter that is not in the
Debargha Mukherjee85514c42015-10-30 09:19:36 -07009260 // switchable list (bilinear) is indicated at the frame level
Jingning Han3ee6db62015-08-05 19:00:31 -07009261 tmp_rd = rd_pick_best_sub8x8_mode(cpi, x,
9262 &x->mbmi_ext->ref_mvs[ref_frame][0],
9263 second_ref, best_yrd, &rate, &rate_y,
9264 &distortion, &skippable, &total_sse,
Yue Chen1ac85872016-01-07 15:13:52 -08009265 (int) this_rd_thresh, seg_mvs,
9266#if CONFIG_EXT_INTER
9267 compound_seg_newmvs,
9268#endif // CONFIG_EXT_INTER
9269 bsi, 0,
Jingning Han3ee6db62015-08-05 19:00:31 -07009270 mi_row, mi_col);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07009271#if CONFIG_EXT_INTERP
9272 if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Debargha Mukherjeebab29122016-02-26 00:18:03 -08009273 mbmi->interp_filter != EIGHTTAP_REGULAR) {
9274 mbmi->interp_filter = EIGHTTAP_REGULAR;
Debargha Mukherjee85514c42015-10-30 09:19:36 -07009275 }
9276#endif // CONFIG_EXT_INTERP
Jingning Han3ee6db62015-08-05 19:00:31 -07009277 if (tmp_rd == INT64_MAX)
9278 continue;
9279 } else {
9280 total_sse = tmp_best_sse;
9281 rate = tmp_best_rate;
9282 rate_y = tmp_best_ratey;
9283 distortion = tmp_best_distortion;
9284 skippable = tmp_best_skippable;
9285 *mbmi = tmp_best_mbmode;
9286 for (i = 0; i < 4; i++)
9287 xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
9288 }
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08009289 // Add in the cost of the transform type
9290 if (!xd->lossless[mbmi->segment_id]) {
9291 int rate_tx_type = 0;
9292#if CONFIG_EXT_TX
9293 if (get_ext_tx_types(mbmi->tx_size, bsize, 1) > 1) {
9294 const int eset = get_ext_tx_set(mbmi->tx_size, bsize, 1);
9295 rate_tx_type =
9296 cpi->inter_tx_type_costs[eset][mbmi->tx_size][mbmi->tx_type];
9297 }
9298#else
9299 if (mbmi->tx_size < TX_32X32) {
9300 rate_tx_type = cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
9301 }
9302#endif
9303 rate += rate_tx_type;
9304 rate_y += rate_tx_type;
9305 }
Jingning Han3ee6db62015-08-05 19:00:31 -07009306
9307 rate2 += rate;
9308 distortion2 += distortion;
9309
9310 if (cm->interp_filter == SWITCHABLE)
9311 rate2 += vp10_get_switchable_rate(cpi, xd);
9312
9313 if (!mode_excluded)
9314 mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
9315 : cm->reference_mode == COMPOUND_REFERENCE;
9316
9317 compmode_cost = vp10_cost_bit(comp_mode_p, comp_pred);
9318
9319 tmp_best_rdu = best_rd -
James Zern5e16d392015-08-17 18:19:22 -07009320 VPXMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
9321 RDCOST(x->rdmult, x->rddiv, 0, total_sse));
Jingning Han3ee6db62015-08-05 19:00:31 -07009322
9323 if (tmp_best_rdu > 0) {
9324 // If even the 'Y' rd value of split is higher than best so far
9325 // then dont bother looking at UV
9326 vp10_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col,
9327 BLOCK_8X8);
9328 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
Jingning Hana8dad552015-10-08 16:46:10 -07009329#if CONFIG_VAR_TX
9330 if (!inter_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
9331 &uv_sse, BLOCK_8X8, tmp_best_rdu))
9332 continue;
9333#else
Jingning Han3ee6db62015-08-05 19:00:31 -07009334 if (!super_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
9335 &uv_sse, BLOCK_8X8, tmp_best_rdu))
9336 continue;
Jingning Hana8dad552015-10-08 16:46:10 -07009337#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07009338 rate2 += rate_uv;
9339 distortion2 += distortion_uv;
9340 skippable = skippable && uv_skippable;
9341 total_sse += uv_sse;
9342 }
9343 }
9344
9345 if (cm->reference_mode == REFERENCE_MODE_SELECT)
9346 rate2 += compmode_cost;
9347
9348 // Estimate the reference frame signaling cost and add it
9349 // to the rolling cost variable.
9350 if (second_ref_frame > INTRA_FRAME) {
9351 rate2 += ref_costs_comp[ref_frame];
9352 } else {
9353 rate2 += ref_costs_single[ref_frame];
9354 }
9355
9356 if (!disable_skip) {
9357 // Skip is never coded at the segment level for sub8x8 blocks and instead
9358 // always coded in the bitstream at the mode info level.
9359
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04009360 if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Jingning Han3ee6db62015-08-05 19:00:31 -07009361 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
9362 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
9363 // Add in the cost of the no skip flag.
9364 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
9365 } else {
9366 // FIXME(rbultje) make this work for splitmv also
9367 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
9368 distortion2 = total_sse;
9369 assert(total_sse >= 0);
9370 rate2 -= (rate_y + rate_uv);
9371 rate_y = 0;
9372 rate_uv = 0;
9373 this_skip2 = 1;
9374 }
9375 } else {
9376 // Add in the cost of the no skip flag.
9377 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
9378 }
9379
9380 // Calculate the final RD estimate for this mode.
9381 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
9382 }
9383
9384 if (!disable_skip && ref_frame == INTRA_FRAME) {
9385 for (i = 0; i < REFERENCE_MODES; ++i)
James Zern5e16d392015-08-17 18:19:22 -07009386 best_pred_rd[i] = VPXMIN(best_pred_rd[i], this_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07009387 }
9388
9389 // Did this mode help.. i.e. is it the new best mode
9390 if (this_rd < best_rd || x->skip) {
9391 if (!mode_excluded) {
9392 int max_plane = MAX_MB_PLANE;
9393 // Note index of best mode so far
9394 best_ref_index = ref_index;
9395
9396 if (ref_frame == INTRA_FRAME) {
9397 /* required for left and above block mv */
9398 mbmi->mv[0].as_int = 0;
9399 max_plane = 1;
9400 }
9401
9402 rd_cost->rate = rate2;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08009403#if CONFIG_SUPERTX
9404 *returnrate_nocoef = rate2 - rate_y - rate_uv;
9405 if (!disable_skip)
9406 *returnrate_nocoef -= vp10_cost_bit(vp10_get_skip_prob(cm, xd),
9407 this_skip2);
9408 *returnrate_nocoef -= vp10_cost_bit(vp10_get_intra_inter_prob(cm, xd),
9409 mbmi->ref_frame[0] != INTRA_FRAME);
9410 assert(*returnrate_nocoef > 0);
9411#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07009412 rd_cost->dist = distortion2;
9413 rd_cost->rdcost = this_rd;
9414 best_rd = this_rd;
9415 best_yrd = best_rd -
9416 RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
9417 best_mbmode = *mbmi;
9418 best_skip2 = this_skip2;
9419 if (!x->select_tx_size)
9420 swap_block_ptr(x, ctx, 1, 0, 0, max_plane);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07009421
9422#if CONFIG_VAR_TX
9423 for (i = 0; i < MAX_MB_PLANE; ++i)
9424 memset(ctx->blk_skip[i], 0, sizeof(uint8_t) * ctx->num_4x4_blk);
9425#else
Jingning Han3ee6db62015-08-05 19:00:31 -07009426 memcpy(ctx->zcoeff_blk, x->zcoeff_blk[TX_4X4],
hui su088b05f2015-08-12 10:41:51 -07009427 sizeof(ctx->zcoeff_blk[0]) * ctx->num_4x4_blk);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07009428#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07009429
9430 for (i = 0; i < 4; i++)
9431 best_bmodes[i] = xd->mi[0]->bmi[i];
9432
9433 // TODO(debargha): enhance this test with a better distortion prediction
9434 // based on qp, activity mask and history
9435 if ((sf->mode_search_skip_flags & FLAG_EARLY_TERMINATE) &&
9436 (ref_index > MIN_EARLY_TERM_INDEX)) {
9437 int qstep = xd->plane[0].dequant[1];
9438 // TODO(debargha): Enhance this by specializing for each mode_index
9439 int scale = 4;
9440#if CONFIG_VP9_HIGHBITDEPTH
9441 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
9442 qstep >>= (xd->bd - 8);
9443 }
9444#endif // CONFIG_VP9_HIGHBITDEPTH
9445 if (x->source_variance < UINT_MAX) {
9446 const int var_adjust = (x->source_variance < 16);
9447 scale -= var_adjust;
9448 }
9449 if (ref_frame > INTRA_FRAME &&
9450 distortion2 * scale < qstep * qstep) {
9451 early_term = 1;
9452 }
9453 }
9454 }
9455 }
9456
9457 /* keep record of best compound/single-only prediction */
9458 if (!disable_skip && ref_frame != INTRA_FRAME) {
9459 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
9460
9461 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
9462 single_rate = rate2 - compmode_cost;
9463 hybrid_rate = rate2;
9464 } else {
9465 single_rate = rate2;
9466 hybrid_rate = rate2 + compmode_cost;
9467 }
9468
9469 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
9470 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
9471
9472 if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE])
9473 best_pred_rd[SINGLE_REFERENCE] = single_rd;
9474 else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE])
9475 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
9476
9477 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
9478 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
9479 }
9480
Jingning Han3ee6db62015-08-05 19:00:31 -07009481 if (early_term)
9482 break;
9483
9484 if (x->skip && !comp_pred)
9485 break;
9486 }
9487
9488 if (best_rd >= best_rd_so_far) {
9489 rd_cost->rate = INT_MAX;
9490 rd_cost->rdcost = INT64_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08009491#if CONFIG_SUPERTX
9492 *returnrate_nocoef = INT_MAX;
9493#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07009494 return;
9495 }
9496
9497 // If we used an estimate for the uv intra rd in the loop above...
9498 if (sf->use_uv_intra_rd_estimate) {
9499 // Do Intra UV best rd mode selection if best mode choice above was intra.
9500 if (best_mbmode.ref_frame[0] == INTRA_FRAME) {
9501 *mbmi = best_mbmode;
9502 rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra,
9503 &rate_uv_tokenonly,
9504 &dist_uv,
9505 &skip_uv,
9506 BLOCK_8X8, TX_4X4);
9507 }
9508 }
9509
9510 if (best_rd == INT64_MAX) {
9511 rd_cost->rate = INT_MAX;
9512 rd_cost->dist = INT64_MAX;
9513 rd_cost->rdcost = INT64_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08009514#if CONFIG_SUPERTX
9515 *returnrate_nocoef = INT_MAX;
9516#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07009517 return;
9518 }
9519
9520 assert((cm->interp_filter == SWITCHABLE) ||
9521 (cm->interp_filter == best_mbmode.interp_filter) ||
9522 !is_inter_block(&best_mbmode));
9523
9524 vp10_update_rd_thresh_fact(tile_data->thresh_freq_fact,
9525 sf->adaptive_rd_thresh, bsize, best_ref_index);
9526
9527 // macroblock modes
9528 *mbmi = best_mbmode;
9529 x->skip |= best_skip2;
9530 if (!is_inter_block(&best_mbmode)) {
9531 for (i = 0; i < 4; i++)
9532 xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
9533 } else {
9534 for (i = 0; i < 4; ++i)
9535 memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
9536
9537 mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
9538 mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
Jingning Handf59bb82016-02-18 11:57:44 -08009539#if CONFIG_REF_MV
9540 mbmi->pred_mv[0].as_int = xd->mi[0]->bmi[3].pred_mv[0].as_int;
9541 mbmi->pred_mv[1].as_int = xd->mi[0]->bmi[3].pred_mv[1].as_int;
9542#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07009543 }
9544
9545 for (i = 0; i < REFERENCE_MODES; ++i) {
9546 if (best_pred_rd[i] == INT64_MAX)
9547 best_pred_diff[i] = INT_MIN;
9548 else
9549 best_pred_diff[i] = best_rd - best_pred_rd[i];
9550 }
9551
Jingning Han3ee6db62015-08-05 19:00:31 -07009552 store_coding_context(x, ctx, best_ref_index,
Angie Chiangb6fef122016-03-11 16:01:46 -08009553 best_pred_diff, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07009554}
Yue Chend1cad9c2016-01-27 14:18:53 -08009555
9556#if CONFIG_OBMC
9557void vp10_build_prediction_by_above_preds(VP10_COMP *cpi,
9558 MACROBLOCKD *xd,
9559 int mi_row, int mi_col,
9560 uint8_t *tmp_buf[MAX_MB_PLANE],
9561 int tmp_stride[MAX_MB_PLANE]) {
9562 VP10_COMMON *const cm = &cpi->common;
9563 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
9564 int i, j, mi_step, ref;
9565
9566 if (mi_row == 0)
9567 return;
9568
9569 for (i = 0; i < VPXMIN(xd->n8_w, cm->mi_cols - mi_col); i += mi_step) {
9570 int mi_row_offset = -1;
9571 int mi_col_offset = i;
9572 int mi_x, mi_y, bw, bh;
9573 MODE_INFO *above_mi = xd->mi[mi_col_offset +
9574 mi_row_offset * xd->mi_stride];
9575 MB_MODE_INFO *above_mbmi = &above_mi->mbmi;
9576
9577 mi_step = VPXMIN(xd->n8_w,
9578 num_8x8_blocks_wide_lookup[above_mbmi->sb_type]);
9579
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009580 if (!is_neighbor_overlappable(above_mbmi))
Yue Chend1cad9c2016-01-27 14:18:53 -08009581 continue;
9582
9583 for (j = 0; j < MAX_MB_PLANE; ++j) {
9584 struct macroblockd_plane *const pd = &xd->plane[j];
9585 setup_pred_plane(&pd->dst,
9586 tmp_buf[j], tmp_stride[j],
9587 0, i, NULL,
9588 pd->subsampling_x, pd->subsampling_y);
9589 }
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009590 /*
Yue Chend1cad9c2016-01-27 14:18:53 -08009591 set_ref_ptrs(cm, xd, above_mbmi->ref_frame[0], above_mbmi->ref_frame[1]);
9592 for (ref = 0; ref < 1 + has_second_ref(above_mbmi); ++ref) {
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009593 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(
9594 cpi, above_mbmi->ref_frame[ref]);
Yue Chend1cad9c2016-01-27 14:18:53 -08009595 assert(cfg != NULL);
9596 vp10_setup_pre_planes(xd, ref, cfg, mi_row, mi_col + i,
9597 &xd->block_refs[ref]->sf);
9598 }
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009599 */
9600 for (ref = 0; ref < 1 + has_second_ref(above_mbmi); ++ref) {
9601 MV_REFERENCE_FRAME frame = above_mbmi->ref_frame[ref];
9602 RefBuffer *ref_buf = &cm->frame_refs[frame - LAST_FRAME];
9603
9604 xd->block_refs[ref] = ref_buf;
9605 if ((!vp10_is_valid_scale(&ref_buf->sf)))
9606 vpx_internal_error(xd->error_info, VPX_CODEC_UNSUP_BITSTREAM,
9607 "Reference frame has invalid dimensions");
9608 vp10_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col + i,
9609 &ref_buf->sf);
9610 }
Yue Chend1cad9c2016-01-27 14:18:53 -08009611
9612 xd->mb_to_left_edge = -(((mi_col + i) * MI_SIZE) * 8);
9613 mi_x = (mi_col + i) << MI_SIZE_LOG2;
9614 mi_y = mi_row << MI_SIZE_LOG2;
9615
9616 for (j = 0; j < MAX_MB_PLANE; ++j) {
9617 const struct macroblockd_plane *pd = &xd->plane[j];
9618 bw = (mi_step * 8) >> pd->subsampling_x;
9619 bh = VPXMAX((num_4x4_blocks_high_lookup[bsize] * 2) >> pd->subsampling_y,
9620 4);
9621
9622 if (above_mbmi->sb_type < BLOCK_8X8) {
9623 const PARTITION_TYPE bp = BLOCK_8X8 - above_mbmi->sb_type;
9624 const int have_vsplit = bp != PARTITION_HORZ;
9625 const int have_hsplit = bp != PARTITION_VERT;
9626 const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
9627 const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);
9628 const int pw = 8 >> (have_vsplit | pd->subsampling_x);
9629 int x, y;
9630
9631 for (y = 0; y < num_4x4_h; ++y)
9632 for (x = 0; x < num_4x4_w; ++x) {
9633 if ((bp == PARTITION_HORZ || bp == PARTITION_SPLIT)
9634 && y == 0 && !pd->subsampling_y)
9635 continue;
9636
9637 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
9638 y * 2 + x, bw, bh,
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009639 4 * x, 0, pw, bh,
9640#if CONFIG_SUPERTX && CONFIG_EXT_INTER
9641 0, 0,
9642#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
9643 mi_x, mi_y);
Yue Chend1cad9c2016-01-27 14:18:53 -08009644 }
9645 } else {
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009646 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
9647 0, bw, bh, 0, 0, bw, bh,
9648#if CONFIG_SUPERTX && CONFIG_EXT_INTER
9649 0, 0,
9650#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
9651 mi_x, mi_y);
Yue Chend1cad9c2016-01-27 14:18:53 -08009652 }
9653 }
9654 }
9655 xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8);
9656}
9657
9658void vp10_build_prediction_by_left_preds(VP10_COMP *cpi,
9659 MACROBLOCKD *xd,
9660 int mi_row, int mi_col,
9661 uint8_t *tmp_buf[MAX_MB_PLANE],
9662 int tmp_stride[MAX_MB_PLANE]) {
9663 VP10_COMMON *const cm = &cpi->common;
9664 const TileInfo *const tile = &xd->tile;
9665 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
9666 int i, j, mi_step, ref;
9667
9668 if (mi_col == 0 || (mi_col - 1 < tile->mi_col_start) ||
9669 (mi_col - 1) >= tile->mi_col_end)
9670 return;
9671
9672 for (i = 0; i < VPXMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) {
9673 int mi_row_offset = i;
9674 int mi_col_offset = -1;
9675 int mi_x, mi_y, bw, bh;
9676 MODE_INFO *left_mi = xd->mi[mi_col_offset +
9677 mi_row_offset * xd->mi_stride];
9678 MB_MODE_INFO *left_mbmi = &left_mi->mbmi;
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009679 const int is_compound = has_second_ref(left_mbmi);
Yue Chend1cad9c2016-01-27 14:18:53 -08009680
9681 mi_step = VPXMIN(xd->n8_h,
9682 num_8x8_blocks_high_lookup[left_mbmi->sb_type]);
9683
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009684 if (!is_neighbor_overlappable(left_mbmi))
Yue Chend1cad9c2016-01-27 14:18:53 -08009685 continue;
9686
9687 for (j = 0; j < MAX_MB_PLANE; ++j) {
9688 struct macroblockd_plane *const pd = &xd->plane[j];
9689 setup_pred_plane(&pd->dst,
9690 tmp_buf[j], tmp_stride[j],
9691 i, 0, NULL,
9692 pd->subsampling_x, pd->subsampling_y);
9693 }
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009694 /*
Yue Chend1cad9c2016-01-27 14:18:53 -08009695 set_ref_ptrs(cm, xd, left_mbmi->ref_frame[0], left_mbmi->ref_frame[1]);
9696 for (ref = 0; ref < 1 + has_second_ref(left_mbmi); ++ref) {
9697 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi,
9698 left_mbmi->ref_frame[ref]);
9699 assert(cfg != NULL);
9700 vp10_setup_pre_planes(xd, ref, cfg, mi_row + i, mi_col,
9701 &xd->block_refs[ref]->sf);
9702 }
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009703 */
9704 for (ref = 0; ref < 1 + is_compound; ++ref) {
9705 MV_REFERENCE_FRAME frame = left_mbmi->ref_frame[ref];
9706 RefBuffer *ref_buf = &cm->frame_refs[frame - LAST_FRAME];
9707
9708 xd->block_refs[ref] = ref_buf;
9709 if ((!vp10_is_valid_scale(&ref_buf->sf)))
9710 vpx_internal_error(xd->error_info, VPX_CODEC_UNSUP_BITSTREAM,
9711 "Reference frame has invalid dimensions");
9712 vp10_setup_pre_planes(xd, ref, ref_buf->buf, mi_row + i, mi_col,
9713 &ref_buf->sf);
9714 }
Yue Chend1cad9c2016-01-27 14:18:53 -08009715
9716 xd->mb_to_top_edge = -(((mi_row + i) * MI_SIZE) * 8);
9717 mi_x = mi_col << MI_SIZE_LOG2;
9718 mi_y = (mi_row + i) << MI_SIZE_LOG2;
9719
9720 for (j = 0; j < MAX_MB_PLANE; ++j) {
9721 const struct macroblockd_plane *pd = &xd->plane[j];
9722 bw = VPXMAX((num_4x4_blocks_wide_lookup[bsize] * 2) >> pd->subsampling_x,
9723 4);
9724 bh = (mi_step << MI_SIZE_LOG2) >> pd->subsampling_y;
9725
9726 if (left_mbmi->sb_type < BLOCK_8X8) {
9727 const PARTITION_TYPE bp = BLOCK_8X8 - left_mbmi->sb_type;
9728 const int have_vsplit = bp != PARTITION_HORZ;
9729 const int have_hsplit = bp != PARTITION_VERT;
9730 const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
9731 const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);
9732 const int ph = 8 >> (have_hsplit | pd->subsampling_y);
9733 int x, y;
9734
9735 for (y = 0; y < num_4x4_h; ++y)
9736 for (x = 0; x < num_4x4_w; ++x) {
9737 if ((bp == PARTITION_VERT || bp == PARTITION_SPLIT)
9738 && x == 0 && !pd->subsampling_x)
9739 continue;
9740
9741 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
9742 y * 2 + x, bw, bh,
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009743 0, 4 * y, bw, ph,
9744#if CONFIG_SUPERTX && CONFIG_EXT_INTER
9745 0, 0,
9746#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
9747 mi_x, mi_y);
Yue Chend1cad9c2016-01-27 14:18:53 -08009748 }
9749 } else {
9750 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0,
Debargha Mukherjeef34deab2016-02-29 16:08:07 -08009751 bw, bh, 0, 0, bw, bh,
9752#if CONFIG_SUPERTX && CONFIG_EXT_INTER
9753 0, 0,
9754#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
9755 mi_x, mi_y);
Yue Chend1cad9c2016-01-27 14:18:53 -08009756 }
9757 }
9758 }
9759 xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8);
9760}
9761#endif // CONFIG_OBMC