blob: ba864e40d0fcfd78dbf16482d4fd73dad4f39f92 [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
Geza Lore7ded0382016-02-22 10:55:32 +000047// TODO(geza.lore) Update this when the extended coding unit size experiment
48// have been ported.
49#define CU_SIZE 64
50
Zoe Liu3ec16012015-11-12 02:12:17 -080051#if CONFIG_EXT_REFS
52
53#define LAST_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \
54 (1 << LAST2_FRAME) | (1 << INTRA_FRAME) | \
55 (1 << LAST3_FRAME) | (1 << LAST4_FRAME))
56#define LAST2_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \
57 (1 << LAST_FRAME) | (1 << INTRA_FRAME) | \
58 (1 << LAST3_FRAME) | (1 << LAST4_FRAME))
59#define LAST3_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \
60 (1 << LAST_FRAME) | (1 << INTRA_FRAME) | \
61 (1 << LAST2_FRAME) | (1 << LAST4_FRAME))
62#define LAST4_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \
63 (1 << LAST_FRAME) | (1 << INTRA_FRAME) | \
64 (1 << LAST2_FRAME) | (1 << LAST3_FRAME))
65#define GOLDEN_FRAME_MODE_MASK ((1 << LAST_FRAME) | (1 << ALTREF_FRAME) | \
66 (1 << LAST2_FRAME) | (1 << INTRA_FRAME) | \
67 (1 << LAST3_FRAME) | (1 << LAST4_FRAME))
68#define ALT_REF_MODE_MASK ((1 << LAST_FRAME) | (1 << GOLDEN_FRAME) | \
69 (1 << LAST2_FRAME) | (1 << INTRA_FRAME) | \
70 (1 << LAST3_FRAME) | (1 << LAST4_FRAME))
71
72#else
73
Jingning Han3ee6db62015-08-05 19:00:31 -070074#define LAST_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \
75 (1 << INTRA_FRAME))
76#define GOLDEN_FRAME_MODE_MASK ((1 << LAST_FRAME) | (1 << ALTREF_FRAME) | \
77 (1 << INTRA_FRAME))
78#define ALT_REF_MODE_MASK ((1 << LAST_FRAME) | (1 << GOLDEN_FRAME) | \
79 (1 << INTRA_FRAME))
80
Zoe Liu3ec16012015-11-12 02:12:17 -080081#endif // CONFIG_EXT_REFS
82
Jingning Han3ee6db62015-08-05 19:00:31 -070083#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | 0x01)
84
85#define MIN_EARLY_TERM_INDEX 3
86#define NEW_MV_DISCOUNT_FACTOR 8
87
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -070088#if CONFIG_EXT_TX
Debargha Mukherjeeda2d4a72016-02-12 16:44:33 -080089const double ext_tx_th = 0.99;
Yaowu Xu0367f322016-01-11 10:27:35 -080090#else
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -080091const double ext_tx_th = 0.99;
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -070092#endif
93
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -080094
Jingning Han3ee6db62015-08-05 19:00:31 -070095typedef struct {
96 PREDICTION_MODE mode;
97 MV_REFERENCE_FRAME ref_frame[2];
98} MODE_DEFINITION;
99
100typedef struct {
101 MV_REFERENCE_FRAME ref_frame[2];
102} REF_DEFINITION;
103
104struct rdcost_block_args {
Jingning Han71c15602015-10-13 12:40:39 -0700105 const VP10_COMP *cpi;
Jingning Han3ee6db62015-08-05 19:00:31 -0700106 MACROBLOCK *x;
107 ENTROPY_CONTEXT t_above[16];
108 ENTROPY_CONTEXT t_left[16];
109 int this_rate;
110 int64_t this_dist;
111 int64_t this_sse;
112 int64_t this_rd;
113 int64_t best_rd;
114 int exit_early;
115 int use_fast_coef_costing;
116 const scan_order *so;
117 uint8_t skippable;
118};
119
120#define LAST_NEW_MV_INDEX 6
121static const MODE_DEFINITION vp10_mode_order[MAX_MODES] = {
122 {NEARESTMV, {LAST_FRAME, NONE}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800123#if CONFIG_EXT_REFS
124 {NEARESTMV, {LAST2_FRAME, NONE}},
125 {NEARESTMV, {LAST3_FRAME, NONE}},
126 {NEARESTMV, {LAST4_FRAME, NONE}},
127#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700128 {NEARESTMV, {ALTREF_FRAME, NONE}},
129 {NEARESTMV, {GOLDEN_FRAME, NONE}},
130
131 {DC_PRED, {INTRA_FRAME, NONE}},
132
133 {NEWMV, {LAST_FRAME, NONE}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800134#if CONFIG_EXT_REFS
135 {NEWMV, {LAST2_FRAME, NONE}},
136 {NEWMV, {LAST3_FRAME, NONE}},
137 {NEWMV, {LAST4_FRAME, NONE}},
138#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700139 {NEWMV, {ALTREF_FRAME, NONE}},
140 {NEWMV, {GOLDEN_FRAME, NONE}},
141
142 {NEARMV, {LAST_FRAME, NONE}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800143#if CONFIG_EXT_REFS
144 {NEARMV, {LAST2_FRAME, NONE}},
145 {NEARMV, {LAST3_FRAME, NONE}},
146 {NEARMV, {LAST4_FRAME, NONE}},
147#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700148 {NEARMV, {ALTREF_FRAME, NONE}},
149 {NEARMV, {GOLDEN_FRAME, NONE}},
150
Yue Chen1ac85872016-01-07 15:13:52 -0800151#if CONFIG_EXT_INTER
152 {NEWFROMNEARMV, {LAST_FRAME, NONE}},
Yue Chen968bbc72016-01-19 16:45:45 -0800153#if CONFIG_EXT_REFS
Yue Chen1ac85872016-01-07 15:13:52 -0800154 {NEWFROMNEARMV, {LAST2_FRAME, NONE}},
155 {NEWFROMNEARMV, {LAST3_FRAME, NONE}},
156 {NEWFROMNEARMV, {LAST4_FRAME, NONE}},
Yue Chen968bbc72016-01-19 16:45:45 -0800157#endif // CONFIG_EXT_REFS
Yue Chen1ac85872016-01-07 15:13:52 -0800158 {NEWFROMNEARMV, {ALTREF_FRAME, NONE}},
159 {NEWFROMNEARMV, {GOLDEN_FRAME, NONE}},
160#endif // CONFIG_EXT_INTER
161
Jingning Han3ee6db62015-08-05 19:00:31 -0700162 {ZEROMV, {LAST_FRAME, NONE}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800163#if CONFIG_EXT_REFS
164 {ZEROMV, {LAST2_FRAME, NONE}},
165 {ZEROMV, {LAST3_FRAME, NONE}},
166 {ZEROMV, {LAST4_FRAME, NONE}},
167#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700168 {ZEROMV, {GOLDEN_FRAME, NONE}},
169 {ZEROMV, {ALTREF_FRAME, NONE}},
170
Yue Chen968bbc72016-01-19 16:45:45 -0800171#if CONFIG_EXT_INTER
172 {NEAREST_NEARESTMV, {LAST_FRAME, ALTREF_FRAME}},
173#if CONFIG_EXT_REFS
174 {NEAREST_NEARESTMV, {LAST2_FRAME, ALTREF_FRAME}},
175 {NEAREST_NEARESTMV, {LAST3_FRAME, ALTREF_FRAME}},
176 {NEAREST_NEARESTMV, {LAST4_FRAME, ALTREF_FRAME}},
177#endif // CONFIG_EXT_REFS
178 {NEAREST_NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
179#else // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -0700180 {NEARESTMV, {LAST_FRAME, ALTREF_FRAME}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800181#if CONFIG_EXT_REFS
182 {NEARESTMV, {LAST2_FRAME, ALTREF_FRAME}},
183 {NEARESTMV, {LAST3_FRAME, ALTREF_FRAME}},
184 {NEARESTMV, {LAST4_FRAME, ALTREF_FRAME}},
185#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700186 {NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
Yue Chen968bbc72016-01-19 16:45:45 -0800187#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -0700188
189 {TM_PRED, {INTRA_FRAME, NONE}},
190
Yue Chen968bbc72016-01-19 16:45:45 -0800191#if CONFIG_EXT_INTER
192 {NEAR_NEARESTMV, {LAST_FRAME, ALTREF_FRAME}},
193 {NEAR_NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
194 {NEAREST_NEARMV, {LAST_FRAME, ALTREF_FRAME}},
195 {NEAREST_NEARMV, {GOLDEN_FRAME, ALTREF_FRAME}},
196 {NEW_NEARESTMV, {LAST_FRAME, ALTREF_FRAME}},
197 {NEW_NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
198 {NEAREST_NEWMV, {LAST_FRAME, ALTREF_FRAME}},
199 {NEAREST_NEWMV, {GOLDEN_FRAME, ALTREF_FRAME}},
200 {NEW_NEARMV, {LAST_FRAME, ALTREF_FRAME}},
201 {NEW_NEARMV, {GOLDEN_FRAME, ALTREF_FRAME}},
202 {NEAR_NEWMV, {LAST_FRAME, ALTREF_FRAME}},
203 {NEAR_NEWMV, {GOLDEN_FRAME, ALTREF_FRAME}},
204 {NEW_NEWMV, {LAST_FRAME, ALTREF_FRAME}},
205 {NEW_NEWMV, {GOLDEN_FRAME, ALTREF_FRAME}},
206 {ZERO_ZEROMV, {LAST_FRAME, ALTREF_FRAME}},
207 {ZERO_ZEROMV, {GOLDEN_FRAME, ALTREF_FRAME}},
208#if CONFIG_EXT_REFS
209 {NEAR_NEARESTMV, {LAST2_FRAME, ALTREF_FRAME}},
210 {NEAREST_NEARMV, {LAST2_FRAME, ALTREF_FRAME}},
211 {NEW_NEARESTMV, {LAST2_FRAME, ALTREF_FRAME}},
212 {NEAREST_NEWMV, {LAST2_FRAME, ALTREF_FRAME}},
213 {NEW_NEARMV, {LAST2_FRAME, ALTREF_FRAME}},
214 {NEAR_NEWMV, {LAST2_FRAME, ALTREF_FRAME}},
215 {NEW_NEWMV, {LAST2_FRAME, ALTREF_FRAME}},
216 {ZERO_ZEROMV, {LAST2_FRAME, ALTREF_FRAME}},
217
218 {NEAR_NEARESTMV, {LAST3_FRAME, ALTREF_FRAME}},
219 {NEAREST_NEARMV, {LAST3_FRAME, ALTREF_FRAME}},
220 {NEW_NEARESTMV, {LAST3_FRAME, ALTREF_FRAME}},
221 {NEAREST_NEWMV, {LAST3_FRAME, ALTREF_FRAME}},
222 {NEW_NEARMV, {LAST3_FRAME, ALTREF_FRAME}},
223 {NEAR_NEWMV, {LAST3_FRAME, ALTREF_FRAME}},
224 {NEW_NEWMV, {LAST3_FRAME, ALTREF_FRAME}},
225 {ZERO_ZEROMV, {LAST3_FRAME, ALTREF_FRAME}},
226
227 {NEAR_NEARESTMV, {LAST4_FRAME, ALTREF_FRAME}},
228 {NEAREST_NEARMV, {LAST4_FRAME, ALTREF_FRAME}},
229 {NEW_NEARESTMV, {LAST4_FRAME, ALTREF_FRAME}},
230 {NEAREST_NEWMV, {LAST4_FRAME, ALTREF_FRAME}},
231 {NEW_NEARMV, {LAST4_FRAME, ALTREF_FRAME}},
232 {NEAR_NEWMV, {LAST4_FRAME, ALTREF_FRAME}},
233 {NEW_NEWMV, {LAST4_FRAME, ALTREF_FRAME}},
234 {ZERO_ZEROMV, {LAST4_FRAME, ALTREF_FRAME}},
235#endif // CONFIG_EXT_REFS
236#else
Jingning Han3ee6db62015-08-05 19:00:31 -0700237 {NEARMV, {LAST_FRAME, ALTREF_FRAME}},
238 {NEWMV, {LAST_FRAME, ALTREF_FRAME}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800239#if CONFIG_EXT_REFS
240 {NEARMV, {LAST2_FRAME, ALTREF_FRAME}},
241 {NEWMV, {LAST2_FRAME, ALTREF_FRAME}},
242 {NEARMV, {LAST3_FRAME, ALTREF_FRAME}},
243 {NEWMV, {LAST3_FRAME, ALTREF_FRAME}},
244 {NEARMV, {LAST4_FRAME, ALTREF_FRAME}},
245 {NEWMV, {LAST4_FRAME, ALTREF_FRAME}},
246#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700247 {NEARMV, {GOLDEN_FRAME, ALTREF_FRAME}},
248 {NEWMV, {GOLDEN_FRAME, ALTREF_FRAME}},
249
250 {ZEROMV, {LAST_FRAME, ALTREF_FRAME}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800251#if CONFIG_EXT_REFS
252 {ZEROMV, {LAST3_FRAME, ALTREF_FRAME}},
253 {ZEROMV, {LAST2_FRAME, ALTREF_FRAME}},
254 {ZEROMV, {LAST4_FRAME, ALTREF_FRAME}},
255#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700256 {ZEROMV, {GOLDEN_FRAME, ALTREF_FRAME}},
Yue Chen968bbc72016-01-19 16:45:45 -0800257#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -0700258
259 {H_PRED, {INTRA_FRAME, NONE}},
260 {V_PRED, {INTRA_FRAME, NONE}},
261 {D135_PRED, {INTRA_FRAME, NONE}},
262 {D207_PRED, {INTRA_FRAME, NONE}},
263 {D153_PRED, {INTRA_FRAME, NONE}},
264 {D63_PRED, {INTRA_FRAME, NONE}},
265 {D117_PRED, {INTRA_FRAME, NONE}},
266 {D45_PRED, {INTRA_FRAME, NONE}},
Geza Lore7ded0382016-02-22 10:55:32 +0000267
268#if CONFIG_EXT_INTER
269 {ZEROMV, {LAST_FRAME, INTRA_FRAME}},
270 {NEARESTMV, {LAST_FRAME, INTRA_FRAME}},
271 {NEARMV, {LAST_FRAME, INTRA_FRAME}},
272 {NEWMV, {LAST_FRAME, INTRA_FRAME}},
273
274#if CONFIG_EXT_REFS
275 {ZEROMV, {LAST2_FRAME, INTRA_FRAME}},
276 {NEARESTMV, {LAST2_FRAME, INTRA_FRAME}},
277 {NEARMV, {LAST2_FRAME, INTRA_FRAME}},
278 {NEWMV, {LAST2_FRAME, INTRA_FRAME}},
279
280 {ZEROMV, {LAST3_FRAME, INTRA_FRAME}},
281 {NEARESTMV, {LAST3_FRAME, INTRA_FRAME}},
282 {NEARMV, {LAST3_FRAME, INTRA_FRAME}},
283 {NEWMV, {LAST3_FRAME, INTRA_FRAME}},
284
285 {ZEROMV, {LAST4_FRAME, INTRA_FRAME}},
286 {NEARESTMV, {LAST4_FRAME, INTRA_FRAME}},
287 {NEARMV, {LAST4_FRAME, INTRA_FRAME}},
288 {NEWMV, {LAST4_FRAME, INTRA_FRAME}},
289#endif // CONFIG_EXT_REFS
290
291 {ZEROMV, {GOLDEN_FRAME, INTRA_FRAME}},
292 {NEARESTMV, {GOLDEN_FRAME, INTRA_FRAME}},
293 {NEARMV, {GOLDEN_FRAME, INTRA_FRAME}},
294 {NEWMV, {GOLDEN_FRAME, INTRA_FRAME}},
295
296 {ZEROMV, {ALTREF_FRAME, INTRA_FRAME}},
297 {NEARESTMV, {ALTREF_FRAME, INTRA_FRAME}},
298 {NEARMV, {ALTREF_FRAME, INTRA_FRAME}},
299 {NEWMV, {ALTREF_FRAME, INTRA_FRAME}},
300#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -0700301};
302
303static const REF_DEFINITION vp10_ref_order[MAX_REFS] = {
304 {{LAST_FRAME, NONE}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800305#if CONFIG_EXT_REFS
306 {{LAST2_FRAME, NONE}},
307 {{LAST3_FRAME, NONE}},
308 {{LAST4_FRAME, NONE}},
309#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700310 {{GOLDEN_FRAME, NONE}},
311 {{ALTREF_FRAME, NONE}},
312 {{LAST_FRAME, ALTREF_FRAME}},
Zoe Liu3ec16012015-11-12 02:12:17 -0800313#if CONFIG_EXT_REFS
314 {{LAST2_FRAME, ALTREF_FRAME}},
315 {{LAST3_FRAME, ALTREF_FRAME}},
316 {{LAST4_FRAME, ALTREF_FRAME}},
317#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -0700318 {{GOLDEN_FRAME, ALTREF_FRAME}},
319 {{INTRA_FRAME, NONE}},
320};
321
hui su5d011cb2015-09-15 12:44:13 -0700322static INLINE int write_uniform_cost(int n, int v) {
323 int l = get_unsigned_bits(n), m = (1 << l) - n;
324 if (l == 0)
325 return 0;
326 if (v < m)
327 return (l - 1) * vp10_cost_bit(128, 0);
328 else
329 return l * vp10_cost_bit(128, 0);
330}
331
Jingning Han3ee6db62015-08-05 19:00:31 -0700332static void swap_block_ptr(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
333 int m, int n, int min_plane, int max_plane) {
334 int i;
335
336 for (i = min_plane; i < max_plane; ++i) {
337 struct macroblock_plane *const p = &x->plane[i];
338 struct macroblockd_plane *const pd = &x->e_mbd.plane[i];
339
340 p->coeff = ctx->coeff_pbuf[i][m];
341 p->qcoeff = ctx->qcoeff_pbuf[i][m];
342 pd->dqcoeff = ctx->dqcoeff_pbuf[i][m];
343 p->eobs = ctx->eobs_pbuf[i][m];
344
345 ctx->coeff_pbuf[i][m] = ctx->coeff_pbuf[i][n];
346 ctx->qcoeff_pbuf[i][m] = ctx->qcoeff_pbuf[i][n];
347 ctx->dqcoeff_pbuf[i][m] = ctx->dqcoeff_pbuf[i][n];
348 ctx->eobs_pbuf[i][m] = ctx->eobs_pbuf[i][n];
349
350 ctx->coeff_pbuf[i][n] = p->coeff;
351 ctx->qcoeff_pbuf[i][n] = p->qcoeff;
352 ctx->dqcoeff_pbuf[i][n] = pd->dqcoeff;
353 ctx->eobs_pbuf[i][n] = p->eobs;
354 }
355}
356
Sarah Parker2ca7d422016-03-01 10:12:13 -0800357#if CONFIG_EXT_TX
358typedef enum {
359 DCT_1D = 0,
360 ADST_1D = 1,
361 FLIPADST_1D = 2,
362 DST_1D = 3,
363 TX_TYPES_1D = 4,
364} TX_TYPE_1D;
365
366static int prune_two_for_sby(const VP10_COMP *cpi,
367 BLOCK_SIZE bsize,
368 MACROBLOCK *x,
369 MACROBLOCKD *xd) {
370 (void) cpi;
371 (void) bsize;
372 (void) x;
373 (void) xd;
374 return 3;
375}
376
377static int prune_three_for_sby(const VP10_COMP *cpi,
378 BLOCK_SIZE bsize,
379 MACROBLOCK *x,
380 MACROBLOCKD *xd) {
381 (void) cpi;
382 (void) bsize;
383 (void) x;
384 (void) xd;
385 return 7;
386}
387
388#endif // CONFIG_EXT_TX
389
390static int prune_one_for_sby(const VP10_COMP *cpi,
391 BLOCK_SIZE bsize,
392 MACROBLOCK *x,
393 MACROBLOCKD *xd) {
394 (void) cpi;
395 (void) bsize;
396 (void) x;
397 (void) xd;
398 return 1;
399}
400
401static int prune_tx_types(const VP10_COMP *cpi,
402 BLOCK_SIZE bsize,
403 MACROBLOCK *x,
404 MACROBLOCKD *xd) {
405 switch (cpi->sf.tx_type_search) {
406 case NO_PRUNE:
407 return 0;
408 break;
409 case PRUNE_ONE :
410 return prune_one_for_sby(cpi, bsize, x, xd);
411 break;
412 #if CONFIG_EXT_TX
413 case PRUNE_TWO :
414 return prune_two_for_sby(cpi, bsize, x, xd);
415 break;
416 case PRUNE_THREE :
417 return prune_three_for_sby(cpi, bsize, x, xd);
418 break;
419 #endif
420 }
421 assert(0);
422 return 0;
423}
424
425static int do_tx_type_search(TX_TYPE tx_type,
426 int prune) {
427// TODO(sarahparker) implement for non ext tx
428#if CONFIG_EXT_TX
429 static TX_TYPE_1D vtx_tab[TX_TYPES] = {
430 DCT_1D,
431 ADST_1D,
432 DCT_1D,
433 ADST_1D,
434 FLIPADST_1D,
435 DCT_1D,
436 FLIPADST_1D,
437 ADST_1D,
438 FLIPADST_1D,
439 DST_1D,
440 DCT_1D,
441 DST_1D,
442 ADST_1D,
443 DST_1D,
444 FLIPADST_1D,
445 DST_1D,
446 };
447 static TX_TYPE_1D htx_tab[TX_TYPES] = {
448 DCT_1D,
449 DCT_1D,
450 ADST_1D,
451 ADST_1D,
452 DCT_1D,
453 FLIPADST_1D,
454 FLIPADST_1D,
455 FLIPADST_1D,
456 ADST_1D,
457 DCT_1D,
458 DST_1D,
459 ADST_1D,
460 DST_1D,
461 FLIPADST_1D,
462 DST_1D,
463 DST_1D,
464 };
465 if (tx_type == IDTX)
466 return 1;
467 return !(((prune >> vtx_tab[tx_type]) & 1) |
468 ((prune >> (htx_tab[tx_type] + TX_TYPES_1D)) & 1));
469#else
470 // temporary to avoid compiler warnings
471 (void) tx_type;
472 (void) prune;
473 return 1;
474#endif
475}
476
Yaowu Xu26a9afc2015-08-13 09:42:27 -0700477static void model_rd_for_sb(VP10_COMP *cpi, BLOCK_SIZE bsize,
Jingning Han3ee6db62015-08-05 19:00:31 -0700478 MACROBLOCK *x, MACROBLOCKD *xd,
479 int *out_rate_sum, int64_t *out_dist_sum,
480 int *skip_txfm_sb, int64_t *skip_sse_sb) {
481 // Note our transform coeffs are 8 times an orthogonal transform.
482 // Hence quantizer step is also 8 times. To get effective quantizer
483 // we need to divide by 8 before sending to modeling function.
484 int i;
485 int64_t rate_sum = 0;
486 int64_t dist_sum = 0;
487 const int ref = xd->mi[0]->mbmi.ref_frame[0];
488 unsigned int sse;
489 unsigned int var = 0;
490 unsigned int sum_sse = 0;
491 int64_t total_sse = 0;
492 int skip_flag = 1;
493 const int shift = 6;
494 int rate;
495 int64_t dist;
496 const int dequant_shift =
497#if CONFIG_VP9_HIGHBITDEPTH
498 (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ?
499 xd->bd - 5 :
500#endif // CONFIG_VP9_HIGHBITDEPTH
501 3;
502
503 x->pred_sse[ref] = 0;
504
505 for (i = 0; i < MAX_MB_PLANE; ++i) {
506 struct macroblock_plane *const p = &x->plane[i];
507 struct macroblockd_plane *const pd = &xd->plane[i];
508 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
509 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
510 const BLOCK_SIZE unit_size = txsize_to_bsize[max_tx_size];
511 const int64_t dc_thr = p->quant_thred[0] >> shift;
512 const int64_t ac_thr = p->quant_thred[1] >> shift;
513 // The low thresholds are used to measure if the prediction errors are
514 // low enough so that we can skip the mode search.
James Zern5e16d392015-08-17 18:19:22 -0700515 const int64_t low_dc_thr = VPXMIN(50, dc_thr >> 2);
516 const int64_t low_ac_thr = VPXMIN(80, ac_thr >> 2);
Sarah Parker2ca7d422016-03-01 10:12:13 -0800517 int bw_shift = (b_width_log2_lookup[bs] - b_width_log2_lookup[unit_size]);
518 int bh_shift = (b_height_log2_lookup[bs] - b_width_log2_lookup[unit_size]);
519 int bw = 1 << bw_shift;
520 int bh = 1 << bh_shift;
Jingning Han3ee6db62015-08-05 19:00:31 -0700521 int idx, idy;
522 int lw = b_width_log2_lookup[unit_size] + 2;
523 int lh = b_height_log2_lookup[unit_size] + 2;
524
525 sum_sse = 0;
526
527 for (idy = 0; idy < bh; ++idy) {
528 for (idx = 0; idx < bw; ++idx) {
529 uint8_t *src = p->src.buf + (idy * p->src.stride << lh) + (idx << lw);
530 uint8_t *dst = pd->dst.buf + (idy * pd->dst.stride << lh) + (idx << lh);
Sarah Parker2ca7d422016-03-01 10:12:13 -0800531 int block_idx = (idy << bw_shift) + idx;
Jingning Han3ee6db62015-08-05 19:00:31 -0700532 int low_err_skip = 0;
533
534 var = cpi->fn_ptr[unit_size].vf(src, p->src.stride,
535 dst, pd->dst.stride, &sse);
536 x->bsse[(i << 2) + block_idx] = sse;
537 sum_sse += sse;
538
539 x->skip_txfm[(i << 2) + block_idx] = SKIP_TXFM_NONE;
540 if (!x->select_tx_size) {
541 // Check if all ac coefficients can be quantized to zero.
542 if (var < ac_thr || var == 0) {
543 x->skip_txfm[(i << 2) + block_idx] = SKIP_TXFM_AC_ONLY;
544
545 // Check if dc coefficient can be quantized to zero.
546 if (sse - var < dc_thr || sse == var) {
547 x->skip_txfm[(i << 2) + block_idx] = SKIP_TXFM_AC_DC;
548
549 if (!sse || (var < low_ac_thr && sse - var < low_dc_thr))
550 low_err_skip = 1;
551 }
552 }
553 }
554
555 if (skip_flag && !low_err_skip)
556 skip_flag = 0;
557
558 if (i == 0)
559 x->pred_sse[ref] += sse;
560 }
561 }
562
563 total_sse += sum_sse;
564
565 // Fast approximate the modelling function.
566 if (cpi->sf.simple_model_rd_from_var) {
567 int64_t rate;
568 const int64_t square_error = sum_sse;
569 int quantizer = (pd->dequant[1] >> dequant_shift);
570
571 if (quantizer < 120)
Alex Converseb3ad8122016-02-10 14:12:26 -0800572 rate = (square_error * (280 - quantizer)) >> (16 - VP9_PROB_COST_SHIFT);
Jingning Han3ee6db62015-08-05 19:00:31 -0700573 else
574 rate = 0;
575 dist = (square_error * quantizer) >> 8;
576 rate_sum += rate;
577 dist_sum += dist;
578 } else {
579 vp10_model_rd_from_var_lapndz(sum_sse, num_pels_log2_lookup[bs],
580 pd->dequant[1] >> dequant_shift,
581 &rate, &dist);
582 rate_sum += rate;
583 dist_sum += dist;
584 }
585 }
586
587 *skip_txfm_sb = skip_flag;
588 *skip_sse_sb = total_sse << 4;
589 *out_rate_sum = (int)rate_sum;
590 *out_dist_sum = dist_sum << 4;
591}
592
593int64_t vp10_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff,
594 intptr_t block_size, int64_t *ssz) {
595 int i;
596 int64_t error = 0, sqcoeff = 0;
597
598 for (i = 0; i < block_size; i++) {
599 const int diff = coeff[i] - dqcoeff[i];
600 error += diff * diff;
601 sqcoeff += coeff[i] * coeff[i];
602 }
603
604 *ssz = sqcoeff;
605 return error;
606}
607
608int64_t vp10_block_error_fp_c(const int16_t *coeff, const int16_t *dqcoeff,
609 int block_size) {
610 int i;
611 int64_t error = 0;
612
613 for (i = 0; i < block_size; i++) {
614 const int diff = coeff[i] - dqcoeff[i];
615 error += diff * diff;
616 }
617
618 return error;
619}
620
621#if CONFIG_VP9_HIGHBITDEPTH
622int64_t vp10_highbd_block_error_c(const tran_low_t *coeff,
623 const tran_low_t *dqcoeff,
624 intptr_t block_size,
625 int64_t *ssz, int bd) {
626 int i;
627 int64_t error = 0, sqcoeff = 0;
628 int shift = 2 * (bd - 8);
629 int rounding = shift > 0 ? 1 << (shift - 1) : 0;
630
631 for (i = 0; i < block_size; i++) {
632 const int64_t diff = coeff[i] - dqcoeff[i];
633 error += diff * diff;
634 sqcoeff += (int64_t)coeff[i] * (int64_t)coeff[i];
635 }
636 assert(error >= 0 && sqcoeff >= 0);
637 error = (error + rounding) >> shift;
638 sqcoeff = (sqcoeff + rounding) >> shift;
639
640 *ssz = sqcoeff;
641 return error;
642}
643#endif // CONFIG_VP9_HIGHBITDEPTH
644
645/* The trailing '0' is a terminator which is used inside cost_coeffs() to
646 * decide whether to include cost of a trailing EOB node or not (i.e. we
647 * can skip this if the last coefficient in this transform block, e.g. the
648 * 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block,
649 * were non-zero). */
650static const int16_t band_counts[TX_SIZES][8] = {
651 { 1, 2, 3, 4, 3, 16 - 13, 0 },
652 { 1, 2, 3, 4, 11, 64 - 21, 0 },
653 { 1, 2, 3, 4, 11, 256 - 21, 0 },
654 { 1, 2, 3, 4, 11, 1024 - 21, 0 },
655};
656static int cost_coeffs(MACROBLOCK *x,
657 int plane, int block,
Jingning Han2cdc1272015-10-09 09:57:42 -0700658#if CONFIG_VAR_TX
659 int coeff_ctx,
660#else
Jingning Han3ee6db62015-08-05 19:00:31 -0700661 ENTROPY_CONTEXT *A, ENTROPY_CONTEXT *L,
Jingning Han2cdc1272015-10-09 09:57:42 -0700662#endif
Jingning Han3ee6db62015-08-05 19:00:31 -0700663 TX_SIZE tx_size,
664 const int16_t *scan, const int16_t *nb,
665 int use_fast_coef_costing) {
666 MACROBLOCKD *const xd = &x->e_mbd;
667 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
668 const struct macroblock_plane *p = &x->plane[plane];
669 const struct macroblockd_plane *pd = &xd->plane[plane];
670 const PLANE_TYPE type = pd->plane_type;
671 const int16_t *band_count = &band_counts[tx_size][1];
672 const int eob = p->eobs[block];
673 const tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
674 unsigned int (*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
675 x->token_costs[tx_size][type][is_inter_block(mbmi)];
676 uint8_t token_cache[32 * 32];
Jingning Han2cdc1272015-10-09 09:57:42 -0700677#if CONFIG_VAR_TX
678 int pt = coeff_ctx;
679#else
Jingning Han3ee6db62015-08-05 19:00:31 -0700680 int pt = combine_entropy_contexts(*A, *L);
Jingning Han2cdc1272015-10-09 09:57:42 -0700681#endif
Jingning Han3ee6db62015-08-05 19:00:31 -0700682 int c, cost;
683#if CONFIG_VP9_HIGHBITDEPTH
Alex Converseb3ad8122016-02-10 14:12:26 -0800684 const int *cat6_high_cost = vp10_get_high_cost_table(xd->bd);
Jingning Han3ee6db62015-08-05 19:00:31 -0700685#else
Alex Converseb3ad8122016-02-10 14:12:26 -0800686 const int *cat6_high_cost = vp10_get_high_cost_table(8);
Jingning Han3ee6db62015-08-05 19:00:31 -0700687#endif
688
Debargha Mukherjee3787b172015-11-19 16:51:16 -0800689#if !CONFIG_VAR_TX && !CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -0700690 // Check for consistency of tx_size with mode info
691 assert(type == PLANE_TYPE_Y ? mbmi->tx_size == tx_size
692 : get_uv_tx_size(mbmi, pd) == tx_size);
Debargha Mukherjee3787b172015-11-19 16:51:16 -0800693#endif // !CONFIG_VAR_TX && !CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -0700694
695 if (eob == 0) {
696 // single eob token
697 cost = token_costs[0][0][pt][EOB_TOKEN];
698 c = 0;
699 } else {
Julia Robsonc6eba0b2016-02-17 15:52:31 +0000700 if (use_fast_coef_costing) {
701 int band_left = *band_count++;
Jingning Han3ee6db62015-08-05 19:00:31 -0700702
Julia Robsonc6eba0b2016-02-17 15:52:31 +0000703 // dc token
704 int v = qcoeff[0];
705 int16_t prev_t;
706 cost = vp10_get_token_cost(v, &prev_t, cat6_high_cost);
707 cost += (*token_costs)[0][pt][prev_t];
Jingning Han3ee6db62015-08-05 19:00:31 -0700708
Julia Robsonc6eba0b2016-02-17 15:52:31 +0000709 token_cache[0] = vp10_pt_energy_class[prev_t];
710 ++token_costs;
Jingning Han3ee6db62015-08-05 19:00:31 -0700711
Julia Robsonc6eba0b2016-02-17 15:52:31 +0000712 // ac tokens
713 for (c = 1; c < eob; c++) {
714 const int rc = scan[c];
715 int16_t t;
Jingning Han3ee6db62015-08-05 19:00:31 -0700716
Julia Robsonc6eba0b2016-02-17 15:52:31 +0000717 v = qcoeff[rc];
718 cost += vp10_get_token_cost(v, &t, cat6_high_cost);
719 cost += (*token_costs)[!prev_t][!prev_t][t];
720 prev_t = t;
721 if (!--band_left) {
722 band_left = *band_count++;
723 ++token_costs;
724 }
Jingning Han3ee6db62015-08-05 19:00:31 -0700725 }
Jingning Han3ee6db62015-08-05 19:00:31 -0700726
Julia Robsonc6eba0b2016-02-17 15:52:31 +0000727 // eob token
728 if (band_left)
Jingning Han3ee6db62015-08-05 19:00:31 -0700729 cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
Julia Robsonc6eba0b2016-02-17 15:52:31 +0000730
731 } else { // !use_fast_coef_costing
732 int band_left = *band_count++;
733
734 // dc token
735 int v = qcoeff[0];
736 int16_t tok;
737 unsigned int (*tok_cost_ptr)[COEFF_CONTEXTS][ENTROPY_TOKENS];
738 cost = vp10_get_token_cost(v, &tok, cat6_high_cost);
739 cost += (*token_costs)[0][pt][tok];
740
741 token_cache[0] = vp10_pt_energy_class[tok];
742 ++token_costs;
743
744 tok_cost_ptr = &((*token_costs)[!tok]);
745
746 // ac tokens
747 for (c = 1; c < eob; c++) {
748 const int rc = scan[c];
749
750 v = qcoeff[rc];
751 cost += vp10_get_token_cost(v, &tok, cat6_high_cost);
752 pt = get_coef_context(nb, token_cache, c);
753 cost += (*tok_cost_ptr)[pt][tok];
754 token_cache[rc] = vp10_pt_energy_class[tok];
755 if (!--band_left) {
756 band_left = *band_count++;
757 ++token_costs;
758 }
759 tok_cost_ptr = &((*token_costs)[!tok]);
760 }
761
762 // eob token
763 if (band_left) {
Jingning Han3ee6db62015-08-05 19:00:31 -0700764 pt = get_coef_context(nb, token_cache, c);
765 cost += (*token_costs)[0][pt][EOB_TOKEN];
766 }
767 }
768 }
769
Jingning Han2cdc1272015-10-09 09:57:42 -0700770#if !CONFIG_VAR_TX
Jingning Han3ee6db62015-08-05 19:00:31 -0700771 // is eob first coefficient;
772 *A = *L = (c > 0);
Jingning Han2cdc1272015-10-09 09:57:42 -0700773#endif
Jingning Han3ee6db62015-08-05 19:00:31 -0700774
775 return cost;
776}
777
Geza Lore3c4b56c2016-02-16 09:54:29 +0000778static void dist_block(const VP10_COMP *cpi, MACROBLOCK *x, int plane,
779 int block, int blk_row, int blk_col, TX_SIZE tx_size,
Jingning Han3ee6db62015-08-05 19:00:31 -0700780 int64_t *out_dist, int64_t *out_sse) {
Geza Lore3c4b56c2016-02-16 09:54:29 +0000781 if (cpi->sf.use_transform_domain_distortion) {
782 // Transform domain distortion computation is more accurate as it does
783 // not involve an inverse transform, but it is less accurate.
784 const int ss_txfrm_size = tx_size << 1;
785 MACROBLOCKD* const xd = &x->e_mbd;
786 const struct macroblock_plane *const p = &x->plane[plane];
787 const struct macroblockd_plane *const pd = &xd->plane[plane];
788 int64_t this_sse;
789 int shift = tx_size == TX_32X32 ? 0 : 2;
790 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
791 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Jingning Han3ee6db62015-08-05 19:00:31 -0700792#if CONFIG_VP9_HIGHBITDEPTH
Geza Lore3c4b56c2016-02-16 09:54:29 +0000793 const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
794 *out_dist = vp10_highbd_block_error(coeff, dqcoeff, 16 << ss_txfrm_size,
795 &this_sse, bd) >> shift;
Jingning Han3ee6db62015-08-05 19:00:31 -0700796#else
Geza Lore3c4b56c2016-02-16 09:54:29 +0000797 *out_dist = vp10_block_error(coeff, dqcoeff, 16 << ss_txfrm_size,
798 &this_sse) >> shift;
Jingning Han3ee6db62015-08-05 19:00:31 -0700799#endif // CONFIG_VP9_HIGHBITDEPTH
Geza Lore3c4b56c2016-02-16 09:54:29 +0000800 *out_sse = this_sse >> shift;
801 } else {
802 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
803 const int bs = 4*num_4x4_blocks_wide_lookup[tx_bsize];
804
805 const MACROBLOCKD *xd = &x->e_mbd;
806 const struct macroblock_plane *p = &x->plane[plane];
807 const struct macroblockd_plane *pd = &xd->plane[plane];
808
809 const int src_stride = x->plane[plane].src.stride;
810 const int dst_stride = xd->plane[plane].dst.stride;
811 const int src_idx = 4 * (blk_row * src_stride + blk_col);
812 const int dst_idx = 4 * (blk_row * dst_stride + blk_col);
813 const uint8_t *src = &x->plane[plane].src.buf[src_idx];
814 const uint8_t *dst = &xd->plane[plane].dst.buf[dst_idx];
815 const tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
816 const uint16_t *eob = &p->eobs[block];
817
818 unsigned int tmp;
819
820 assert(cpi != NULL);
821
822 cpi->fn_ptr[tx_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
823 *out_sse = (int64_t)tmp * 16;
824
825 if (*eob) {
826 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
827#if CONFIG_VP9_HIGHBITDEPTH
828 DECLARE_ALIGNED(16, uint16_t, recon16[32 * 32]); // MAX TX_SIZE**2
829 uint8_t *recon = (uint8_t*)recon16;
830#else
831 DECLARE_ALIGNED(16, uint8_t, recon[32 * 32]); // MAX TX_SIZE**2
832#endif // CONFIG_VP9_HIGHBITDEPTH
833
834 const PLANE_TYPE plane_type = plane == 0 ? PLANE_TYPE_Y : PLANE_TYPE_UV;
835
836 INV_TXFM_PARAM inv_txfm_param;
837
838 inv_txfm_param.tx_type = get_tx_type(plane_type, xd, block, tx_size);
839 inv_txfm_param.tx_size = tx_size;
840 inv_txfm_param.eob = *eob;
841 inv_txfm_param.lossless = xd->lossless[mbmi->segment_id];
842
843#if CONFIG_VP9_HIGHBITDEPTH
844 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
845 recon = CONVERT_TO_BYTEPTR(recon);
846 inv_txfm_param.bd = xd->bd;
847 vpx_highbd_convolve_copy(dst, dst_stride, recon, 32,
848 NULL, 0, NULL, 0, bs, bs, xd->bd);
849 highbd_inv_txfm_add(dqcoeff, recon, 32, &inv_txfm_param);
850 } else
851#endif // CONFIG_VP9_HIGHBITDEPTH
852 {
853 vpx_convolve_copy(dst, dst_stride, recon, 32,
854 NULL, 0, NULL, 0, bs, bs);
855 inv_txfm_add(dqcoeff, recon, 32, &inv_txfm_param);
856 }
857
858 cpi->fn_ptr[tx_bsize].vf(src, src_stride, recon, 32, &tmp);
859 }
860
861 *out_dist = (int64_t)tmp * 16;
862 }
Jingning Han3ee6db62015-08-05 19:00:31 -0700863}
864
Jingning Hanebc48ef2015-10-07 11:43:48 -0700865static int rate_block(int plane, int block, int blk_row, int blk_col,
Jingning Han3ee6db62015-08-05 19:00:31 -0700866 TX_SIZE tx_size, struct rdcost_block_args* args) {
Jingning Han2cdc1272015-10-09 09:57:42 -0700867#if CONFIG_VAR_TX
868 int coeff_ctx = combine_entropy_contexts(*(args->t_above + blk_col),
869 *(args->t_left + blk_row));
870 int coeff_cost = cost_coeffs(args->x, plane, block, coeff_ctx,
871 tx_size, args->so->scan, args->so->neighbors,
872 args->use_fast_coef_costing);
873 const struct macroblock_plane *p = &args->x->plane[plane];
874 *(args->t_above + blk_col) = !(p->eobs[block] == 0);
875 *(args->t_left + blk_row) = !(p->eobs[block] == 0);
876 return coeff_cost;
877#else
878 return cost_coeffs(args->x, plane, block,
879 args->t_above + blk_col,
880 args->t_left + blk_row,
881 tx_size, args->so->scan, args->so->neighbors,
Jingning Han3ee6db62015-08-05 19:00:31 -0700882 args->use_fast_coef_costing);
Geza Lore3c4b56c2016-02-16 09:54:29 +0000883#endif // CONFIG_VAR_TX
Jingning Han3ee6db62015-08-05 19:00:31 -0700884}
885
Jingning Hanebc48ef2015-10-07 11:43:48 -0700886static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
887 BLOCK_SIZE plane_bsize,
Jingning Han3ee6db62015-08-05 19:00:31 -0700888 TX_SIZE tx_size, void *arg) {
889 struct rdcost_block_args *args = arg;
890 MACROBLOCK *const x = args->x;
891 MACROBLOCKD *const xd = &x->e_mbd;
892 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
893 int64_t rd1, rd2, rd;
894 int rate;
895 int64_t dist;
896 int64_t sse;
897
898 if (args->exit_early)
899 return;
900
901 if (!is_inter_block(mbmi)) {
Jingning Han71c15602015-10-13 12:40:39 -0700902 struct encode_b_args arg = {x, NULL, &mbmi->skip};
Jingning Han71c15602015-10-13 12:40:39 -0700903 vp10_encode_block_intra(plane, block, blk_row, blk_col,
904 plane_bsize, tx_size, &arg);
Geza Loreabd00502016-02-12 16:04:35 +0000905
Geza Lore3c4b56c2016-02-16 09:54:29 +0000906 if (args->cpi->sf.use_transform_domain_distortion) {
907 dist_block(args->cpi, x, plane, block, blk_row, blk_col,
908 tx_size, &dist, &sse);
909 } else {
910 // Note that the encode block_intra call above already calls
911 // inv_txfm_add, so we can't just call dist_block here.
Geza Loreabd00502016-02-12 16:04:35 +0000912 const int bs = 4 << tx_size;
913 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
914 const vpx_variance_fn_t variance = args->cpi->fn_ptr[tx_bsize].vf;
915
916 const struct macroblock_plane *const p = &x->plane[plane];
917 const struct macroblockd_plane *const pd = &xd->plane[plane];
918
919 const int src_stride = p->src.stride;
920 const int dst_stride = pd->dst.stride;
921 const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
922
923 const uint8_t *src = &p->src.buf[4 * (blk_row * src_stride + blk_col)];
924 const uint8_t *dst = &pd->dst.buf[4 * (blk_row * dst_stride + blk_col)];
925 const int16_t *diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
926
927 unsigned int tmp;
Geza Lore3c4b56c2016-02-16 09:54:29 +0000928
929 sse = vpx_sum_squares_2d_i16(diff, diff_stride, bs);
Yaowu Xu0c0f3ef2016-02-18 15:42:19 -0800930#if CONFIG_VP9_HIGHBITDEPTH
Debargha Mukherjee389efb22016-02-24 11:25:20 -0800931 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
932 sse = ROUNDZ_POWER_OF_TWO(sse, (xd->bd - 8) * 2);
Geza Lore3c4b56c2016-02-16 09:54:29 +0000933#endif // CONFIG_VP9_HIGHBITDEPTH
934 sse = (int64_t)sse * 16;
935
Geza Loreabd00502016-02-12 16:04:35 +0000936 variance(src, src_stride, dst, dst_stride, &tmp);
937 dist = (int64_t)tmp * 16;
938 }
Jingning Han3ee6db62015-08-05 19:00:31 -0700939 } else if (max_txsize_lookup[plane_bsize] == tx_size) {
940 if (x->skip_txfm[(plane << 2) + (block >> (tx_size << 1))] ==
941 SKIP_TXFM_NONE) {
942 // full forward transform and quantization
Jingning Hancaeb10b2015-10-22 17:25:00 -0700943 vp10_xform_quant(x, plane, block, blk_row, blk_col,
Angie Chiang88cae8b2015-11-25 13:07:13 -0800944 plane_bsize, tx_size, VP10_XFORM_QUANT_B);
Geza Lore3c4b56c2016-02-16 09:54:29 +0000945 dist_block(args->cpi, x, plane, block, blk_row, blk_col,
946 tx_size, &dist, &sse);
Jingning Han3ee6db62015-08-05 19:00:31 -0700947 } else if (x->skip_txfm[(plane << 2) + (block >> (tx_size << 1))] ==
948 SKIP_TXFM_AC_ONLY) {
949 // compute DC coefficient
950 tran_low_t *const coeff = BLOCK_OFFSET(x->plane[plane].coeff, block);
951 tran_low_t *const dqcoeff = BLOCK_OFFSET(xd->plane[plane].dqcoeff, block);
Angie Chiang88cae8b2015-11-25 13:07:13 -0800952 vp10_xform_quant(x, plane, block, blk_row, blk_col,
953 plane_bsize, tx_size, VP10_XFORM_QUANT_DC);
Jingning Han3ee6db62015-08-05 19:00:31 -0700954 sse = x->bsse[(plane << 2) + (block >> (tx_size << 1))] << 4;
955 dist = sse;
956 if (x->plane[plane].eobs[block]) {
957 const int64_t orig_sse = (int64_t)coeff[0] * coeff[0];
958 const int64_t resd_sse = coeff[0] - dqcoeff[0];
959 int64_t dc_correct = orig_sse - resd_sse * resd_sse;
960#if CONFIG_VP9_HIGHBITDEPTH
961 dc_correct >>= ((xd->bd - 8) * 2);
962#endif
963 if (tx_size != TX_32X32)
964 dc_correct >>= 2;
965
James Zern5e16d392015-08-17 18:19:22 -0700966 dist = VPXMAX(0, sse - dc_correct);
Jingning Han3ee6db62015-08-05 19:00:31 -0700967 }
968 } else {
969 // SKIP_TXFM_AC_DC
970 // skip forward transform
971 x->plane[plane].eobs[block] = 0;
972 sse = x->bsse[(plane << 2) + (block >> (tx_size << 1))] << 4;
973 dist = sse;
974 }
975 } else {
976 // full forward transform and quantization
Angie Chiang88cae8b2015-11-25 13:07:13 -0800977 vp10_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
978 VP10_XFORM_QUANT_B);
Geza Lore3c4b56c2016-02-16 09:54:29 +0000979 dist_block(args->cpi, x, plane, block, blk_row, blk_col,
980 tx_size, &dist, &sse);
Jingning Han3ee6db62015-08-05 19:00:31 -0700981 }
982
983 rd = RDCOST(x->rdmult, x->rddiv, 0, dist);
984 if (args->this_rd + rd > args->best_rd) {
985 args->exit_early = 1;
986 return;
987 }
988
Jingning Hanebc48ef2015-10-07 11:43:48 -0700989 rate = rate_block(plane, block, blk_row, blk_col, tx_size, args);
Jingning Han3ee6db62015-08-05 19:00:31 -0700990 rd1 = RDCOST(x->rdmult, x->rddiv, rate, dist);
991 rd2 = RDCOST(x->rdmult, x->rddiv, 0, sse);
992
993 // TODO(jingning): temporarily enabled only for luma component
James Zern5e16d392015-08-17 18:19:22 -0700994 rd = VPXMIN(rd1, rd2);
Jingning Han3ee6db62015-08-05 19:00:31 -0700995 if (plane == 0)
996 x->zcoeff_blk[tx_size][block] = !x->plane[plane].eobs[block] ||
Ronald S. Bultje60c58b52015-10-12 17:54:25 -0400997 (rd1 > rd2 && !xd->lossless[mbmi->segment_id]);
Jingning Han3ee6db62015-08-05 19:00:31 -0700998
999 args->this_rate += rate;
1000 args->this_dist += dist;
1001 args->this_sse += sse;
1002 args->this_rd += rd;
1003
1004 if (args->this_rd > args->best_rd) {
1005 args->exit_early = 1;
1006 return;
1007 }
1008
1009 args->skippable &= !x->plane[plane].eobs[block];
1010}
1011
1012static void txfm_rd_in_plane(MACROBLOCK *x,
Jingning Han71c15602015-10-13 12:40:39 -07001013 const VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07001014 int *rate, int64_t *distortion,
1015 int *skippable, int64_t *sse,
1016 int64_t ref_best_rd, int plane,
1017 BLOCK_SIZE bsize, TX_SIZE tx_size,
1018 int use_fast_coef_casting) {
1019 MACROBLOCKD *const xd = &x->e_mbd;
1020 const struct macroblockd_plane *const pd = &xd->plane[plane];
hui su5eed74e2015-08-18 16:57:07 -07001021 TX_TYPE tx_type;
Jingning Han3ee6db62015-08-05 19:00:31 -07001022 struct rdcost_block_args args;
1023 vp10_zero(args);
1024 args.x = x;
Jingning Han71c15602015-10-13 12:40:39 -07001025 args.cpi = cpi;
Jingning Han3ee6db62015-08-05 19:00:31 -07001026 args.best_rd = ref_best_rd;
1027 args.use_fast_coef_costing = use_fast_coef_casting;
1028 args.skippable = 1;
1029
1030 if (plane == 0)
1031 xd->mi[0]->mbmi.tx_size = tx_size;
1032
1033 vp10_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
1034
hui sub3cc3a02015-08-24 14:37:54 -07001035 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001036 args.so = get_scan(tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Jingning Han3ee6db62015-08-05 19:00:31 -07001037
1038 vp10_foreach_transformed_block_in_plane(xd, bsize, plane,
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001039 block_rd_txfm, &args);
Jingning Han3ee6db62015-08-05 19:00:31 -07001040 if (args.exit_early) {
1041 *rate = INT_MAX;
1042 *distortion = INT64_MAX;
1043 *sse = INT64_MAX;
1044 *skippable = 0;
1045 } else {
1046 *distortion = args.this_dist;
1047 *rate = args.this_rate;
1048 *sse = args.this_sse;
1049 *skippable = args.skippable;
1050 }
1051}
1052
Debargha Mukherjee3787b172015-11-19 16:51:16 -08001053#if CONFIG_SUPERTX
1054void vp10_txfm_rd_in_plane_supertx(MACROBLOCK *x,
Geza Lore3c4b56c2016-02-16 09:54:29 +00001055 const VP10_COMP *cpi,
Debargha Mukherjee3787b172015-11-19 16:51:16 -08001056 int *rate, int64_t *distortion,
1057 int *skippable, int64_t *sse,
1058 int64_t ref_best_rd, int plane,
1059 BLOCK_SIZE bsize, TX_SIZE tx_size,
1060 int use_fast_coef_casting) {
1061 MACROBLOCKD *const xd = &x->e_mbd;
1062 const struct macroblockd_plane *const pd = &xd->plane[plane];
1063 struct rdcost_block_args args;
1064 TX_TYPE tx_type;
1065
1066 vp10_zero(args);
Geza Lore3c4b56c2016-02-16 09:54:29 +00001067 args.cpi = cpi;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08001068 args.x = x;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08001069 args.best_rd = ref_best_rd;
1070 args.use_fast_coef_costing = use_fast_coef_casting;
1071
1072 if (plane == 0)
1073 xd->mi[0]->mbmi.tx_size = tx_size;
1074
1075 vp10_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
1076
1077 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
1078 args.so = get_scan(tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
1079
1080 block_rd_txfm(plane, 0, 0, 0, get_plane_block_size(bsize, pd),
1081 tx_size, &args);
1082
1083 if (args.exit_early) {
1084 *rate = INT_MAX;
1085 *distortion = INT64_MAX;
1086 *sse = INT64_MAX;
1087 *skippable = 0;
1088 } else {
1089 *distortion = args.this_dist;
1090 *rate = args.this_rate;
1091 *sse = args.this_sse;
1092 *skippable = !x->plane[plane].eobs[0];
1093 }
1094}
1095#endif // CONFIG_SUPERTX
1096
Yaowu Xu26a9afc2015-08-13 09:42:27 -07001097static void choose_largest_tx_size(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07001098 int *rate, int64_t *distortion,
1099 int *skip, int64_t *sse,
1100 int64_t ref_best_rd,
1101 BLOCK_SIZE bs) {
1102 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
Yaowu Xufc7cbd12015-08-13 09:36:53 -07001103 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07001104 const TX_SIZE largest_tx_size = tx_mode_to_biggest_tx_size[cm->tx_mode];
1105 MACROBLOCKD *const xd = &x->e_mbd;
1106 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001107 TX_TYPE tx_type, best_tx_type = DCT_DCT;
hui su6c81e372015-09-29 12:09:15 -07001108 int r, s;
1109 int64_t d, psse, this_rd, best_rd = INT64_MAX;
1110 vpx_prob skip_prob = vp10_get_skip_prob(cm, xd);
1111 int s0 = vp10_cost_bit(skip_prob, 0);
1112 int s1 = vp10_cost_bit(skip_prob, 1);
Sarah Parker2ca7d422016-03-01 10:12:13 -08001113 const int is_inter = is_inter_block(mbmi);
1114 int prune = 0;
Yaowu Xu0367f322016-01-11 10:27:35 -08001115#if CONFIG_EXT_TX
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001116 int ext_tx_set;
hui su6c81e372015-09-29 12:09:15 -07001117#endif // CONFIG_EXT_TX
Jingning Han3ee6db62015-08-05 19:00:31 -07001118
Sarah Parker2ca7d422016-03-01 10:12:13 -08001119 if (is_inter && cpi->sf.tx_type_search > 0)
1120 prune = prune_tx_types(cpi, bs, x, xd);
James Zern5e16d392015-08-17 18:19:22 -07001121 mbmi->tx_size = VPXMIN(max_tx_size, largest_tx_size);
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001122
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001123#if CONFIG_EXT_TX
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001124 ext_tx_set = get_ext_tx_set(mbmi->tx_size, bs, is_inter);
1125
Debargha Mukherjee8d69a6e2016-01-06 14:36:13 -08001126 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1 &&
Yaowu Xu5a27b3b2015-10-22 12:18:52 -07001127 !xd->lossless[mbmi->segment_id]) {
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001128 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
1129 if (is_inter) {
1130 if (!ext_tx_used_inter[ext_tx_set][tx_type])
1131 continue;
Sarah Parker2ca7d422016-03-01 10:12:13 -08001132 if (cpi->sf.tx_type_search > 0) {
1133 if (!do_tx_type_search(tx_type, prune))
1134 continue;
1135 } else if (ext_tx_set == 1 &&
1136 tx_type >= DST_ADST && tx_type < IDTX &&
1137 best_tx_type == DCT_DCT) {
1138 tx_type = IDTX - 1;
1139 continue;
1140 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001141 } else {
hui sud894d342015-11-18 11:24:26 -08001142 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
Yaowu Xu0367f322016-01-11 10:27:35 -08001143 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode])
hui sud894d342015-11-18 11:24:26 -08001144 continue;
1145 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001146 if (!ext_tx_used_intra[ext_tx_set][tx_type])
1147 continue;
Sarah Parker2ca7d422016-03-01 10:12:13 -08001148 if (ext_tx_set == 1 &&
1149 tx_type >= DST_ADST && tx_type < IDTX &&
1150 best_tx_type == DCT_DCT) {
1151 tx_type = IDTX - 1;
1152 continue;
1153 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001154 }
1155
1156 mbmi->tx_type = tx_type;
hui su6c81e372015-09-29 12:09:15 -07001157
Jingning Han71c15602015-10-13 12:40:39 -07001158 txfm_rd_in_plane(x,
Jingning Han71c15602015-10-13 12:40:39 -07001159 cpi,
Jingning Han71c15602015-10-13 12:40:39 -07001160 &r, &d, &s,
hui su6c81e372015-09-29 12:09:15 -07001161 &psse, ref_best_rd, 0, bs, mbmi->tx_size,
1162 cpi->sf.use_fast_coef_costing);
1163
1164 if (r == INT_MAX)
1165 continue;
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001166 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1) {
1167 if (is_inter) {
1168 if (ext_tx_set > 0)
1169 r += cpi->inter_tx_type_costs[ext_tx_set]
1170 [mbmi->tx_size][mbmi->tx_type];
1171 } else {
hui sud894d342015-11-18 11:24:26 -08001172 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001173 r += cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size]
1174 [mbmi->mode][mbmi->tx_type];
1175 }
hui su3fa01292015-09-28 18:38:00 -07001176 }
hui su6c81e372015-09-29 12:09:15 -07001177
1178 if (s)
1179 this_rd = RDCOST(x->rdmult, x->rddiv, s1, psse);
1180 else
1181 this_rd = RDCOST(x->rdmult, x->rddiv, r + s0, d);
Yaowu Xu5a27b3b2015-10-22 12:18:52 -07001182 if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] && !s)
hui su6c81e372015-09-29 12:09:15 -07001183 this_rd = VPXMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, psse));
1184
hui su4f16f112015-10-02 10:45:27 -07001185 if (this_rd < ((best_tx_type == DCT_DCT) ? ext_tx_th : 1) * best_rd) {
hui su6c81e372015-09-29 12:09:15 -07001186 best_rd = this_rd;
hui su4f16f112015-10-02 10:45:27 -07001187 best_tx_type = mbmi->tx_type;
hui su6c81e372015-09-29 12:09:15 -07001188 }
1189 }
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001190 }
hui su6c81e372015-09-29 12:09:15 -07001191
Yaowu Xu0367f322016-01-11 10:27:35 -08001192#else // CONFIG_EXT_TX
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001193 if (mbmi->tx_size < TX_32X32 &&
1194 !xd->lossless[mbmi->segment_id]) {
1195 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
1196 mbmi->tx_type = tx_type;
Yaowu Xu0367f322016-01-11 10:27:35 -08001197 txfm_rd_in_plane(x,
Yaowu Xu0367f322016-01-11 10:27:35 -08001198 cpi,
Yaowu Xu0367f322016-01-11 10:27:35 -08001199 &r, &d, &s,
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001200 &psse, ref_best_rd, 0, bs, mbmi->tx_size,
1201 cpi->sf.use_fast_coef_costing);
1202 if (r == INT_MAX)
1203 continue;
Sarah Parker2ca7d422016-03-01 10:12:13 -08001204 if (is_inter) {
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001205 r += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Sarah Parker2ca7d422016-03-01 10:12:13 -08001206 if (cpi->sf.tx_type_search > 0 && !do_tx_type_search(tx_type, prune))
1207 continue;
1208 } else {
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001209 r += cpi->intra_tx_type_costs[mbmi->tx_size]
1210 [intra_mode_to_tx_type_context[mbmi->mode]]
1211 [mbmi->tx_type];
Sarah Parker2ca7d422016-03-01 10:12:13 -08001212 }
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001213 if (s)
1214 this_rd = RDCOST(x->rdmult, x->rddiv, s1, psse);
1215 else
1216 this_rd = RDCOST(x->rdmult, x->rddiv, r + s0, d);
1217 if (is_inter && !xd->lossless[mbmi->segment_id] && !s)
1218 this_rd = VPXMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, psse));
1219
1220 if (this_rd < ((best_tx_type == DCT_DCT) ? ext_tx_th : 1) * best_rd) {
1221 best_rd = this_rd;
1222 best_tx_type = mbmi->tx_type;
1223 }
1224 }
1225 }
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001226#endif // CONFIG_EXT_TX
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001227 mbmi->tx_type = best_tx_type;
Jingning Han3ee6db62015-08-05 19:00:31 -07001228
Jingning Han71c15602015-10-13 12:40:39 -07001229 txfm_rd_in_plane(x,
Jingning Han71c15602015-10-13 12:40:39 -07001230 cpi,
Jingning Han71c15602015-10-13 12:40:39 -07001231 rate, distortion, skip,
Jingning Han3ee6db62015-08-05 19:00:31 -07001232 sse, ref_best_rd, 0, bs,
1233 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
1234}
1235
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001236static void choose_smallest_tx_size(VP10_COMP *cpi, MACROBLOCK *x,
1237 int *rate, int64_t *distortion,
1238 int *skip, int64_t *sse,
1239 int64_t ref_best_rd,
1240 BLOCK_SIZE bs) {
1241 MACROBLOCKD *const xd = &x->e_mbd;
1242 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1243
1244 mbmi->tx_size = TX_4X4;
Debargha Mukherjee4e406f72016-01-22 03:29:39 -08001245 mbmi->tx_type = DCT_DCT;
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001246
Jingning Han71c15602015-10-13 12:40:39 -07001247 txfm_rd_in_plane(x,
Jingning Han71c15602015-10-13 12:40:39 -07001248 cpi,
Jingning Han71c15602015-10-13 12:40:39 -07001249 rate, distortion, skip,
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001250 sse, ref_best_rd, 0, bs,
1251 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
1252}
1253
Yaowu Xu26a9afc2015-08-13 09:42:27 -07001254static void choose_tx_size_from_rd(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07001255 int *rate,
1256 int64_t *distortion,
1257 int *skip,
1258 int64_t *psse,
1259 int64_t ref_best_rd,
1260 BLOCK_SIZE bs) {
1261 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
Yaowu Xufc7cbd12015-08-13 09:36:53 -07001262 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07001263 MACROBLOCKD *const xd = &x->e_mbd;
1264 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1265 vpx_prob skip_prob = vp10_get_skip_prob(cm, xd);
hui su38debe52015-09-20 19:18:00 -07001266 int r, s;
1267 int64_t d, sse;
1268 int64_t rd = INT64_MAX;
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08001269 int n;
Jingning Han3ee6db62015-08-05 19:00:31 -07001270 int s0, s1;
hui su38debe52015-09-20 19:18:00 -07001271 int64_t best_rd = INT64_MAX, last_rd = INT64_MAX;
Jingning Han3ee6db62015-08-05 19:00:31 -07001272 TX_SIZE best_tx = max_tx_size;
1273 int start_tx, end_tx;
hui su38debe52015-09-20 19:18:00 -07001274 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001275 const int is_inter = is_inter_block(mbmi);
Sarah Parker2ca7d422016-03-01 10:12:13 -08001276 TX_TYPE tx_type, best_tx_type = DCT_DCT;
1277 int prune = 0;
Yaowu Xu0367f322016-01-11 10:27:35 -08001278#if CONFIG_EXT_TX
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001279 int ext_tx_set;
hui su07154b02015-09-22 10:34:18 -07001280#endif // CONFIG_EXT_TX
1281
Sarah Parker2ca7d422016-03-01 10:12:13 -08001282 if (is_inter && cpi->sf.tx_type_search > 0)
1283 prune = prune_tx_types(cpi, bs, x, xd);
1284
Jingning Han3ee6db62015-08-05 19:00:31 -07001285 assert(skip_prob > 0);
1286 s0 = vp10_cost_bit(skip_prob, 0);
1287 s1 = vp10_cost_bit(skip_prob, 1);
1288
hui su38debe52015-09-20 19:18:00 -07001289 if (tx_select) {
Jingning Han3ee6db62015-08-05 19:00:31 -07001290 start_tx = max_tx_size;
1291 end_tx = 0;
1292 } else {
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001293 const TX_SIZE chosen_tx_size =
1294 VPXMIN(max_tx_size, tx_mode_to_biggest_tx_size[cm->tx_mode]);
Jingning Han3ee6db62015-08-05 19:00:31 -07001295 start_tx = chosen_tx_size;
1296 end_tx = chosen_tx_size;
1297 }
1298
hui su38debe52015-09-20 19:18:00 -07001299 *distortion = INT64_MAX;
1300 *rate = INT_MAX;
1301 *skip = 0;
1302 *psse = INT64_MAX;
1303
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001304 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001305 last_rd = INT64_MAX;
hui su07154b02015-09-22 10:34:18 -07001306 for (n = start_tx; n >= end_tx; --n) {
hui su954e5602016-03-07 15:25:50 -08001307 const int r_tx_size =
1308 cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)][n];
hui su329e3402016-02-10 10:52:14 -08001309 if (FIXED_TX_TYPE && tx_type != get_default_tx_type(0, xd, 0, n))
1310 continue;
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001311#if CONFIG_EXT_TX
1312 ext_tx_set = get_ext_tx_set(n, bs, is_inter);
1313 if (is_inter) {
1314 if (!ext_tx_used_inter[ext_tx_set][tx_type])
1315 continue;
Sarah Parker2ca7d422016-03-01 10:12:13 -08001316 if (cpi->sf.tx_type_search > 0) {
1317 if (!do_tx_type_search(tx_type, prune))
1318 continue;
1319 } else if (ext_tx_set == 1 &&
1320 tx_type >= DST_ADST && tx_type < IDTX &&
1321 best_tx_type == DCT_DCT) {
1322 tx_type = IDTX - 1;
1323 continue;
1324 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001325 } else {
hui sud894d342015-11-18 11:24:26 -08001326 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
Yaowu Xu0367f322016-01-11 10:27:35 -08001327 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode])
hui sud894d342015-11-18 11:24:26 -08001328 continue;
1329 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001330 if (!ext_tx_used_intra[ext_tx_set][tx_type])
1331 continue;
Sarah Parker2ca7d422016-03-01 10:12:13 -08001332 if (ext_tx_set == 1 &&
1333 tx_type >= DST_ADST && tx_type < IDTX &&
1334 best_tx_type == DCT_DCT) {
1335 tx_type = IDTX - 1;
1336 break;
1337 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001338 }
1339 mbmi->tx_type = tx_type;
Jingning Han71c15602015-10-13 12:40:39 -07001340 txfm_rd_in_plane(x,
Jingning Han71c15602015-10-13 12:40:39 -07001341 cpi,
Jingning Han71c15602015-10-13 12:40:39 -07001342 &r, &d, &s,
hui su07154b02015-09-22 10:34:18 -07001343 &sse, ref_best_rd, 0, bs, n,
1344 cpi->sf.use_fast_coef_costing);
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001345 if (get_ext_tx_types(n, bs, is_inter) > 1 &&
1346 !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1347 r != INT_MAX) {
1348 if (is_inter) {
1349 if (ext_tx_set > 0)
1350 r += cpi->inter_tx_type_costs[ext_tx_set]
1351 [mbmi->tx_size][mbmi->tx_type];
1352 } else {
hui sud894d342015-11-18 11:24:26 -08001353 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001354 r += cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size]
1355 [mbmi->mode][mbmi->tx_type];
1356 }
hui su3fa01292015-09-28 18:38:00 -07001357 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001358#else // CONFIG_EXT_TX
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001359 if (n >= TX_32X32 && tx_type != DCT_DCT) {
1360 continue;
1361 }
1362 mbmi->tx_type = tx_type;
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001363 txfm_rd_in_plane(x,
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001364 cpi,
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001365 &r, &d, &s,
1366 &sse, ref_best_rd, 0, bs, n,
1367 cpi->sf.use_fast_coef_costing);
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001368 if (n < TX_32X32 &&
1369 !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
hui su329e3402016-02-10 10:52:14 -08001370 r != INT_MAX && !FIXED_TX_TYPE) {
Sarah Parker2ca7d422016-03-01 10:12:13 -08001371 if (is_inter) {
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001372 r += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Sarah Parker2ca7d422016-03-01 10:12:13 -08001373 if (cpi->sf.tx_type_search > 0 && !do_tx_type_search(tx_type, prune))
1374 continue;
1375 } else {
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001376 r += cpi->intra_tx_type_costs[mbmi->tx_size]
1377 [intra_mode_to_tx_type_context[mbmi->mode]]
1378 [mbmi->tx_type];
Sarah Parker2ca7d422016-03-01 10:12:13 -08001379 }
Debargha Mukherjeef7dfa4e2016-01-06 11:24:57 -08001380 }
hui su07154b02015-09-22 10:34:18 -07001381#endif // CONFIG_EXT_TX
1382
1383 if (r == INT_MAX)
1384 continue;
1385
hui su07154b02015-09-22 10:34:18 -07001386 if (s) {
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001387 if (is_inter) {
hui su07154b02015-09-22 10:34:18 -07001388 rd = RDCOST(x->rdmult, x->rddiv, s1, sse);
hui su07154b02015-09-22 10:34:18 -07001389 } else {
1390 rd = RDCOST(x->rdmult, x->rddiv, s1 + r_tx_size * tx_select, sse);
1391 }
1392 } else {
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001393 rd = RDCOST(x->rdmult, x->rddiv, r + s0 + r_tx_size * tx_select, d);
hui su07154b02015-09-22 10:34:18 -07001394 }
1395
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001396 if (tx_select && !(s && is_inter))
1397 r += r_tx_size;
1398
1399 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] && !s)
hui su07154b02015-09-22 10:34:18 -07001400 rd = VPXMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, sse));
1401
1402 // Early termination in transform size search.
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001403 if (cpi->sf.tx_size_search_breakout &&
1404 (rd == INT64_MAX ||
Jingning Han35b3bd32015-11-10 16:02:33 -08001405 (s == 1 && tx_type != DCT_DCT && n < start_tx) ||
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001406 (n < (int) max_tx_size && rd > last_rd)))
hui su07154b02015-09-22 10:34:18 -07001407 break;
1408
1409 last_rd = rd;
hui su4f16f112015-10-02 10:45:27 -07001410 if (rd <
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001411 (is_inter && best_tx_type == DCT_DCT ? ext_tx_th : 1) *
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001412 best_rd) {
hui su07154b02015-09-22 10:34:18 -07001413 best_tx = n;
1414 best_rd = rd;
1415 *distortion = d;
1416 *rate = r;
1417 *skip = s;
1418 *psse = sse;
hui su4f16f112015-10-02 10:45:27 -07001419 best_tx_type = mbmi->tx_type;
hui su07154b02015-09-22 10:34:18 -07001420 }
Jingning Han3ee6db62015-08-05 19:00:31 -07001421 }
Jingning Han3ee6db62015-08-05 19:00:31 -07001422 }
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001423
Jingning Han3ee6db62015-08-05 19:00:31 -07001424 mbmi->tx_size = best_tx;
hui su4f16f112015-10-02 10:45:27 -07001425 mbmi->tx_type = best_tx_type;
Julia Robson9fe188e2016-01-21 17:14:29 +00001426 if (mbmi->tx_size >= TX_32X32)
1427 assert(mbmi->tx_type == DCT_DCT);
Jingning Han71c15602015-10-13 12:40:39 -07001428 txfm_rd_in_plane(x,
Jingning Han71c15602015-10-13 12:40:39 -07001429 cpi,
Jingning Han71c15602015-10-13 12:40:39 -07001430 &r, &d, &s,
hui su07154b02015-09-22 10:34:18 -07001431 &sse, ref_best_rd, 0, bs, best_tx,
1432 cpi->sf.use_fast_coef_costing);
Jingning Han3ee6db62015-08-05 19:00:31 -07001433}
1434
Yaowu Xu26a9afc2015-08-13 09:42:27 -07001435static void super_block_yrd(VP10_COMP *cpi, MACROBLOCK *x, int *rate,
Jingning Han3ee6db62015-08-05 19:00:31 -07001436 int64_t *distortion, int *skip,
1437 int64_t *psse, BLOCK_SIZE bs,
1438 int64_t ref_best_rd) {
1439 MACROBLOCKD *xd = &x->e_mbd;
1440 int64_t sse;
1441 int64_t *ret_sse = psse ? psse : &sse;
1442
1443 assert(bs == xd->mi[0]->mbmi.sb_type);
1444
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08001445 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001446 choose_smallest_tx_size(cpi, x, rate, distortion, skip, ret_sse,
1447 ref_best_rd, bs);
hui su66f2f652015-11-16 16:58:15 -08001448 } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
Jingning Han3ee6db62015-08-05 19:00:31 -07001449 choose_largest_tx_size(cpi, x, rate, distortion, skip, ret_sse, ref_best_rd,
1450 bs);
1451 } else {
1452 choose_tx_size_from_rd(cpi, x, rate, distortion, skip, ret_sse,
1453 ref_best_rd, bs);
1454 }
1455}
1456
1457static int conditional_skipintra(PREDICTION_MODE mode,
1458 PREDICTION_MODE best_intra_mode) {
1459 if (mode == D117_PRED &&
1460 best_intra_mode != V_PRED &&
1461 best_intra_mode != D135_PRED)
1462 return 1;
1463 if (mode == D63_PRED &&
1464 best_intra_mode != V_PRED &&
1465 best_intra_mode != D45_PRED)
1466 return 1;
1467 if (mode == D207_PRED &&
1468 best_intra_mode != H_PRED &&
1469 best_intra_mode != D45_PRED)
1470 return 1;
1471 if (mode == D153_PRED &&
1472 best_intra_mode != H_PRED &&
1473 best_intra_mode != D135_PRED)
1474 return 1;
1475 return 0;
1476}
1477
hui suc93e5cc2015-12-07 18:18:57 -08001478void rd_pick_palette_intra_sby(VP10_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
1479 int palette_ctx, int dc_mode_cost,
1480 PALETTE_MODE_INFO *palette_mode_info,
1481 uint8_t *best_palette_color_map,
1482 TX_SIZE *best_tx, PREDICTION_MODE *mode_selected,
1483 int64_t *best_rd) {
1484 MACROBLOCKD *const xd = &x->e_mbd;
1485 MODE_INFO *const mic = xd->mi[0];
1486 int rows = 4 * num_4x4_blocks_high_lookup[bsize];
1487 int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
1488 int this_rate, this_rate_tokenonly, s;
1489 int64_t this_distortion, this_rd;
1490 int colors, n;
1491 int src_stride = x->plane[0].src.stride;
1492 uint8_t *src = x->plane[0].src.buf;
1493
1494#if CONFIG_VP9_HIGHBITDEPTH
1495 if (cpi->common.use_highbitdepth)
1496 colors = vp10_count_colors_highbd(src, src_stride, rows, cols,
1497 cpi->common.bit_depth);
1498 else
1499#endif // CONFIG_VP9_HIGHBITDEPTH
1500 colors = vp10_count_colors(src, src_stride, rows, cols);
1501 palette_mode_info->palette_size[0] = 0;
1502
1503 if (colors > 1 && colors <= 64 && cpi->common.allow_screen_content_tools) {
1504 int r, c, i, j, k;
1505 int max_itr = 50;
1506 int color_ctx, color_idx = 0;
1507 int color_order[PALETTE_MAX_SIZE];
1508 double *data = x->palette_buffer->kmeans_data_buf;
1509 uint8_t *indices = x->palette_buffer->kmeans_indices_buf;
1510 uint8_t *pre_indices = x->palette_buffer->kmeans_pre_indices_buf;
1511 double centroids[PALETTE_MAX_SIZE];
1512 uint8_t *color_map;
1513 double lb, ub, val;
1514 PALETTE_MODE_INFO *pmi = &mic->mbmi.palette_mode_info;
1515#if CONFIG_VP9_HIGHBITDEPTH
1516 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
1517 if (cpi->common.use_highbitdepth)
1518 lb = ub = src16[0];
1519 else
1520#endif // CONFIG_VP9_HIGHBITDEPTH
1521 lb = ub = src[0];
1522
1523#if CONFIG_VP9_HIGHBITDEPTH
1524 if (cpi->common.use_highbitdepth) {
1525 for (r = 0; r < rows; ++r) {
1526 for (c = 0; c < cols; ++c) {
1527 val = src16[r * src_stride + c];
1528 data[r * cols + c] = val;
1529 if (val < lb)
1530 lb = val;
1531 else if (val > ub)
1532 ub = val;
1533 }
1534 }
1535 } else {
1536#endif // CONFIG_VP9_HIGHBITDEPTH
1537 for (r = 0; r < rows; ++r) {
1538 for (c = 0; c < cols; ++c) {
1539 val = src[r * src_stride + c];
1540 data[r * cols + c] = val;
1541 if (val < lb)
1542 lb = val;
1543 else if (val > ub)
1544 ub = val;
1545 }
1546 }
1547#if CONFIG_VP9_HIGHBITDEPTH
1548 }
1549#endif // CONFIG_VP9_HIGHBITDEPTH
1550
1551 mic->mbmi.mode = DC_PRED;
1552
1553 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors;
1554 n >= 2; --n) {
1555 for (i = 0; i < n; ++i)
1556 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
1557 vp10_k_means(data, centroids, indices, pre_indices, rows * cols,
1558 n, 1, max_itr);
1559 vp10_insertion_sort(centroids, n);
1560 for (i = 0; i < n; ++i)
1561 centroids[i] = round(centroids[i]);
1562 // remove duplicates
1563 i = 1;
1564 k = n;
1565 while (i < k) {
1566 if (centroids[i] == centroids[i - 1]) {
1567 j = i;
1568 while (j < k - 1) {
1569 centroids[j] = centroids[j + 1];
1570 ++j;
1571 }
1572 --k;
1573 } else {
1574 ++i;
1575 }
1576 }
1577
1578#if CONFIG_VP9_HIGHBITDEPTH
1579 if (cpi->common.use_highbitdepth)
1580 for (i = 0; i < k; ++i)
Yaowu Xu3c28b4a2016-02-08 09:41:43 -08001581 pmi->palette_colors[i] = clip_pixel_highbd((int)round(centroids[i]),
1582 cpi->common.bit_depth);
hui suc93e5cc2015-12-07 18:18:57 -08001583 else
1584#endif // CONFIG_VP9_HIGHBITDEPTH
1585 for (i = 0; i < k; ++i)
1586 pmi->palette_colors[i] = clip_pixel((int)round(centroids[i]));
1587 pmi->palette_size[0] = k;
1588
1589 vp10_calc_indices(data, centroids, indices, rows * cols, k, 1);
1590 for (r = 0; r < rows; ++r)
1591 for (c = 0; c < cols; ++c)
1592 xd->plane[0].color_index_map[r * cols + c] = indices[r * cols + c];
1593
1594 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
1595 &s, NULL, bsize, *best_rd);
1596 if (this_rate_tokenonly == INT_MAX)
1597 continue;
1598
1599 this_rate = this_rate_tokenonly + dc_mode_cost +
1600 cpi->common.bit_depth * k * vp10_cost_bit(128, 0) +
1601 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - 2];
1602 this_rate +=
1603 vp10_cost_bit(vp10_default_palette_y_mode_prob[bsize - BLOCK_8X8]
1604 [palette_ctx], 1);
1605 color_map = xd->plane[0].color_index_map;
1606 this_rate += write_uniform_cost(k, xd->plane[0].color_index_map[0]);
1607 for (i = 0; i < rows; ++i) {
1608 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
1609 color_ctx = vp10_get_palette_color_context(color_map, cols, i, j,
1610 k, color_order);
1611 for (r = 0; r < k; ++r)
1612 if (color_map[i * cols + j] == color_order[r]) {
1613 color_idx = r;
1614 break;
1615 }
1616 assert(color_idx < k);
1617 this_rate +=
1618 cpi->palette_y_color_cost[k - 2][color_ctx][color_idx];
1619 }
1620 }
1621 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
1622
1623 if (this_rd < *best_rd) {
1624 *best_rd = this_rd;
1625 *palette_mode_info = mic->mbmi.palette_mode_info;
1626 memcpy(best_palette_color_map, xd->plane[0].color_index_map,
1627 rows * cols * sizeof(xd->plane[0].color_index_map[0]));
1628 *mode_selected = DC_PRED;
1629 *best_tx = mic->mbmi.tx_size;
1630 }
1631 }
1632 }
1633}
1634
Yaowu Xu26a9afc2015-08-13 09:42:27 -07001635static int64_t rd_pick_intra4x4block(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07001636 int row, int col,
1637 PREDICTION_MODE *best_mode,
1638 const int *bmode_costs,
1639 ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
1640 int *bestrate, int *bestratey,
1641 int64_t *bestdistortion,
1642 BLOCK_SIZE bsize, int64_t rd_thresh) {
1643 PREDICTION_MODE mode;
1644 MACROBLOCKD *const xd = &x->e_mbd;
1645 int64_t best_rd = rd_thresh;
1646 struct macroblock_plane *p = &x->plane[0];
1647 struct macroblockd_plane *pd = &xd->plane[0];
1648 const int src_stride = p->src.stride;
1649 const int dst_stride = pd->dst.stride;
1650 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
1651 uint8_t *dst_init = &pd->dst.buf[row * 4 * src_stride + col * 4];
1652 ENTROPY_CONTEXT ta[2], tempa[2];
1653 ENTROPY_CONTEXT tl[2], templ[2];
1654 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1655 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1656 int idx, idy;
1657 uint8_t best_dst[8 * 8];
1658#if CONFIG_VP9_HIGHBITDEPTH
1659 uint16_t best_dst16[8 * 8];
1660#endif
1661
1662 memcpy(ta, a, sizeof(ta));
1663 memcpy(tl, l, sizeof(tl));
1664 xd->mi[0]->mbmi.tx_size = TX_4X4;
hui suc93e5cc2015-12-07 18:18:57 -08001665 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07001666
1667#if CONFIG_VP9_HIGHBITDEPTH
1668 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1669 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
1670 int64_t this_rd;
1671 int ratey = 0;
1672 int64_t distortion = 0;
1673 int rate = bmode_costs[mode];
1674
1675 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode)))
1676 continue;
1677
1678 // Only do the oblique modes if the best so far is
1679 // one of the neighboring directional modes
1680 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
1681 if (conditional_skipintra(mode, *best_mode))
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001682 continue;
Jingning Han3ee6db62015-08-05 19:00:31 -07001683 }
1684
1685 memcpy(tempa, ta, sizeof(ta));
1686 memcpy(templ, tl, sizeof(tl));
1687
1688 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
1689 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
1690 const int block = (row + idy) * 2 + (col + idx);
1691 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
1692 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
1693 int16_t *const src_diff = vp10_raster_block_offset_int16(BLOCK_8X8,
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001694 block,
1695 p->src_diff);
Jingning Han3ee6db62015-08-05 19:00:31 -07001696 tran_low_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block);
1697 xd->mi[0]->bmi[block].as_mode = mode;
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001698 vp10_predict_intra_block(xd, 1, 1, TX_4X4, mode, dst, dst_stride,
Jingning Han3ee6db62015-08-05 19:00:31 -07001699 dst, dst_stride,
1700 col + idx, row + idy, 0);
1701 vpx_highbd_subtract_block(4, 4, src_diff, 8, src, src_stride,
1702 dst, dst_stride, xd->bd);
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001703 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
hui sub3cc3a02015-08-24 14:37:54 -07001704 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001705 const scan_order *so = get_scan(TX_4X4, tx_type, 0);
Jingning Han20484042015-10-21 17:38:00 -07001706#if CONFIG_VAR_TX
1707 const int coeff_ctx = combine_entropy_contexts(*(tempa + idx),
1708 *(templ + idy));
Geza Lore432e8752016-01-22 13:57:28 +00001709#endif // CONFIG_VAR_TX
Yaowu Xu7c514e22015-09-28 15:55:46 -07001710 vp10_highbd_fwd_txfm_4x4(src_diff, coeff, 8, DCT_DCT, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07001711 vp10_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
Jingning Han20484042015-10-21 17:38:00 -07001712#if CONFIG_VAR_TX
Geza Lore432e8752016-01-22 13:57:28 +00001713 ratey += cost_coeffs(x, 0, block, coeff_ctx, TX_4X4, so->scan,
1714 so->neighbors, cpi->sf.use_fast_coef_costing);
1715 *(tempa + idx) = !(p->eobs[block] == 0);
1716 *(templ + idy) = !(p->eobs[block] == 0);
Jingning Han20484042015-10-21 17:38:00 -07001717#else
Geza Lore432e8752016-01-22 13:57:28 +00001718 ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy,
Jingning Han20484042015-10-21 17:38:00 -07001719 TX_4X4,
Jingning Han3ee6db62015-08-05 19:00:31 -07001720 so->scan, so->neighbors,
1721 cpi->sf.use_fast_coef_costing);
Geza Lore432e8752016-01-22 13:57:28 +00001722#endif // CONFIG_VAR_TX
Jingning Han3ee6db62015-08-05 19:00:31 -07001723 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1724 goto next_highbd;
hui sud76e5b32015-08-13 16:27:19 -07001725 vp10_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block),
1726 dst, dst_stride, p->eobs[block],
Yaowu Xu7c514e22015-09-28 15:55:46 -07001727 xd->bd, DCT_DCT, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07001728 } else {
Yue Chenef8f7c12016-03-04 09:48:57 -08001729 int64_t dist;
1730 unsigned int tmp;
hui sub3cc3a02015-08-24 14:37:54 -07001731 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001732 const scan_order *so = get_scan(TX_4X4, tx_type, 0);
Jingning Han20484042015-10-21 17:38:00 -07001733#if CONFIG_VAR_TX
1734 const int coeff_ctx = combine_entropy_contexts(*(tempa + idx),
1735 *(templ + idy));
Geza Lore432e8752016-01-22 13:57:28 +00001736#endif // CONFIG_VAR_TX
Yaowu Xu7c514e22015-09-28 15:55:46 -07001737 vp10_highbd_fwd_txfm_4x4(src_diff, coeff, 8, tx_type, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07001738 vp10_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
Jingning Han20484042015-10-21 17:38:00 -07001739#if CONFIG_VAR_TX
Geza Lore432e8752016-01-22 13:57:28 +00001740 ratey += cost_coeffs(x, 0, block, coeff_ctx, TX_4X4, so->scan,
1741 so->neighbors, cpi->sf.use_fast_coef_costing);
1742 *(tempa + idx) = !(p->eobs[block] == 0);
1743 *(templ + idy) = !(p->eobs[block] == 0);
Jingning Han20484042015-10-21 17:38:00 -07001744#else
Geza Lore432e8752016-01-22 13:57:28 +00001745 ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy,
1746 TX_4X4, so->scan, so->neighbors,
Jingning Han3ee6db62015-08-05 19:00:31 -07001747 cpi->sf.use_fast_coef_costing);
Geza Lore432e8752016-01-22 13:57:28 +00001748#endif // CONFIG_VAR_TX
hui sud76e5b32015-08-13 16:27:19 -07001749 vp10_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block),
1750 dst, dst_stride, p->eobs[block],
Yaowu Xu7c514e22015-09-28 15:55:46 -07001751 xd->bd, tx_type, 0);
Yue Chenef8f7c12016-03-04 09:48:57 -08001752 cpi->fn_ptr[BLOCK_4X4].vf(src, src_stride, dst, dst_stride, &tmp);
1753 dist = (int64_t)tmp << 4;
1754 distortion += dist;
1755 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1756 goto next_highbd;
Jingning Han3ee6db62015-08-05 19:00:31 -07001757 }
1758 }
1759 }
1760
1761 rate += ratey;
1762 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
1763
1764 if (this_rd < best_rd) {
1765 *bestrate = rate;
1766 *bestratey = ratey;
1767 *bestdistortion = distortion;
1768 best_rd = this_rd;
1769 *best_mode = mode;
1770 memcpy(a, tempa, sizeof(tempa));
1771 memcpy(l, templ, sizeof(templ));
1772 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
1773 memcpy(best_dst16 + idy * 8,
1774 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
1775 num_4x4_blocks_wide * 4 * sizeof(uint16_t));
1776 }
1777 }
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001778next_highbd:
Jingning Han3ee6db62015-08-05 19:00:31 -07001779 {}
1780 }
Geza Lore432e8752016-01-22 13:57:28 +00001781
Jingning Han481b8342015-09-11 08:56:06 -07001782 if (best_rd >= rd_thresh)
Jingning Han3ee6db62015-08-05 19:00:31 -07001783 return best_rd;
1784
1785 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
1786 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
1787 best_dst16 + idy * 8,
1788 num_4x4_blocks_wide * 4 * sizeof(uint16_t));
1789 }
1790
1791 return best_rd;
1792 }
1793#endif // CONFIG_VP9_HIGHBITDEPTH
1794
1795 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
1796 int64_t this_rd;
1797 int ratey = 0;
1798 int64_t distortion = 0;
1799 int rate = bmode_costs[mode];
1800
1801 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode)))
1802 continue;
1803
1804 // Only do the oblique modes if the best so far is
1805 // one of the neighboring directional modes
1806 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
1807 if (conditional_skipintra(mode, *best_mode))
Debargha Mukherjee8a429242015-10-12 12:30:55 -07001808 continue;
Jingning Han3ee6db62015-08-05 19:00:31 -07001809 }
1810
1811 memcpy(tempa, ta, sizeof(ta));
1812 memcpy(templ, tl, sizeof(tl));
1813
1814 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
1815 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
1816 const int block = (row + idy) * 2 + (col + idx);
1817 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
1818 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
1819 int16_t *const src_diff =
1820 vp10_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff);
1821 tran_low_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block);
1822 xd->mi[0]->bmi[block].as_mode = mode;
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001823 vp10_predict_intra_block(xd, 1, 1, TX_4X4, mode, dst, dst_stride,
Jingning Han3ee6db62015-08-05 19:00:31 -07001824 dst, dst_stride, col + idx, row + idy, 0);
1825 vpx_subtract_block(4, 4, src_diff, 8, src, src_stride, dst, dst_stride);
1826
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04001827 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
hui sub3cc3a02015-08-24 14:37:54 -07001828 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001829 const scan_order *so = get_scan(TX_4X4, tx_type, 0);
Jingning Han2cdc1272015-10-09 09:57:42 -07001830#if CONFIG_VAR_TX
Geza Lore432e8752016-01-22 13:57:28 +00001831 const int coeff_ctx = combine_entropy_contexts(*(tempa + idx),
1832 *(templ + idy));
Jingning Han2cdc1272015-10-09 09:57:42 -07001833#endif
Yaowu Xu7c514e22015-09-28 15:55:46 -07001834 vp10_fwd_txfm_4x4(src_diff, coeff, 8, DCT_DCT, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07001835 vp10_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
Jingning Han2cdc1272015-10-09 09:57:42 -07001836#if CONFIG_VAR_TX
1837 ratey += cost_coeffs(x, 0, block, coeff_ctx, TX_4X4, so->scan,
1838 so->neighbors, cpi->sf.use_fast_coef_costing);
1839 *(tempa + idx) = !(p->eobs[block] == 0);
1840 *(templ + idy) = !(p->eobs[block] == 0);
1841#else
1842 ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy,
1843 TX_4X4,
Jingning Han3ee6db62015-08-05 19:00:31 -07001844 so->scan, so->neighbors,
1845 cpi->sf.use_fast_coef_costing);
Jingning Han2cdc1272015-10-09 09:57:42 -07001846#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07001847 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1848 goto next;
hui sud76e5b32015-08-13 16:27:19 -07001849 vp10_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block),
Yaowu Xu7c514e22015-09-28 15:55:46 -07001850 dst, dst_stride, p->eobs[block], DCT_DCT, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07001851 } else {
Yue Chenef8f7c12016-03-04 09:48:57 -08001852 int64_t dist;
1853 unsigned int tmp;
hui sub3cc3a02015-08-24 14:37:54 -07001854 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07001855 const scan_order *so = get_scan(TX_4X4, tx_type, 0);
Jingning Han2cdc1272015-10-09 09:57:42 -07001856#if CONFIG_VAR_TX
Geza Lore432e8752016-01-22 13:57:28 +00001857 const int coeff_ctx = combine_entropy_contexts(*(tempa + idx),
1858 *(templ + idy));
Jingning Han2cdc1272015-10-09 09:57:42 -07001859#endif
Yaowu Xu7c514e22015-09-28 15:55:46 -07001860 vp10_fwd_txfm_4x4(src_diff, coeff, 8, tx_type, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07001861 vp10_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
Jingning Han2cdc1272015-10-09 09:57:42 -07001862#if CONFIG_VAR_TX
1863 ratey += cost_coeffs(x, 0, block, coeff_ctx, TX_4X4, so->scan,
1864 so->neighbors, cpi->sf.use_fast_coef_costing);
1865 *(tempa + idx) = !(p->eobs[block] == 0);
1866 *(templ + idy) = !(p->eobs[block] == 0);
1867#else
1868 ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy,
1869 TX_4X4, so->scan, so->neighbors,
1870 cpi->sf.use_fast_coef_costing);
1871#endif
hui sud76e5b32015-08-13 16:27:19 -07001872 vp10_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block),
Yaowu Xu7c514e22015-09-28 15:55:46 -07001873 dst, dst_stride, p->eobs[block], tx_type, 0);
Yue Chenef8f7c12016-03-04 09:48:57 -08001874 cpi->fn_ptr[BLOCK_4X4].vf(src, src_stride, dst, dst_stride, &tmp);
1875 dist = (int64_t)tmp << 4;
1876 distortion += dist;
1877 // To use the pixel domain distortion, the step below needs to be
1878 // put behind the inv txfm. Compared to calculating the distortion
1879 // in the frequency domain, the overhead of encoding effort is low.
1880 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1881 goto next;
Jingning Han3ee6db62015-08-05 19:00:31 -07001882 }
1883 }
1884 }
1885
1886 rate += ratey;
1887 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
1888
1889 if (this_rd < best_rd) {
1890 *bestrate = rate;
1891 *bestratey = ratey;
1892 *bestdistortion = distortion;
1893 best_rd = this_rd;
1894 *best_mode = mode;
1895 memcpy(a, tempa, sizeof(tempa));
1896 memcpy(l, templ, sizeof(templ));
1897 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
1898 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
1899 num_4x4_blocks_wide * 4);
1900 }
1901 next:
1902 {}
1903 }
1904
Jingning Hanf1376972015-09-10 12:42:21 -07001905 if (best_rd >= rd_thresh)
Jingning Han3ee6db62015-08-05 19:00:31 -07001906 return best_rd;
1907
1908 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
1909 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
1910 num_4x4_blocks_wide * 4);
1911
1912 return best_rd;
1913}
1914
Yaowu Xu26a9afc2015-08-13 09:42:27 -07001915static int64_t rd_pick_intra_sub_8x8_y_mode(VP10_COMP *cpi, MACROBLOCK *mb,
Jingning Han3ee6db62015-08-05 19:00:31 -07001916 int *rate, int *rate_y,
1917 int64_t *distortion,
1918 int64_t best_rd) {
1919 int i, j;
1920 const MACROBLOCKD *const xd = &mb->e_mbd;
1921 MODE_INFO *const mic = xd->mi[0];
1922 const MODE_INFO *above_mi = xd->above_mi;
1923 const MODE_INFO *left_mi = xd->left_mi;
1924 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
1925 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1926 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1927 int idx, idy;
1928 int cost = 0;
1929 int64_t total_distortion = 0;
1930 int tot_rate_y = 0;
1931 int64_t total_rd = 0;
1932 ENTROPY_CONTEXT t_above[4], t_left[4];
hui su1559afd2015-12-30 10:27:19 -08001933 const int *bmode_costs = cpi->mbmode_cost[0];
Jingning Han3ee6db62015-08-05 19:00:31 -07001934
1935 memcpy(t_above, xd->plane[0].above_context, sizeof(t_above));
1936 memcpy(t_left, xd->plane[0].left_context, sizeof(t_left));
1937
hui sube3559b2015-10-07 09:29:02 -07001938#if CONFIG_EXT_INTRA
1939 mic->mbmi.ext_intra_mode_info.use_ext_intra_mode[0] = 0;
hui su3b1c7662016-01-12 16:38:58 -08001940 mic->mbmi.intra_filter = INTRA_FILTER_LINEAR;
hui sube3559b2015-10-07 09:29:02 -07001941#endif // CONFIG_EXT_INTRA
1942
Debargha Mukherjeed46c1f22016-02-08 15:59:17 -08001943 // TODO(any): Add search of the tx_type to improve rd performance at the
1944 // expense of speed.
1945 mic->mbmi.tx_type = DCT_DCT;
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08001946 mic->mbmi.tx_size = TX_4X4;
Debargha Mukherjeed46c1f22016-02-08 15:59:17 -08001947
Jingning Han3ee6db62015-08-05 19:00:31 -07001948 // Pick modes for each sub-block (of size 4x4, 4x8, or 8x4) in an 8x8 block.
1949 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
1950 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
1951 PREDICTION_MODE best_mode = DC_PRED;
1952 int r = INT_MAX, ry = INT_MAX;
1953 int64_t d = INT64_MAX, this_rd = INT64_MAX;
1954 i = idy * 2 + idx;
1955 if (cpi->common.frame_type == KEY_FRAME) {
1956 const PREDICTION_MODE A = vp10_above_block_mode(mic, above_mi, i);
1957 const PREDICTION_MODE L = vp10_left_block_mode(mic, left_mi, i);
1958
1959 bmode_costs = cpi->y_mode_costs[A][L];
1960 }
1961
1962 this_rd = rd_pick_intra4x4block(cpi, mb, idy, idx, &best_mode,
1963 bmode_costs, t_above + idx, t_left + idy,
1964 &r, &ry, &d, bsize, best_rd - total_rd);
1965 if (this_rd >= best_rd - total_rd)
1966 return INT64_MAX;
1967
1968 total_rd += this_rd;
1969 cost += r;
1970 total_distortion += d;
1971 tot_rate_y += ry;
1972
1973 mic->bmi[i].as_mode = best_mode;
1974 for (j = 1; j < num_4x4_blocks_high; ++j)
1975 mic->bmi[i + j * 2].as_mode = best_mode;
1976 for (j = 1; j < num_4x4_blocks_wide; ++j)
1977 mic->bmi[i + j].as_mode = best_mode;
1978
1979 if (total_rd >= best_rd)
1980 return INT64_MAX;
1981 }
1982 }
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08001983 mic->mbmi.mode = mic->bmi[3].as_mode;
1984
1985 // Add in the cost of the transform type
1986 if (!xd->lossless[mic->mbmi.segment_id]) {
1987 int rate_tx_type = 0;
1988#if CONFIG_EXT_TX
1989 if (get_ext_tx_types(TX_4X4, bsize, 0) > 1) {
1990 const int eset = get_ext_tx_set(TX_4X4, bsize, 0);
1991 rate_tx_type =
1992 cpi->intra_tx_type_costs[eset][TX_4X4]
1993 [mic->mbmi.mode][mic->mbmi.tx_type];
1994 }
1995#else
1996 rate_tx_type =
1997 cpi->intra_tx_type_costs[TX_4X4]
1998 [intra_mode_to_tx_type_context[mic->mbmi.mode]]
1999 [mic->mbmi.tx_type];
2000#endif
2001 assert(mic->mbmi.tx_size == TX_4X4);
2002 cost += rate_tx_type;
2003 tot_rate_y += rate_tx_type;
2004 }
Jingning Han3ee6db62015-08-05 19:00:31 -07002005
2006 *rate = cost;
2007 *rate_y = tot_rate_y;
2008 *distortion = total_distortion;
Jingning Han3ee6db62015-08-05 19:00:31 -07002009
2010 return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
2011}
2012
hui sube3559b2015-10-07 09:29:02 -07002013#if CONFIG_EXT_INTRA
2014// Return 1 if an ext intra mode is selected; return 0 otherwise.
2015static int rd_pick_ext_intra_sby(VP10_COMP *cpi, MACROBLOCK *x,
2016 int *rate, int *rate_tokenonly,
2017 int64_t *distortion, int *skippable,
2018 BLOCK_SIZE bsize, int mode_cost,
2019 int64_t *best_rd) {
2020 MACROBLOCKD *const xd = &x->e_mbd;
2021 MODE_INFO *const mic = xd->mi[0];
2022 MB_MODE_INFO *mbmi = &mic->mbmi;
2023 int this_rate, this_rate_tokenonly, s;
2024 int ext_intra_selected_flag = 0;
hui su4aa50c12015-11-10 12:09:59 -08002025 int64_t this_distortion, this_rd;
hui sube3559b2015-10-07 09:29:02 -07002026 EXT_INTRA_MODE mode;
2027 TX_SIZE best_tx_size = TX_4X4;
2028 EXT_INTRA_MODE_INFO ext_intra_mode_info;
hui sube3559b2015-10-07 09:29:02 -07002029 TX_TYPE best_tx_type;
hui sube3559b2015-10-07 09:29:02 -07002030
2031 vp10_zero(ext_intra_mode_info);
2032 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 1;
2033 mbmi->mode = DC_PRED;
2034
hui su4aa50c12015-11-10 12:09:59 -08002035 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
2036 mbmi->ext_intra_mode_info.ext_intra_mode[0] = mode;
2037 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
2038 &s, NULL, bsize, *best_rd);
2039 if (this_rate_tokenonly == INT_MAX)
2040 continue;
hui sube3559b2015-10-07 09:29:02 -07002041
hui su4aa50c12015-11-10 12:09:59 -08002042 this_rate = this_rate_tokenonly +
2043 vp10_cost_bit(cpi->common.fc->ext_intra_probs[0], 1) +
2044 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
2045 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui sube3559b2015-10-07 09:29:02 -07002046
hui su4aa50c12015-11-10 12:09:59 -08002047 if (this_rd < *best_rd) {
2048 *best_rd = this_rd;
2049 best_tx_size = mic->mbmi.tx_size;
2050 ext_intra_mode_info = mbmi->ext_intra_mode_info;
hui su4aa50c12015-11-10 12:09:59 -08002051 best_tx_type = mic->mbmi.tx_type;
hui su4aa50c12015-11-10 12:09:59 -08002052 *rate = this_rate;
2053 *rate_tokenonly = this_rate_tokenonly;
2054 *distortion = this_distortion;
2055 *skippable = s;
2056 ext_intra_selected_flag = 1;
hui sube3559b2015-10-07 09:29:02 -07002057 }
2058 }
2059
2060 if (ext_intra_selected_flag) {
2061 mbmi->mode = DC_PRED;
2062 mbmi->tx_size = best_tx_size;
2063 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] =
2064 ext_intra_mode_info.use_ext_intra_mode[0];
2065 mbmi->ext_intra_mode_info.ext_intra_mode[0] =
2066 ext_intra_mode_info.ext_intra_mode[0];
hui sube3559b2015-10-07 09:29:02 -07002067 mbmi->tx_type = best_tx_type;
hui sube3559b2015-10-07 09:29:02 -07002068 return 1;
2069 } else {
2070 return 0;
2071 }
2072}
hui su4aa50c12015-11-10 12:09:59 -08002073
hui su5a7c8d82016-02-08 10:39:17 -08002074static void pick_intra_angle_routine_sby(VP10_COMP *cpi, MACROBLOCK *x,
2075 int *rate, int *rate_tokenonly,
2076 int64_t *distortion, int *skippable,
2077 int *best_angle_delta,
2078 TX_SIZE *best_tx_size,
2079 TX_TYPE *best_tx_type,
2080 INTRA_FILTER *best_filter,
2081 BLOCK_SIZE bsize, int rate_overhead,
2082 int64_t *best_rd) {
2083 int this_rate, this_rate_tokenonly, s;
2084 int64_t this_distortion, this_rd;
2085 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
2086 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
2087 &s, NULL, bsize, *best_rd);
2088 if (this_rate_tokenonly == INT_MAX)
2089 return;
2090
2091 this_rate = this_rate_tokenonly + rate_overhead;
2092 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
2093
2094 if (this_rd < *best_rd) {
2095 *best_rd = this_rd;
2096 *best_angle_delta = mbmi->angle_delta[0];
2097 *best_tx_size = mbmi->tx_size;
2098 *best_filter = mbmi->intra_filter;
2099 *best_tx_type = mbmi->tx_type;
2100 *rate = this_rate;
2101 *rate_tokenonly = this_rate_tokenonly;
2102 *distortion = this_distortion;
2103 *skippable = s;
2104 }
2105}
2106
hui su4aa50c12015-11-10 12:09:59 -08002107static int64_t rd_pick_intra_angle_sby(VP10_COMP *cpi, MACROBLOCK *x,
2108 int *rate, int *rate_tokenonly,
2109 int64_t *distortion, int *skippable,
2110 BLOCK_SIZE bsize, int rate_overhead,
2111 int64_t best_rd) {
2112 MACROBLOCKD *const xd = &x->e_mbd;
2113 MODE_INFO *const mic = xd->mi[0];
2114 MB_MODE_INFO *mbmi = &mic->mbmi;
2115 int this_rate, this_rate_tokenonly, s;
hui su3b1c7662016-01-12 16:38:58 -08002116 int angle_delta, best_angle_delta = 0, p_angle;
2117 const int intra_filter_ctx = vp10_get_pred_context_intra_interp(xd);
2118 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
hui su4aa50c12015-11-10 12:09:59 -08002119 const double rd_adjust = 1.2;
2120 int64_t this_distortion, this_rd, sse_dummy;
2121 TX_SIZE best_tx_size = mic->mbmi.tx_size;
hui su4aa50c12015-11-10 12:09:59 -08002122 TX_TYPE best_tx_type = mbmi->tx_type;
hui su4aa50c12015-11-10 12:09:59 -08002123
2124 if (ANGLE_FAST_SEARCH) {
2125 int deltas_level1[3] = {0, -2, 2};
2126 int deltas_level2[3][2] = {
2127 {-1, 1}, {-3, -1}, {1, 3},
2128 };
2129 const int level1 = 3, level2 = 2;
2130 int i, j, best_i = -1;
2131
2132 for (i = 0; i < level1; ++i) {
2133 mic->mbmi.angle_delta[0] = deltas_level1[i];
hui su3b1c7662016-01-12 16:38:58 -08002134 p_angle = mode_to_angle_map[mbmi->mode] +
2135 mbmi->angle_delta[0] * ANGLE_STEP;
2136 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
Yaowu Xu28eb7842016-03-07 16:23:26 -08002137 int64_t tmp_best_rd;
hui su5b618b72016-02-03 11:32:25 -08002138 if ((FILTER_FAST_SEARCH || !pick_intra_filter(p_angle)) &&
2139 filter != INTRA_FILTER_LINEAR)
hui su4aa50c12015-11-10 12:09:59 -08002140 continue;
hui su3b1c7662016-01-12 16:38:58 -08002141 mic->mbmi.intra_filter = filter;
Yaowu Xu28eb7842016-03-07 16:23:26 -08002142 tmp_best_rd = (i == 0 && filter == INTRA_FILTER_LINEAR &&
2143 best_rd < INT64_MAX) ? (int64_t)(best_rd * rd_adjust) : best_rd;
hui su4aa50c12015-11-10 12:09:59 -08002144 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
Yaowu Xu28eb7842016-03-07 16:23:26 -08002145 &s, NULL, bsize, tmp_best_rd);
hui su3b1c7662016-01-12 16:38:58 -08002146 if (this_rate_tokenonly == INT_MAX) {
2147 if (i == 0 && filter == INTRA_FILTER_LINEAR)
2148 return best_rd;
2149 else
2150 continue;
2151 }
2152 this_rate = this_rate_tokenonly + rate_overhead +
2153 cpi->intra_filter_cost[intra_filter_ctx][filter];
hui su4aa50c12015-11-10 12:09:59 -08002154 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui su3b1c7662016-01-12 16:38:58 -08002155 if (i == 0 && filter == INTRA_FILTER_LINEAR &&
2156 best_rd < INT64_MAX && this_rd > best_rd * rd_adjust)
2157 return best_rd;
hui su4aa50c12015-11-10 12:09:59 -08002158 if (this_rd < best_rd) {
hui su3b1c7662016-01-12 16:38:58 -08002159 best_i = i;
hui su4aa50c12015-11-10 12:09:59 -08002160 best_rd = this_rd;
2161 best_angle_delta = mbmi->angle_delta[0];
2162 best_tx_size = mbmi->tx_size;
hui su3b1c7662016-01-12 16:38:58 -08002163 best_filter = mbmi->intra_filter;
hui su4aa50c12015-11-10 12:09:59 -08002164 best_tx_type = mbmi->tx_type;
hui su4aa50c12015-11-10 12:09:59 -08002165 *rate = this_rate;
2166 *rate_tokenonly = this_rate_tokenonly;
2167 *distortion = this_distortion;
2168 *skippable = s;
2169 }
2170 }
2171 }
hui su3b1c7662016-01-12 16:38:58 -08002172
2173 if (best_i >= 0) {
2174 for (j = 0; j < level2; ++j) {
2175 mic->mbmi.angle_delta[0] = deltas_level2[best_i][j];
2176 p_angle = mode_to_angle_map[mbmi->mode] +
2177 mbmi->angle_delta[0] * ANGLE_STEP;
2178 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2179 mic->mbmi.intra_filter = filter;
hui su5b618b72016-02-03 11:32:25 -08002180 if ((FILTER_FAST_SEARCH || !pick_intra_filter(p_angle)) &&
2181 filter != INTRA_FILTER_LINEAR)
hui su3b1c7662016-01-12 16:38:58 -08002182 continue;
hui su5a7c8d82016-02-08 10:39:17 -08002183 pick_intra_angle_routine_sby(cpi, x, rate, rate_tokenonly,
2184 distortion, skippable,
2185 &best_angle_delta, &best_tx_size,
2186 &best_tx_type, &best_filter, bsize,
2187 rate_overhead +
2188 cpi->intra_filter_cost
2189 [intra_filter_ctx][filter],
2190 &best_rd);
hui su3b1c7662016-01-12 16:38:58 -08002191 }
2192 }
2193 }
hui su4aa50c12015-11-10 12:09:59 -08002194 } else {
2195 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
2196 ++angle_delta) {
hui su3b1c7662016-01-12 16:38:58 -08002197 mbmi->angle_delta[0] = angle_delta;
2198 p_angle = mode_to_angle_map[mbmi->mode] +
2199 mbmi->angle_delta[0] * ANGLE_STEP;
2200 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2201 mic->mbmi.intra_filter = filter;
hui su5b618b72016-02-03 11:32:25 -08002202 if ((FILTER_FAST_SEARCH || !pick_intra_filter(p_angle)) &&
2203 filter != INTRA_FILTER_LINEAR)
hui su3b1c7662016-01-12 16:38:58 -08002204 continue;
hui su5a7c8d82016-02-08 10:39:17 -08002205 pick_intra_angle_routine_sby(cpi, x, rate, rate_tokenonly,
2206 distortion, skippable,
2207 &best_angle_delta, &best_tx_size,
2208 &best_tx_type, &best_filter, bsize,
2209 rate_overhead +
2210 cpi->intra_filter_cost
2211 [intra_filter_ctx][filter],
2212 &best_rd);
hui su4aa50c12015-11-10 12:09:59 -08002213 }
2214 }
2215 }
2216
hui su5b618b72016-02-03 11:32:25 -08002217 if (FILTER_FAST_SEARCH && *rate_tokenonly < INT_MAX) {
2218 mbmi->angle_delta[0] = best_angle_delta;
2219 p_angle = mode_to_angle_map[mbmi->mode] +
2220 mbmi->angle_delta[0] * ANGLE_STEP;
2221 if (pick_intra_filter(p_angle)) {
2222 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
2223 mic->mbmi.intra_filter = filter;
hui su5a7c8d82016-02-08 10:39:17 -08002224 pick_intra_angle_routine_sby(cpi, x, rate, rate_tokenonly,
2225 distortion, skippable,
2226 &best_angle_delta, &best_tx_size,
2227 &best_tx_type, &best_filter, bsize,
2228 rate_overhead + cpi->intra_filter_cost
2229 [intra_filter_ctx][filter], &best_rd);
hui su5b618b72016-02-03 11:32:25 -08002230 }
2231 }
2232 }
2233
hui su4aa50c12015-11-10 12:09:59 -08002234 mbmi->tx_size = best_tx_size;
2235 mbmi->angle_delta[0] = best_angle_delta;
hui su3b1c7662016-01-12 16:38:58 -08002236 mic->mbmi.intra_filter = best_filter;
hui su4aa50c12015-11-10 12:09:59 -08002237 mbmi->tx_type = best_tx_type;
hui su4aa50c12015-11-10 12:09:59 -08002238
2239 if (*rate_tokenonly < INT_MAX) {
2240 txfm_rd_in_plane(x,
hui su4aa50c12015-11-10 12:09:59 -08002241 cpi,
hui su4aa50c12015-11-10 12:09:59 -08002242 &this_rate_tokenonly, &this_distortion, &s,
2243 &sse_dummy, INT64_MAX, 0, bsize, mbmi->tx_size,
2244 cpi->sf.use_fast_coef_costing);
2245 }
2246
2247 return best_rd;
2248}
hui sud7c8bc72015-11-12 19:18:32 -08002249
Yaowu Xu28eb7842016-03-07 16:23:26 -08002250static INLINE int get_angle_index(double angle) {
hui sud7c8bc72015-11-12 19:18:32 -08002251 const double step = 22.5, base = 45;
2252 return (int)round((angle - base) / step);
2253}
2254
2255static void angle_estimation(const uint8_t *src, int src_stride,
2256 int rows, int cols, double *hist) {
2257 int r, c, i, index;
2258 const double pi = 3.1415;
2259 double angle, dx, dy;
2260 double temp, divisor = 0;
2261
2262 for (i = 0; i < DIRECTIONAL_MODES; ++i)
2263 hist[i] = 0;
2264
2265 src += src_stride;
2266 for (r = 1; r < rows; ++r) {
2267 for (c = 1; c < cols; ++c) {
2268 dx = src[c] - src[c - 1];
2269 dy = src[c] - src[c - src_stride];
2270 temp = dx * dx + dy * dy;
2271 if (dy == 0)
2272 angle = 90;
2273 else
2274 angle = (atan((double)dx / (double)dy)) * 180 / pi;
2275 assert(angle >= -90 && angle <= 90);
2276 index = get_angle_index(angle + 180);
2277 if (index < DIRECTIONAL_MODES) {
2278 hist[index] += temp;
2279 divisor += temp;
2280 }
2281 if (angle > 0) {
2282 index = get_angle_index(angle);
2283 if (index >= 0) {
2284 hist[index] += temp;
2285 divisor += temp;
2286 }
2287 }
2288 }
2289 src += src_stride;
2290 }
2291
2292 if (divisor < 1)
2293 divisor = 1;
2294 for (i = 0; i < DIRECTIONAL_MODES; ++i)
2295 hist[i] /= divisor;
2296}
2297
2298#if CONFIG_VP9_HIGHBITDEPTH
2299static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
2300 int rows, int cols, double *hist) {
2301 int r, c, i, index;
2302 const double pi = 3.1415;
2303 double angle, dx, dy;
2304 double temp, divisor = 0;
2305 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
2306
2307 for (i = 0; i < DIRECTIONAL_MODES; ++i)
2308 hist[i] = 0;
2309
2310 src += src_stride;
2311 for (r = 1; r < rows; ++r) {
2312 for (c = 1; c < cols; ++c) {
2313 dx = src[c] - src[c - 1];
2314 dy = src[c] - src[c - src_stride];
2315 temp = dx * dx + dy * dy;
2316 if (dy == 0)
2317 angle = 90;
2318 else
2319 angle = (atan((double)dx / (double)dy)) * 180 / pi;
2320 assert(angle >= -90 && angle <= 90);
2321 index = get_angle_index(angle + 180);
2322 if (index < DIRECTIONAL_MODES) {
2323 hist[index] += temp;
2324 divisor += temp;
2325 }
2326 if (angle > 0) {
2327 index = get_angle_index(angle);
2328 if (index >= 0) {
2329 hist[index] += temp;
2330 divisor += temp;
2331 }
2332 }
2333 }
2334 src += src_stride;
2335 }
2336
2337 if (divisor < 1)
2338 divisor = 1;
2339 for (i = 0; i < DIRECTIONAL_MODES; ++i)
2340 hist[i] /= divisor;
2341}
2342#endif // CONFIG_VP9_HIGHBITDEPTH
hui sube3559b2015-10-07 09:29:02 -07002343#endif // CONFIG_EXT_INTRA
2344
Jingning Han3ee6db62015-08-05 19:00:31 -07002345// This function is used only for intra_only frames
Yaowu Xu26a9afc2015-08-13 09:42:27 -07002346static int64_t rd_pick_intra_sby_mode(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07002347 int *rate, int *rate_tokenonly,
2348 int64_t *distortion, int *skippable,
2349 BLOCK_SIZE bsize,
2350 int64_t best_rd) {
2351 PREDICTION_MODE mode;
2352 PREDICTION_MODE mode_selected = DC_PRED;
2353 MACROBLOCKD *const xd = &x->e_mbd;
2354 MODE_INFO *const mic = xd->mi[0];
2355 int this_rate, this_rate_tokenonly, s;
2356 int64_t this_distortion, this_rd;
2357 TX_SIZE best_tx = TX_4X4;
hui sube3559b2015-10-07 09:29:02 -07002358#if CONFIG_EXT_INTRA
hui su3b1c7662016-01-12 16:38:58 -08002359 const int intra_filter_ctx = vp10_get_pred_context_intra_interp(xd);
hui sube3559b2015-10-07 09:29:02 -07002360 EXT_INTRA_MODE_INFO ext_intra_mode_info;
hui su4aa50c12015-11-10 12:09:59 -08002361 int is_directional_mode, rate_overhead, best_angle_delta = 0;
hui su3b1c7662016-01-12 16:38:58 -08002362 INTRA_FILTER best_filter = INTRA_FILTER_LINEAR;
hui sud7c8bc72015-11-12 19:18:32 -08002363 uint8_t directional_mode_skip_mask[INTRA_MODES];
2364 const int src_stride = x->plane[0].src.stride;
2365 const uint8_t *src = x->plane[0].src.buf;
2366 double hist[DIRECTIONAL_MODES];
hui sube3559b2015-10-07 09:29:02 -07002367#endif // CONFIG_EXT_INTRA
hui su4f16f112015-10-02 10:45:27 -07002368 TX_TYPE best_tx_type = DCT_DCT;
Jingning Han3ee6db62015-08-05 19:00:31 -07002369 int *bmode_costs;
hui suc93e5cc2015-12-07 18:18:57 -08002370 PALETTE_MODE_INFO palette_mode_info;
2371 uint8_t *best_palette_color_map = cpi->common.allow_screen_content_tools ?
2372 x->palette_buffer->best_palette_color_map : NULL;
2373 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
2374 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
2375 int palette_ctx = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07002376 const MODE_INFO *above_mi = xd->above_mi;
2377 const MODE_INFO *left_mi = xd->left_mi;
2378 const PREDICTION_MODE A = vp10_above_block_mode(mic, above_mi, 0);
2379 const PREDICTION_MODE L = vp10_left_block_mode(mic, left_mi, 0);
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08002380 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
Jingning Han3ee6db62015-08-05 19:00:31 -07002381 bmode_costs = cpi->y_mode_costs[A][L];
2382
hui sube3559b2015-10-07 09:29:02 -07002383#if CONFIG_EXT_INTRA
2384 ext_intra_mode_info.use_ext_intra_mode[0] = 0;
2385 mic->mbmi.ext_intra_mode_info.use_ext_intra_mode[0] = 0;
hui su4aa50c12015-11-10 12:09:59 -08002386 mic->mbmi.angle_delta[0] = 0;
hui sud7c8bc72015-11-12 19:18:32 -08002387 memset(directional_mode_skip_mask, 0,
2388 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
2389#if CONFIG_VP9_HIGHBITDEPTH
2390 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
2391 highbd_angle_estimation(src, src_stride, rows, cols, hist);
2392 else
2393#endif
2394 angle_estimation(src, src_stride, rows, cols, hist);
2395
2396 for (mode = 0; mode < INTRA_MODES; ++mode) {
2397 if (mode != DC_PRED && mode != TM_PRED) {
2398 int index = get_angle_index((double)mode_to_angle_map[mode]);
2399 double score, weight = 1.0;
2400 score = hist[index];
2401 if (index > 0) {
2402 score += hist[index - 1] * 0.5;
2403 weight += 0.5;
2404 }
2405 if (index < DIRECTIONAL_MODES - 1) {
2406 score += hist[index + 1] * 0.5;
2407 weight += 0.5;
2408 }
2409 score /= weight;
2410 if (score < ANGLE_SKIP_THRESH)
2411 directional_mode_skip_mask[mode] = 1;
2412 }
2413 }
hui sube3559b2015-10-07 09:29:02 -07002414#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07002415 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
hui suc93e5cc2015-12-07 18:18:57 -08002416 palette_mode_info.palette_size[0] = 0;
2417 mic->mbmi.palette_mode_info.palette_size[0] = 0;
2418 if (above_mi)
2419 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
2420 if (left_mi)
2421 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
hui su5d011cb2015-09-15 12:44:13 -07002422
Jingning Han3ee6db62015-08-05 19:00:31 -07002423 /* Y Search for intra prediction mode */
hui sube3559b2015-10-07 09:29:02 -07002424 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
Jingning Han3ee6db62015-08-05 19:00:31 -07002425 mic->mbmi.mode = mode;
hui su4aa50c12015-11-10 12:09:59 -08002426#if CONFIG_EXT_INTRA
2427 is_directional_mode = (mode != DC_PRED && mode != TM_PRED);
hui sud7c8bc72015-11-12 19:18:32 -08002428 if (is_directional_mode && directional_mode_skip_mask[mode])
2429 continue;
hui su4aa50c12015-11-10 12:09:59 -08002430 if (is_directional_mode) {
hui sud7c8bc72015-11-12 19:18:32 -08002431 rate_overhead = bmode_costs[mode] +
2432 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
2433 this_rate_tokenonly = INT_MAX;
2434 this_rd =
2435 rd_pick_intra_angle_sby(cpi, x, &this_rate, &this_rate_tokenonly,
2436 &this_distortion, &s, bsize, rate_overhead,
2437 best_rd);
hui su4aa50c12015-11-10 12:09:59 -08002438 } else {
2439 mic->mbmi.angle_delta[0] = 0;
2440 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
2441 &s, NULL, bsize, best_rd);
2442 }
2443#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07002444 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
hui su4aa50c12015-11-10 12:09:59 -08002445 &s, NULL, bsize, best_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07002446
2447 if (this_rate_tokenonly == INT_MAX)
2448 continue;
2449
2450 this_rate = this_rate_tokenonly + bmode_costs[mode];
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08002451
2452 if (!xd->lossless[xd->mi[0]->mbmi.segment_id]) {
2453 // super_block_yrd above includes the cost of the tx_size in the
2454 // tokenonly rate, but for intra blocks, tx_size is always coded
2455 // (prediction granularity), so we account for it in the full rate,
2456 // not the tokenonly rate.
hui su954e5602016-03-07 15:25:50 -08002457 this_rate_tokenonly -=
2458 cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
2459 [mic->mbmi.tx_size];
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08002460 }
hui suc93e5cc2015-12-07 18:18:57 -08002461 if (cpi->common.allow_screen_content_tools && mode == DC_PRED)
2462 this_rate +=
2463 vp10_cost_bit(vp10_default_palette_y_mode_prob[bsize - BLOCK_8X8]
2464 [palette_ctx], 0);
hui sube3559b2015-10-07 09:29:02 -07002465#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08002466 if (mode == DC_PRED && ALLOW_FILTER_INTRA_MODES)
hui sube3559b2015-10-07 09:29:02 -07002467 this_rate += vp10_cost_bit(cpi->common.fc->ext_intra_probs[0], 0);
hui su3b1c7662016-01-12 16:38:58 -08002468 if (is_directional_mode) {
2469 int p_angle;
hui su4aa50c12015-11-10 12:09:59 -08002470 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
2471 MAX_ANGLE_DELTAS +
2472 mic->mbmi.angle_delta[0]);
hui su3b1c7662016-01-12 16:38:58 -08002473 p_angle = mode_to_angle_map[mic->mbmi.mode] +
2474 mic->mbmi.angle_delta[0] * ANGLE_STEP;
2475 if (pick_intra_filter(p_angle))
2476 this_rate +=
2477 cpi->intra_filter_cost[intra_filter_ctx][mic->mbmi.intra_filter];
2478 }
hui sube3559b2015-10-07 09:29:02 -07002479#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07002480 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
2481
2482 if (this_rd < best_rd) {
2483 mode_selected = mode;
2484 best_rd = this_rd;
2485 best_tx = mic->mbmi.tx_size;
hui su4aa50c12015-11-10 12:09:59 -08002486#if CONFIG_EXT_INTRA
2487 best_angle_delta = mic->mbmi.angle_delta[0];
hui su3b1c7662016-01-12 16:38:58 -08002488 best_filter = mic->mbmi.intra_filter;
hui su4aa50c12015-11-10 12:09:59 -08002489#endif // CONFIG_EXT_INTRA
hui su4f16f112015-10-02 10:45:27 -07002490 best_tx_type = mic->mbmi.tx_type;
Jingning Han3ee6db62015-08-05 19:00:31 -07002491 *rate = this_rate;
2492 *rate_tokenonly = this_rate_tokenonly;
2493 *distortion = this_distortion;
2494 *skippable = s;
2495 }
2496 }
2497
hui suc93e5cc2015-12-07 18:18:57 -08002498 if (cpi->common.allow_screen_content_tools)
2499 rd_pick_palette_intra_sby(cpi, x, bsize, palette_ctx, bmode_costs[DC_PRED],
2500 &palette_mode_info, best_palette_color_map,
2501 &best_tx, &mode_selected, &best_rd);
2502
hui sube3559b2015-10-07 09:29:02 -07002503#if CONFIG_EXT_INTRA
hui suc93e5cc2015-12-07 18:18:57 -08002504 if (!palette_mode_info.palette_size[0] > 0 && ALLOW_FILTER_INTRA_MODES) {
2505 if (rd_pick_ext_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
2506 skippable, bsize, bmode_costs[DC_PRED],
2507 &best_rd)) {
2508 mode_selected = mic->mbmi.mode;
2509 best_tx = mic->mbmi.tx_size;
2510 ext_intra_mode_info = mic->mbmi.ext_intra_mode_info;
hui suc93e5cc2015-12-07 18:18:57 -08002511 best_tx_type = mic->mbmi.tx_type;
hui suc93e5cc2015-12-07 18:18:57 -08002512 }
hui sube3559b2015-10-07 09:29:02 -07002513 }
2514
2515 mic->mbmi.ext_intra_mode_info.use_ext_intra_mode[0] =
2516 ext_intra_mode_info.use_ext_intra_mode[0];
2517 if (ext_intra_mode_info.use_ext_intra_mode[0]) {
2518 mic->mbmi.ext_intra_mode_info.ext_intra_mode[0] =
2519 ext_intra_mode_info.ext_intra_mode[0];
hui sube3559b2015-10-07 09:29:02 -07002520 }
2521#endif // CONFIG_EXT_INTRA
2522
Jingning Han3ee6db62015-08-05 19:00:31 -07002523 mic->mbmi.mode = mode_selected;
2524 mic->mbmi.tx_size = best_tx;
hui su4aa50c12015-11-10 12:09:59 -08002525#if CONFIG_EXT_INTRA
2526 mic->mbmi.angle_delta[0] = best_angle_delta;
hui su3b1c7662016-01-12 16:38:58 -08002527 mic->mbmi.intra_filter = best_filter;
hui su4aa50c12015-11-10 12:09:59 -08002528#endif // CONFIG_EXT_INTRA
hui su4f16f112015-10-02 10:45:27 -07002529 mic->mbmi.tx_type = best_tx_type;
hui suc93e5cc2015-12-07 18:18:57 -08002530 mic->mbmi.palette_mode_info.palette_size[0] =
2531 palette_mode_info.palette_size[0];
2532 if (palette_mode_info.palette_size[0] > 0) {
2533 memcpy(mic->mbmi.palette_mode_info.palette_colors,
2534 palette_mode_info.palette_colors,
2535 PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
2536 memcpy(xd->plane[0].color_index_map, best_palette_color_map,
2537 rows * cols * sizeof(best_palette_color_map[0]));
2538 }
Jingning Han3ee6db62015-08-05 19:00:31 -07002539
2540 return best_rd;
2541}
2542
Jingning Hana8dad552015-10-08 16:46:10 -07002543#if CONFIG_VAR_TX
Jingning Han4c6c82a2016-02-09 17:51:49 -08002544void vp10_tx_block_rd_b(const VP10_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
2545 int blk_row, int blk_col, int plane, int block,
2546 int plane_bsize, int coeff_ctx,
2547 int *rate, int64_t *dist, int64_t *bsse, int *skip) {
Jingning Han2cdc1272015-10-09 09:57:42 -07002548 MACROBLOCKD *xd = &x->e_mbd;
2549 const struct macroblock_plane *const p = &x->plane[plane];
2550 struct macroblockd_plane *const pd = &xd->plane[plane];
Yaowu Xu5c613ea2016-03-01 09:17:17 -08002551 int64_t tmp;
Jingning Han2cdc1272015-10-09 09:57:42 -07002552 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
2553 PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
2554 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
2555 const scan_order *const scan_order =
2556 get_scan(tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
2557
Jingning Han71c15602015-10-13 12:40:39 -07002558 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
2559 int bh = 4 * num_4x4_blocks_wide_lookup[txm_bsize];
2560 int src_stride = p->src.stride;
2561 uint8_t *src = &p->src.buf[4 * blk_row * src_stride + 4 * blk_col];
2562 uint8_t *dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
Peter de Rivaz22850492015-12-08 15:58:21 +00002563#if CONFIG_VP9_HIGHBITDEPTH
2564 DECLARE_ALIGNED(16, uint16_t, rec_buffer_alloc_16[32 * 32]);
2565 uint8_t *rec_buffer;
2566#else
Jingning Han71c15602015-10-13 12:40:39 -07002567 DECLARE_ALIGNED(16, uint8_t, rec_buffer[32 * 32]);
Geza Lore3c4b56c2016-02-16 09:54:29 +00002568#endif // CONFIG_VP9_HIGHBITDEPTH
Geza Loreabd00502016-02-12 16:04:35 +00002569 const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
2570 const int16_t *diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
Jingning Han71c15602015-10-13 12:40:39 -07002571
2572 int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
2573 int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
2574
2575 if (xd->mb_to_bottom_edge < 0)
2576 max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
2577 if (xd->mb_to_right_edge < 0)
2578 max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
2579
Angie Chiang88cae8b2015-11-25 13:07:13 -08002580 vp10_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
2581 VP10_XFORM_QUANT_B);
Jingning Han2cdc1272015-10-09 09:57:42 -07002582
Geza Lore3c4b56c2016-02-16 09:54:29 +00002583 // TODO(any): Use dist_block to compute distortion
Peter de Rivaz22850492015-12-08 15:58:21 +00002584#if CONFIG_VP9_HIGHBITDEPTH
2585 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2586 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer_alloc_16);
2587 vpx_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, 32,
2588 NULL, 0, NULL, 0, bh, bh, xd->bd);
2589 } else {
2590 rec_buffer = (uint8_t *)rec_buffer_alloc_16;
2591 vpx_convolve_copy(dst, pd->dst.stride, rec_buffer, 32,
2592 NULL, 0, NULL, 0, bh, bh);
2593 }
2594#else
Jingning Han71c15602015-10-13 12:40:39 -07002595 vpx_convolve_copy(dst, pd->dst.stride, rec_buffer, 32,
2596 NULL, 0, NULL, 0, bh, bh);
Geza Lore3c4b56c2016-02-16 09:54:29 +00002597#endif // CONFIG_VP9_HIGHBITDEPTH
Jingning Han71c15602015-10-13 12:40:39 -07002598
2599 if (blk_row + (bh >> 2) > max_blocks_high ||
2600 blk_col + (bh >> 2) > max_blocks_wide) {
2601 int idx, idy;
Jingning Han71c15602015-10-13 12:40:39 -07002602 int blocks_height = VPXMIN(bh >> 2, max_blocks_high - blk_row);
2603 int blocks_width = VPXMIN(bh >> 2, max_blocks_wide - blk_col);
Geza Lore3c4b56c2016-02-16 09:54:29 +00002604 tmp = 0;
Jingning Han71c15602015-10-13 12:40:39 -07002605 for (idy = 0; idy < blocks_height; idy += 2) {
2606 for (idx = 0; idx < blocks_width; idx += 2) {
Geza Loreabd00502016-02-12 16:04:35 +00002607 const int16_t *d = diff + 4 * idy * diff_stride + 4 * idx;
Geza Lore3c4b56c2016-02-16 09:54:29 +00002608 tmp += vpx_sum_squares_2d_i16(d, diff_stride, 8);
Jingning Han71c15602015-10-13 12:40:39 -07002609 }
2610 }
2611 } else {
Geza Lore3c4b56c2016-02-16 09:54:29 +00002612 tmp = vpx_sum_squares_2d_i16(diff, diff_stride, bh);
Jingning Han71c15602015-10-13 12:40:39 -07002613 }
2614
Geza Lore3c4b56c2016-02-16 09:54:29 +00002615#if CONFIG_VP9_HIGHBITDEPTH
Debargha Mukherjee389efb22016-02-24 11:25:20 -08002616 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
2617 tmp = ROUNDZ_POWER_OF_TWO(tmp, (xd->bd - 8) * 2);
Geza Lore3c4b56c2016-02-16 09:54:29 +00002618#endif // CONFIG_VP9_HIGHBITDEPTH
Yaowu Xu5c613ea2016-03-01 09:17:17 -08002619 *bsse += tmp * 16;
Jingning Han71c15602015-10-13 12:40:39 -07002620
2621 if (p->eobs[block] > 0) {
Geza Lore432e8752016-01-22 13:57:28 +00002622 const int lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
2623#if CONFIG_VP9_HIGHBITDEPTH
2624 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2625 const int bd = xd->bd;
2626 switch (tx_size) {
2627 case TX_32X32:
2628 vp10_highbd_inv_txfm_add_32x32(dqcoeff, rec_buffer, 32,
2629 p->eobs[block], bd, tx_type);
2630 break;
2631 case TX_16X16:
2632 vp10_highbd_inv_txfm_add_16x16(dqcoeff, rec_buffer, 32,
2633 p->eobs[block], bd, tx_type);
2634 break;
2635 case TX_8X8:
2636 vp10_highbd_inv_txfm_add_8x8(dqcoeff, rec_buffer, 32,
2637 p->eobs[block], bd, tx_type);
2638 break;
2639 case TX_4X4:
2640 vp10_highbd_inv_txfm_add_4x4(dqcoeff, rec_buffer, 32,
2641 p->eobs[block], bd, tx_type, lossless);
2642 break;
2643 default:
2644 assert(0 && "Invalid transform size");
2645 break;
2646 }
2647 } else {
2648#else
2649 {
2650#endif // CONFIG_VP9_HIGHBITDEPTH
2651 switch (tx_size) {
2652 case TX_32X32:
2653 vp10_inv_txfm_add_32x32(dqcoeff, rec_buffer, 32, p->eobs[block],
2654 tx_type);
2655 break;
2656 case TX_16X16:
2657 vp10_inv_txfm_add_16x16(dqcoeff, rec_buffer, 32, p->eobs[block],
2658 tx_type);
2659 break;
2660 case TX_8X8:
2661 vp10_inv_txfm_add_8x8(dqcoeff, rec_buffer, 32, p->eobs[block],
Jingning Han71c15602015-10-13 12:40:39 -07002662 tx_type);
Geza Lore432e8752016-01-22 13:57:28 +00002663 break;
2664 case TX_4X4:
2665 vp10_inv_txfm_add_4x4(dqcoeff, rec_buffer, 32, p->eobs[block],
2666 tx_type, lossless);
2667 break;
2668 default:
2669 assert(0 && "Invalid transform size");
2670 break;
2671 }
Jingning Han71c15602015-10-13 12:40:39 -07002672 }
2673
2674 if ((bh >> 2) + blk_col > max_blocks_wide ||
2675 (bh >> 2) + blk_row > max_blocks_high) {
2676 int idx, idy;
Geza Lore3c4b56c2016-02-16 09:54:29 +00002677 unsigned int this_dist;
Jingning Han71c15602015-10-13 12:40:39 -07002678 int blocks_height = VPXMIN(bh >> 2, max_blocks_high - blk_row);
2679 int blocks_width = VPXMIN(bh >> 2, max_blocks_wide - blk_col);
Geza Lore3c4b56c2016-02-16 09:54:29 +00002680 tmp = 0;
Jingning Han71c15602015-10-13 12:40:39 -07002681 for (idy = 0; idy < blocks_height; idy += 2) {
2682 for (idx = 0; idx < blocks_width; idx += 2) {
2683 cpi->fn_ptr[BLOCK_8X8].vf(src + 4 * idy * src_stride + 4 * idx,
2684 src_stride,
2685 rec_buffer + 4 * idy * 32 + 4 * idx,
Geza Lore3c4b56c2016-02-16 09:54:29 +00002686 32, &this_dist);
2687 tmp += this_dist;
Jingning Han71c15602015-10-13 12:40:39 -07002688 }
2689 }
2690 } else {
Yaowu Xu5c613ea2016-03-01 09:17:17 -08002691 uint32_t this_dist;
2692 cpi->fn_ptr[txm_bsize].vf(src, src_stride, rec_buffer, 32, &this_dist);
2693 tmp = this_dist;
Jingning Han71c15602015-10-13 12:40:39 -07002694 }
2695 }
Yaowu Xu5c613ea2016-03-01 09:17:17 -08002696 *dist += tmp * 16;
Jingning Han2cdc1272015-10-09 09:57:42 -07002697 *rate += cost_coeffs(x, plane, block, coeff_ctx, tx_size,
2698 scan_order->scan, scan_order->neighbors, 0);
2699 *skip &= (p->eobs[block] == 0);
2700}
2701
2702static void select_tx_block(const VP10_COMP *cpi, MACROBLOCK *x,
2703 int blk_row, int blk_col, int plane, int block,
2704 TX_SIZE tx_size, BLOCK_SIZE plane_bsize,
Jingning Han2cdc1272015-10-09 09:57:42 -07002705 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
Jingning Han3edad6e2015-10-14 09:38:17 -07002706 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
Jingning Han2cdc1272015-10-09 09:57:42 -07002707 int *rate, int64_t *dist,
Jingning Han1e48f742015-10-13 11:59:49 -07002708 int64_t *bsse, int *skip,
2709 int64_t ref_best_rd, int *is_cost_valid) {
Jingning Han2cdc1272015-10-09 09:57:42 -07002710 MACROBLOCKD *const xd = &x->e_mbd;
2711 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2712 struct macroblock_plane *const p = &x->plane[plane];
2713 struct macroblockd_plane *const pd = &xd->plane[plane];
2714 int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
2715 (blk_col >> (1 - pd->subsampling_x));
2716 int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
2717 int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
2718 int64_t this_rd = INT64_MAX;
Jingning Han2cdc1272015-10-09 09:57:42 -07002719 ENTROPY_CONTEXT *pta = ta + blk_col;
2720 ENTROPY_CONTEXT *ptl = tl + blk_row;
Jingning Han3a279612015-10-12 19:20:58 -07002721 ENTROPY_CONTEXT stxa = 0, stxl = 0;
Jingning Han2cdc1272015-10-09 09:57:42 -07002722 int coeff_ctx, i;
Jingning Han3edad6e2015-10-14 09:38:17 -07002723 int ctx = txfm_partition_context(tx_above + (blk_col >> 1),
2724 tx_left + (blk_row >> 1), tx_size);
2725
Jingning Han3a279612015-10-12 19:20:58 -07002726 int64_t sum_dist = 0, sum_bsse = 0;
2727 int64_t sum_rd = INT64_MAX;
Jingning Han3edad6e2015-10-14 09:38:17 -07002728 int sum_rate = vp10_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Jingning Han3a279612015-10-12 19:20:58 -07002729 int all_skip = 1;
Jingning Han1e48f742015-10-13 11:59:49 -07002730 int tmp_eob = 0;
Jingning Hanbfeac5e2015-10-15 23:11:30 -07002731 int zero_blk_rate;
Jingning Han1e48f742015-10-13 11:59:49 -07002732
2733 if (ref_best_rd < 0) {
2734 *is_cost_valid = 0;
2735 return;
2736 }
Jingning Han2cdc1272015-10-09 09:57:42 -07002737
2738 switch (tx_size) {
2739 case TX_4X4:
Jingning Han3a279612015-10-12 19:20:58 -07002740 stxa = pta[0];
2741 stxl = ptl[0];
Jingning Han2cdc1272015-10-09 09:57:42 -07002742 break;
2743 case TX_8X8:
Jingning Han3a279612015-10-12 19:20:58 -07002744 stxa = !!*(const uint16_t *)&pta[0];
2745 stxl = !!*(const uint16_t *)&ptl[0];
Jingning Han2cdc1272015-10-09 09:57:42 -07002746 break;
2747 case TX_16X16:
Jingning Han3a279612015-10-12 19:20:58 -07002748 stxa = !!*(const uint32_t *)&pta[0];
2749 stxl = !!*(const uint32_t *)&ptl[0];
Jingning Han2cdc1272015-10-09 09:57:42 -07002750 break;
2751 case TX_32X32:
Jingning Han3a279612015-10-12 19:20:58 -07002752 stxa = !!*(const uint64_t *)&pta[0];
2753 stxl = !!*(const uint64_t *)&ptl[0];
Jingning Han2cdc1272015-10-09 09:57:42 -07002754 break;
2755 default:
2756 assert(0 && "Invalid transform size.");
2757 break;
2758 }
Jingning Han3a279612015-10-12 19:20:58 -07002759 coeff_ctx = combine_entropy_contexts(stxa, stxl);
Jingning Han2cdc1272015-10-09 09:57:42 -07002760
2761 if (xd->mb_to_bottom_edge < 0)
2762 max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
2763 if (xd->mb_to_right_edge < 0)
2764 max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
2765
2766 *rate = 0;
2767 *dist = 0;
2768 *bsse = 0;
2769 *skip = 1;
2770
2771 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
2772 return;
2773
Jingning Hanbfeac5e2015-10-15 23:11:30 -07002774 zero_blk_rate =
2775 x->token_costs[tx_size][pd->plane_type][1][0][0][coeff_ctx][EOB_TOKEN];
2776
Jingning Han1e48f742015-10-13 11:59:49 -07002777 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
2778 mbmi->inter_tx_size[tx_idx] = tx_size;
Jingning Han4c6c82a2016-02-09 17:51:49 -08002779 vp10_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
2780 plane_bsize, coeff_ctx, rate, dist, bsse, skip);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07002781
Jingning Han47c7fd92015-10-30 13:00:48 -07002782 if ((RDCOST(x->rdmult, x->rddiv, *rate, *dist) >=
2783 RDCOST(x->rdmult, x->rddiv, zero_blk_rate, *bsse) || *skip == 1) &&
Jingning Hanbfeac5e2015-10-15 23:11:30 -07002784 !xd->lossless[mbmi->segment_id]) {
2785 *rate = zero_blk_rate;
2786 *dist = *bsse;
2787 *skip = 1;
2788 x->blk_skip[plane][blk_row * max_blocks_wide + blk_col] = 1;
2789 p->eobs[block] = 0;
2790 } else {
2791 x->blk_skip[plane][blk_row * max_blocks_wide + blk_col] = 0;
2792 *skip = 0;
2793 }
2794
Jingning Han1e48f742015-10-13 11:59:49 -07002795 if (tx_size > TX_4X4)
Jingning Han3edad6e2015-10-14 09:38:17 -07002796 *rate += vp10_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
Jingning Han1e48f742015-10-13 11:59:49 -07002797 this_rd = RDCOST(x->rdmult, x->rddiv, *rate, *dist);
2798 tmp_eob = p->eobs[block];
2799 }
2800
Jingning Han2cdc1272015-10-09 09:57:42 -07002801 if (tx_size > TX_4X4) {
2802 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
Jingning Han3a279612015-10-12 19:20:58 -07002803 int bsl = b_height_log2_lookup[bsize];
Jingning Han2cdc1272015-10-09 09:57:42 -07002804 int sub_step = 1 << (2 * (tx_size - 1));
2805 int i;
Jingning Han3a279612015-10-12 19:20:58 -07002806 int this_rate;
2807 int64_t this_dist;
2808 int64_t this_bsse;
2809 int this_skip;
Jingning Han1e48f742015-10-13 11:59:49 -07002810 int this_cost_valid = 1;
2811 int64_t tmp_rd = 0;
Jingning Han3a279612015-10-12 19:20:58 -07002812
2813 --bsl;
Jingning Han236623c2015-10-26 19:39:30 -07002814 for (i = 0; i < 4 && this_cost_valid; ++i) {
Jingning Han3a279612015-10-12 19:20:58 -07002815 int offsetr = (i >> 1) << bsl;
2816 int offsetc = (i & 0x01) << bsl;
Jingning Han2cdc1272015-10-09 09:57:42 -07002817 select_tx_block(cpi, x, blk_row + offsetr, blk_col + offsetc,
2818 plane, block + i * sub_step, tx_size - 1,
Jingning Han3edad6e2015-10-14 09:38:17 -07002819 plane_bsize, ta, tl, tx_above, tx_left,
2820 &this_rate, &this_dist,
Jingning Han1e48f742015-10-13 11:59:49 -07002821 &this_bsse, &this_skip,
2822 ref_best_rd - tmp_rd, &this_cost_valid);
Jingning Han2cdc1272015-10-09 09:57:42 -07002823 sum_rate += this_rate;
2824 sum_dist += this_dist;
2825 sum_bsse += this_bsse;
2826 all_skip &= this_skip;
Peter de Rivaz2f943132016-01-05 15:35:43 +00002827 tmp_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
Jingning Han1e48f742015-10-13 11:59:49 -07002828 if (this_rd < tmp_rd)
2829 break;
Jingning Han2cdc1272015-10-09 09:57:42 -07002830 }
Jingning Han1e48f742015-10-13 11:59:49 -07002831 if (this_cost_valid)
2832 sum_rd = tmp_rd;
Jingning Han3a279612015-10-12 19:20:58 -07002833 }
2834
2835 if (this_rd < sum_rd) {
Jingning Han79fe7242015-10-23 14:27:21 -07002836 int idx, idy;
Jingning Han3a279612015-10-12 19:20:58 -07002837 for (i = 0; i < (1 << tx_size); ++i)
Jingning Han1e48f742015-10-13 11:59:49 -07002838 pta[i] = ptl[i] = !(tmp_eob == 0);
Jingning Han3edad6e2015-10-14 09:38:17 -07002839 txfm_partition_update(tx_above + (blk_col >> 1),
2840 tx_left + (blk_row >> 1), tx_size);
Jingning Han1e48f742015-10-13 11:59:49 -07002841 mbmi->inter_tx_size[tx_idx] = tx_size;
Jingning Han79fe7242015-10-23 14:27:21 -07002842
2843 for (idy = 0; idy < (1 << tx_size) / 2; ++idy)
2844 for (idx = 0; idx < (1 << tx_size) / 2; ++idx)
2845 mbmi->inter_tx_size[tx_idx + (idy << 3) + idx] = tx_size;
Jingning Han3a279612015-10-12 19:20:58 -07002846 mbmi->tx_size = tx_size;
Jingning Han236623c2015-10-26 19:39:30 -07002847 if (this_rd == INT64_MAX)
2848 *is_cost_valid = 0;
Jingning Hanbfeac5e2015-10-15 23:11:30 -07002849 x->blk_skip[plane][blk_row * max_blocks_wide + blk_col] = *skip;
Jingning Han3a279612015-10-12 19:20:58 -07002850 } else {
2851 *rate = sum_rate;
2852 *dist = sum_dist;
2853 *bsse = sum_bsse;
2854 *skip = all_skip;
Jingning Han236623c2015-10-26 19:39:30 -07002855 if (sum_rd == INT64_MAX)
2856 *is_cost_valid = 0;
Jingning Han2cdc1272015-10-09 09:57:42 -07002857 }
2858}
2859
2860static void inter_block_yrd(const VP10_COMP *cpi, MACROBLOCK *x,
2861 int *rate, int64_t *distortion, int *skippable,
2862 int64_t *sse, BLOCK_SIZE bsize,
2863 int64_t ref_best_rd) {
2864 MACROBLOCKD *const xd = &x->e_mbd;
2865 int is_cost_valid = 1;
Jingning Han1e48f742015-10-13 11:59:49 -07002866 int64_t this_rd = 0;
Jingning Han2cdc1272015-10-09 09:57:42 -07002867
2868 if (ref_best_rd < 0)
2869 is_cost_valid = 0;
2870
2871 *rate = 0;
2872 *distortion = 0;
2873 *sse = 0;
2874 *skippable = 1;
2875
2876 if (is_cost_valid) {
2877 const struct macroblockd_plane *const pd = &xd->plane[0];
2878 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
2879 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
2880 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
2881 BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[plane_bsize]];
2882 int bh = num_4x4_blocks_wide_lookup[txb_size];
2883 int idx, idy;
2884 int block = 0;
2885 int step = 1 << (max_txsize_lookup[plane_bsize] * 2);
2886 ENTROPY_CONTEXT ctxa[16], ctxl[16];
Jingning Han3edad6e2015-10-14 09:38:17 -07002887 TXFM_CONTEXT tx_above[8], tx_left[8];
Jingning Han2cdc1272015-10-09 09:57:42 -07002888
2889 int pnrate = 0, pnskip = 1;
2890 int64_t pndist = 0, pnsse = 0;
2891
2892 vp10_get_entropy_contexts(bsize, TX_4X4, pd, ctxa, ctxl);
Jingning Han3edad6e2015-10-14 09:38:17 -07002893 memcpy(tx_above, xd->above_txfm_context,
2894 sizeof(TXFM_CONTEXT) * (mi_width >> 1));
2895 memcpy(tx_left, xd->left_txfm_context,
2896 sizeof(TXFM_CONTEXT) * (mi_height >> 1));
Jingning Han2cdc1272015-10-09 09:57:42 -07002897
2898 for (idy = 0; idy < mi_height; idy += bh) {
2899 for (idx = 0; idx < mi_width; idx += bh) {
2900 select_tx_block(cpi, x, idy, idx, 0, block,
Jingning Han3a279612015-10-12 19:20:58 -07002901 max_txsize_lookup[plane_bsize], plane_bsize,
Jingning Han3edad6e2015-10-14 09:38:17 -07002902 ctxa, ctxl, tx_above, tx_left,
2903 &pnrate, &pndist, &pnsse, &pnskip,
Jingning Han1e48f742015-10-13 11:59:49 -07002904 ref_best_rd - this_rd, &is_cost_valid);
Jingning Han2cdc1272015-10-09 09:57:42 -07002905 *rate += pnrate;
2906 *distortion += pndist;
2907 *sse += pnsse;
2908 *skippable &= pnskip;
Jingning Han1e48f742015-10-13 11:59:49 -07002909 this_rd += VPXMIN(RDCOST(x->rdmult, x->rddiv, pnrate, pndist),
2910 RDCOST(x->rdmult, x->rddiv, 0, pnsse));
Jingning Han2cdc1272015-10-09 09:57:42 -07002911 block += step;
2912 }
2913 }
2914 }
2915
2916 this_rd = VPXMIN(RDCOST(x->rdmult, x->rddiv, *rate, *distortion),
2917 RDCOST(x->rdmult, x->rddiv, 0, *sse));
2918 if (this_rd > ref_best_rd)
2919 is_cost_valid = 0;
2920
2921 if (!is_cost_valid) {
2922 // reset cost value
2923 *rate = INT_MAX;
2924 *distortion = INT64_MAX;
2925 *sse = INT64_MAX;
2926 *skippable = 0;
2927 }
2928}
2929
Jingning Han4b594d32015-11-02 12:05:47 -08002930static void select_tx_type_yrd(const VP10_COMP *cpi, MACROBLOCK *x,
2931 int *rate, int64_t *distortion, int *skippable,
2932 int64_t *sse, BLOCK_SIZE bsize,
2933 int64_t ref_best_rd) {
2934 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
2935 const VP10_COMMON *const cm = &cpi->common;
2936 MACROBLOCKD *const xd = &x->e_mbd;
2937 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2938 int64_t rd = INT64_MAX;
2939 int64_t best_rd = INT64_MAX;
2940 TX_TYPE tx_type, best_tx_type = DCT_DCT;
Jingning Han4b594d32015-11-02 12:05:47 -08002941 const int is_inter = is_inter_block(mbmi);
2942 vpx_prob skip_prob = vp10_get_skip_prob(cm, xd);
2943 int s0 = vp10_cost_bit(skip_prob, 0);
2944 int s1 = vp10_cost_bit(skip_prob, 1);
Jingning Han696ee002015-11-03 08:56:47 -08002945 TX_SIZE best_tx_size[64];
Jingning Han493d0232015-11-03 12:59:24 -08002946 TX_SIZE best_tx = TX_SIZES;
2947 uint8_t best_blk_skip[256];
2948 const int n4 = 1 << (num_pels_log2_lookup[bsize] - 4);
Jingning Han696ee002015-11-03 08:56:47 -08002949 int idx, idy;
Sarah Parker2ca7d422016-03-01 10:12:13 -08002950 int prune = 0;
Julia Robson9fe188e2016-01-21 17:14:29 +00002951#if CONFIG_EXT_TX
2952 int ext_tx_set = get_ext_tx_set(max_tx_size, bsize, is_inter);
Sarah Parker2ca7d422016-03-01 10:12:13 -08002953#endif // CONFIG_EXT_TX
2954
2955 if (is_inter && cpi->sf.tx_type_search > 0)
2956 prune = prune_tx_types(cpi, bsize, x, xd);
Jingning Han4b594d32015-11-02 12:05:47 -08002957
2958 *distortion = INT64_MAX;
2959 *rate = INT_MAX;
2960 *skippable = 0;
2961 *sse = INT64_MAX;
2962
2963 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
2964 int this_rate = 0;
2965 int this_skip = 1;
2966 int64_t this_dist = 0;
2967 int64_t this_sse = 0;
Julia Robson9fe188e2016-01-21 17:14:29 +00002968#if CONFIG_EXT_TX
Jingning Han4b594d32015-11-02 12:05:47 -08002969 if (is_inter) {
2970 if (!ext_tx_used_inter[ext_tx_set][tx_type])
2971 continue;
Sarah Parker2ca7d422016-03-01 10:12:13 -08002972 if (cpi->sf.tx_type_search > 0) {
2973 if (!do_tx_type_search(tx_type, prune))
2974 continue;
2975 } else if (ext_tx_set == 1 &&
2976 tx_type >= DST_ADST && tx_type < IDTX &&
2977 best_tx_type == DCT_DCT) {
2978 tx_type = IDTX - 1;
2979 continue;
2980 }
Jingning Han4b594d32015-11-02 12:05:47 -08002981 } else {
hui sud894d342015-11-18 11:24:26 -08002982 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
Yaowu Xu0367f322016-01-11 10:27:35 -08002983 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode])
hui sud894d342015-11-18 11:24:26 -08002984 continue;
2985 }
Jingning Han4b594d32015-11-02 12:05:47 -08002986 if (!ext_tx_used_intra[ext_tx_set][tx_type])
2987 continue;
Sarah Parker2ca7d422016-03-01 10:12:13 -08002988 if (ext_tx_set == 1 &&
2989 tx_type >= DST_ADST && tx_type < IDTX &&
2990 best_tx_type == DCT_DCT) {
2991 tx_type = IDTX - 1;
2992 break;
2993 }
Jingning Han4b594d32015-11-02 12:05:47 -08002994 }
2995
2996 mbmi->tx_type = tx_type;
2997
Jingning Han4b594d32015-11-02 12:05:47 -08002998 inter_block_yrd(cpi, x, &this_rate, &this_dist, &this_skip, &this_sse,
2999 bsize, ref_best_rd);
3000
3001 if (get_ext_tx_types(max_tx_size, bsize, is_inter) > 1 &&
3002 !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
3003 this_rate != INT_MAX) {
3004 if (is_inter) {
3005 if (ext_tx_set > 0)
3006 this_rate += cpi->inter_tx_type_costs[ext_tx_set]
Jingning Han696ee002015-11-03 08:56:47 -08003007 [max_tx_size][mbmi->tx_type];
Jingning Han4b594d32015-11-02 12:05:47 -08003008 } else {
hui sud894d342015-11-18 11:24:26 -08003009 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Jingning Han696ee002015-11-03 08:56:47 -08003010 this_rate += cpi->intra_tx_type_costs[ext_tx_set][max_tx_size]
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08003011 [mbmi->mode][mbmi->tx_type];
Jingning Han4b594d32015-11-02 12:05:47 -08003012 }
3013 }
Julia Robson9fe188e2016-01-21 17:14:29 +00003014#else // CONFIG_EXT_TX
Jingning Han5c772f32016-02-10 11:33:37 -08003015 if (max_tx_size >= TX_32X32 && tx_type != DCT_DCT)
Julia Robson9fe188e2016-01-21 17:14:29 +00003016 continue;
Jingning Han5c772f32016-02-10 11:33:37 -08003017
Julia Robson9fe188e2016-01-21 17:14:29 +00003018 mbmi->tx_type = tx_type;
3019
3020 inter_block_yrd(cpi, x, &this_rate, &this_dist, &this_skip, &this_sse,
3021 bsize, ref_best_rd);
3022
3023 if (max_tx_size < TX_32X32 &&
3024 !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
3025 this_rate != INT_MAX) {
Sarah Parker2ca7d422016-03-01 10:12:13 -08003026 if (is_inter) {
Julia Robson9fe188e2016-01-21 17:14:29 +00003027 this_rate += cpi->inter_tx_type_costs[max_tx_size][mbmi->tx_type];
Sarah Parker2ca7d422016-03-01 10:12:13 -08003028 if (cpi->sf.tx_type_search > 0 && !do_tx_type_search(tx_type, prune))
3029 continue;
3030 } else {
Julia Robson9fe188e2016-01-21 17:14:29 +00003031 this_rate += cpi->intra_tx_type_costs[max_tx_size]
3032 [intra_mode_to_tx_type_context[mbmi->mode]]
3033 [mbmi->tx_type];
Sarah Parker2ca7d422016-03-01 10:12:13 -08003034 }
Julia Robson9fe188e2016-01-21 17:14:29 +00003035 }
3036#endif // CONFIG_EXT_TX
Jingning Han4b594d32015-11-02 12:05:47 -08003037
3038 if (this_rate == INT_MAX)
3039 continue;
3040
3041 if (this_skip)
3042 rd = RDCOST(x->rdmult, x->rddiv, s1, this_sse);
3043 else
3044 rd = RDCOST(x->rdmult, x->rddiv, this_rate + s0, this_dist);
3045
3046 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] && !this_skip)
3047 rd = VPXMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, this_sse));
3048
Jingning Han5c772f32016-02-10 11:33:37 -08003049 if (rd < (is_inter && best_tx_type == DCT_DCT ? ext_tx_th : 1) * best_rd) {
Jingning Han4b594d32015-11-02 12:05:47 -08003050 best_rd = rd;
3051 *distortion = this_dist;
3052 *rate = this_rate;
3053 *skippable = this_skip;
3054 *sse = this_sse;
3055 best_tx_type = mbmi->tx_type;
Jingning Han493d0232015-11-03 12:59:24 -08003056 best_tx = mbmi->tx_size;
3057 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
Jingning Han696ee002015-11-03 08:56:47 -08003058 for (idy = 0; idy < xd->n8_h; ++idy)
3059 for (idx = 0; idx < xd->n8_w; ++idx)
3060 best_tx_size[idy * 8 + idx] = mbmi->inter_tx_size[idy * 8 + idx];
Jingning Han4b594d32015-11-02 12:05:47 -08003061 }
3062 }
3063
3064 mbmi->tx_type = best_tx_type;
Jingning Han696ee002015-11-03 08:56:47 -08003065 for (idy = 0; idy < xd->n8_h; ++idy)
3066 for (idx = 0; idx < xd->n8_w; ++idx)
3067 mbmi->inter_tx_size[idy * 8 + idx] = best_tx_size[idy * 8 + idx];
Jingning Han493d0232015-11-03 12:59:24 -08003068 mbmi->tx_size = best_tx;
3069 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
Jingning Han4b594d32015-11-02 12:05:47 -08003070}
Jingning Han4b594d32015-11-02 12:05:47 -08003071
Jingning Hana8dad552015-10-08 16:46:10 -07003072static void tx_block_rd(const VP10_COMP *cpi, MACROBLOCK *x,
3073 int blk_row, int blk_col, int plane, int block,
3074 TX_SIZE tx_size, BLOCK_SIZE plane_bsize,
3075 ENTROPY_CONTEXT *above_ctx, ENTROPY_CONTEXT *left_ctx,
3076 int *rate, int64_t *dist, int64_t *bsse, int *skip) {
3077 MACROBLOCKD *const xd = &x->e_mbd;
3078 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Jingning Han2cdc1272015-10-09 09:57:42 -07003079 struct macroblock_plane *const p = &x->plane[plane];
Jingning Hana8dad552015-10-08 16:46:10 -07003080 struct macroblockd_plane *const pd = &xd->plane[plane];
Jingning Han2cdc1272015-10-09 09:57:42 -07003081 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
Jingning Hana8dad552015-10-08 16:46:10 -07003082 int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
3083 (blk_col >> (1 - pd->subsampling_x));
3084 TX_SIZE plane_tx_size = plane ?
Jingning Han2cdc1272015-10-09 09:57:42 -07003085 get_uv_tx_size_impl(mbmi->inter_tx_size[tx_idx], bsize,
3086 0, 0) :
Jingning Hana8dad552015-10-08 16:46:10 -07003087 mbmi->inter_tx_size[tx_idx];
3088
3089 int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
3090 int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
3091
3092 if (xd->mb_to_bottom_edge < 0)
3093 max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
3094 if (xd->mb_to_right_edge < 0)
3095 max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
3096
3097 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
3098 return;
3099
3100 if (tx_size == plane_tx_size) {
Jingning Han2cdc1272015-10-09 09:57:42 -07003101 int coeff_ctx, i;
Jingning Hana8dad552015-10-08 16:46:10 -07003102 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
Jingning Han2cdc1272015-10-09 09:57:42 -07003103 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
Jingning Hana8dad552015-10-08 16:46:10 -07003104 switch (tx_size) {
3105 case TX_4X4:
3106 break;
3107 case TX_8X8:
3108 ta[0] = !!*(const uint16_t *)&ta[0];
3109 tl[0] = !!*(const uint16_t *)&tl[0];
3110 break;
3111 case TX_16X16:
3112 ta[0] = !!*(const uint32_t *)&ta[0];
3113 tl[0] = !!*(const uint32_t *)&tl[0];
3114 break;
3115 case TX_32X32:
3116 ta[0] = !!*(const uint64_t *)&ta[0];
3117 tl[0] = !!*(const uint64_t *)&tl[0];
3118 break;
3119 default:
3120 assert(0 && "Invalid transform size.");
3121 break;
3122 }
Jingning Han2cdc1272015-10-09 09:57:42 -07003123 coeff_ctx = combine_entropy_contexts(ta[0], tl[0]);
Jingning Han4c6c82a2016-02-09 17:51:49 -08003124 vp10_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
3125 plane_bsize, coeff_ctx, rate, dist, bsse, skip);
Jingning Hana8dad552015-10-08 16:46:10 -07003126 for (i = 0; i < (1 << tx_size); ++i) {
Jingning Han2cdc1272015-10-09 09:57:42 -07003127 ta[i] = !(p->eobs[block] == 0);
3128 tl[i] = !(p->eobs[block] == 0);
Jingning Hana8dad552015-10-08 16:46:10 -07003129 }
Jingning Hana8dad552015-10-08 16:46:10 -07003130 } else {
Jingning Hana8dad552015-10-08 16:46:10 -07003131 int bsl = b_width_log2_lookup[bsize];
3132 int step = 1 << (2 * (tx_size - 1));
3133 int i;
3134
3135 assert(bsl > 0);
3136 --bsl;
3137
3138 for (i = 0; i < 4; ++i) {
3139 int offsetr = (i >> 1) << bsl;
3140 int offsetc = (i & 0x01) << bsl;
3141 tx_block_rd(cpi, x, blk_row + offsetr, blk_col + offsetc, plane,
3142 block + i * step, tx_size - 1, plane_bsize,
3143 above_ctx, left_ctx, rate, dist, bsse, skip);
3144 }
3145 }
3146}
3147
3148// Return value 0: early termination triggered, no valid rd cost available;
3149// 1: rd cost values are valid.
3150static int inter_block_uvrd(const VP10_COMP *cpi, MACROBLOCK *x,
3151 int *rate, int64_t *distortion, int *skippable,
3152 int64_t *sse, BLOCK_SIZE bsize,
3153 int64_t ref_best_rd) {
3154 MACROBLOCKD *const xd = &x->e_mbd;
3155 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3156 int plane;
3157 int is_cost_valid = 1;
3158 int64_t this_rd;
3159
3160 if (ref_best_rd < 0)
3161 is_cost_valid = 0;
3162
3163 if (is_inter_block(mbmi) && is_cost_valid) {
3164 int plane;
3165 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
3166 vp10_subtract_plane(x, bsize, plane);
3167 }
3168
3169 *rate = 0;
3170 *distortion = 0;
3171 *sse = 0;
3172 *skippable = 1;
3173
3174 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
3175 const struct macroblockd_plane *const pd = &xd->plane[plane];
3176 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
3177 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
3178 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
3179 BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[plane_bsize]];
3180 int bh = num_4x4_blocks_wide_lookup[txb_size];
3181 int idx, idy;
3182 int block = 0;
3183 int step = 1 << (max_txsize_lookup[plane_bsize] * 2);
3184 int pnrate = 0, pnskip = 1;
3185 int64_t pndist = 0, pnsse = 0;
3186 ENTROPY_CONTEXT ta[16], tl[16];
3187
3188 vp10_get_entropy_contexts(bsize, TX_4X4, pd, ta, tl);
3189
3190 for (idy = 0; idy < mi_height; idy += bh) {
3191 for (idx = 0; idx < mi_width; idx += bh) {
3192 tx_block_rd(cpi, x, idy, idx, plane, block,
3193 max_txsize_lookup[plane_bsize], plane_bsize, ta, tl,
3194 &pnrate, &pndist, &pnsse, &pnskip);
3195 block += step;
3196 }
3197 }
3198
3199 if (pnrate == INT_MAX) {
3200 is_cost_valid = 0;
3201 break;
3202 }
3203
3204 *rate += pnrate;
3205 *distortion += pndist;
3206 *sse += pnsse;
3207 *skippable &= pnskip;
3208
3209 this_rd = VPXMIN(RDCOST(x->rdmult, x->rddiv, *rate, *distortion),
3210 RDCOST(x->rdmult, x->rddiv, 0, *sse));
3211
3212 if (this_rd > ref_best_rd) {
3213 is_cost_valid = 0;
3214 break;
3215 }
3216 }
3217
3218 if (!is_cost_valid) {
3219 // reset cost value
3220 *rate = INT_MAX;
3221 *distortion = INT64_MAX;
3222 *sse = INT64_MAX;
3223 *skippable = 0;
3224 }
3225
3226 return is_cost_valid;
3227}
3228#endif
3229
Jingning Han3ee6db62015-08-05 19:00:31 -07003230// Return value 0: early termination triggered, no valid rd cost available;
3231// 1: rd cost values are valid.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003232static int super_block_uvrd(const VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003233 int *rate, int64_t *distortion, int *skippable,
3234 int64_t *sse, BLOCK_SIZE bsize,
3235 int64_t ref_best_rd) {
3236 MACROBLOCKD *const xd = &x->e_mbd;
3237 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3238 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
3239 int plane;
3240 int pnrate = 0, pnskip = 1;
3241 int64_t pndist = 0, pnsse = 0;
3242 int is_cost_valid = 1;
3243
3244 if (ref_best_rd < 0)
3245 is_cost_valid = 0;
3246
3247 if (is_inter_block(mbmi) && is_cost_valid) {
3248 int plane;
3249 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
3250 vp10_subtract_plane(x, bsize, plane);
3251 }
3252
3253 *rate = 0;
3254 *distortion = 0;
3255 *sse = 0;
3256 *skippable = 1;
3257
3258 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
Jingning Han71c15602015-10-13 12:40:39 -07003259 txfm_rd_in_plane(x,
Jingning Han71c15602015-10-13 12:40:39 -07003260 cpi,
Jingning Han71c15602015-10-13 12:40:39 -07003261 &pnrate, &pndist, &pnskip, &pnsse,
Jingning Han3ee6db62015-08-05 19:00:31 -07003262 ref_best_rd, plane, bsize, uv_tx_size,
3263 cpi->sf.use_fast_coef_costing);
3264 if (pnrate == INT_MAX) {
3265 is_cost_valid = 0;
3266 break;
3267 }
3268 *rate += pnrate;
3269 *distortion += pndist;
3270 *sse += pnsse;
3271 *skippable &= pnskip;
3272 }
3273
3274 if (!is_cost_valid) {
3275 // reset cost value
3276 *rate = INT_MAX;
3277 *distortion = INT64_MAX;
3278 *sse = INT64_MAX;
3279 *skippable = 0;
3280 }
3281
3282 return is_cost_valid;
3283}
3284
hui sube3559b2015-10-07 09:29:02 -07003285#if CONFIG_EXT_INTRA
3286// Return 1 if an ext intra mode is selected; return 0 otherwise.
3287static int rd_pick_ext_intra_sbuv(VP10_COMP *cpi, MACROBLOCK *x,
3288 PICK_MODE_CONTEXT *ctx,
3289 int *rate, int *rate_tokenonly,
3290 int64_t *distortion, int *skippable,
3291 BLOCK_SIZE bsize, int64_t *best_rd) {
3292 MACROBLOCKD *const xd = &x->e_mbd;
3293 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
3294 int ext_intra_selected_flag = 0;
3295 int this_rate_tokenonly, this_rate, s;
hui su4aa50c12015-11-10 12:09:59 -08003296 int64_t this_distortion, this_sse, this_rd;
hui sube3559b2015-10-07 09:29:02 -07003297 EXT_INTRA_MODE mode;
hui sube3559b2015-10-07 09:29:02 -07003298 EXT_INTRA_MODE_INFO ext_intra_mode_info;
3299
3300 vp10_zero(ext_intra_mode_info);
3301 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 1;
3302 mbmi->uv_mode = DC_PRED;
3303
hui su4aa50c12015-11-10 12:09:59 -08003304 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
3305 mbmi->ext_intra_mode_info.ext_intra_mode[1] = mode;
3306 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3307 &this_distortion, &s, &this_sse, bsize, *best_rd))
3308 continue;
hui sube3559b2015-10-07 09:29:02 -07003309
hui su4aa50c12015-11-10 12:09:59 -08003310 this_rate = this_rate_tokenonly +
3311 vp10_cost_bit(cpi->common.fc->ext_intra_probs[1], 1) +
3312 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
3313 write_uniform_cost(FILTER_INTRA_MODES, mode);
3314 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3315 if (this_rd < *best_rd) {
3316 *best_rd = this_rd;
3317 *rate = this_rate;
3318 *rate_tokenonly = this_rate_tokenonly;
3319 *distortion = this_distortion;
3320 *skippable = s;
3321 ext_intra_mode_info = mbmi->ext_intra_mode_info;
3322 ext_intra_selected_flag = 1;
3323 if (!x->select_tx_size)
3324 swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE);
hui sube3559b2015-10-07 09:29:02 -07003325 }
3326 }
3327
hui sube3559b2015-10-07 09:29:02 -07003328
3329 if (ext_intra_selected_flag) {
3330 mbmi->uv_mode = DC_PRED;
3331 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
3332 ext_intra_mode_info.use_ext_intra_mode[1];
3333 mbmi->ext_intra_mode_info.ext_intra_mode[1] =
3334 ext_intra_mode_info.ext_intra_mode[1];
hui sube3559b2015-10-07 09:29:02 -07003335 return 1;
3336 } else {
3337 return 0;
3338 }
3339}
hui su4aa50c12015-11-10 12:09:59 -08003340
hui su5a7c8d82016-02-08 10:39:17 -08003341static void pick_intra_angle_routine_sbuv(VP10_COMP *cpi, MACROBLOCK *x,
3342 int *rate, int *rate_tokenonly,
3343 int64_t *distortion, int *skippable,
3344 int *best_angle_delta,
3345 BLOCK_SIZE bsize, int rate_overhead,
3346 int64_t *best_rd) {
3347 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
3348 int this_rate_tokenonly, this_rate, s;
3349 int64_t this_distortion, this_sse, this_rd;
3350
3351 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3352 &this_distortion, &s, &this_sse, bsize, *best_rd))
3353 return;
3354
3355 this_rate = this_rate_tokenonly + rate_overhead;
3356 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3357 if (this_rd < *best_rd) {
3358 *best_rd = this_rd;
3359 *best_angle_delta = mbmi->angle_delta[1];
3360 *rate = this_rate;
3361 *rate_tokenonly = this_rate_tokenonly;
3362 *distortion = this_distortion;
3363 *skippable = s;
3364 }
3365}
3366
hui su4aa50c12015-11-10 12:09:59 -08003367static int rd_pick_intra_angle_sbuv(VP10_COMP *cpi, MACROBLOCK *x,
3368 PICK_MODE_CONTEXT *ctx,
3369 int *rate, int *rate_tokenonly,
3370 int64_t *distortion, int *skippable,
3371 BLOCK_SIZE bsize, int rate_overhead,
3372 int64_t best_rd) {
3373 MACROBLOCKD *const xd = &x->e_mbd;
3374 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
3375 int this_rate_tokenonly, this_rate, s;
3376 int64_t this_distortion, this_sse, this_rd;
3377 int angle_delta, best_angle_delta = 0;
3378 const double rd_adjust = 1.2;
3379
3380 (void)ctx;
3381 *rate_tokenonly = INT_MAX;
3382 if (ANGLE_FAST_SEARCH) {
3383 int deltas_level1[3] = {0, -2, 2};
3384 int deltas_level2[3][2] = {
3385 {-1, 1}, {-3, -1}, {1, 3},
3386 };
3387 const int level1 = 3, level2 = 2;
3388 int i, j, best_i = -1;
3389
3390 for (i = 0; i < level1; ++i) {
Yaowu Xu28eb7842016-03-07 16:23:26 -08003391 int64_t tmp_best_rd;
hui su4aa50c12015-11-10 12:09:59 -08003392 mbmi->angle_delta[1] = deltas_level1[i];
Yaowu Xu28eb7842016-03-07 16:23:26 -08003393 tmp_best_rd = (i == 0 && best_rd < INT64_MAX) ?
3394 (int64_t)(best_rd * rd_adjust) : best_rd;
3395 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion,
3396 &s, &this_sse, bsize, tmp_best_rd)) {
hui su4aa50c12015-11-10 12:09:59 -08003397 if (i == 0)
3398 break;
3399 else
3400 continue;
3401 }
3402 this_rate = this_rate_tokenonly + rate_overhead;
3403 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3404 if (i == 0 && best_rd < INT64_MAX && this_rd > best_rd * rd_adjust)
3405 break;
3406 if (this_rd < best_rd) {
3407 best_i = i;
3408 best_rd = this_rd;
3409 best_angle_delta = mbmi->angle_delta[1];
3410 *rate = this_rate;
3411 *rate_tokenonly = this_rate_tokenonly;
3412 *distortion = this_distortion;
3413 *skippable = s;
3414 }
3415 }
3416
3417 if (best_i >= 0) {
3418 for (j = 0; j < level2; ++j) {
3419 mbmi->angle_delta[1] = deltas_level2[best_i][j];
hui su5a7c8d82016-02-08 10:39:17 -08003420 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly,
3421 distortion, skippable,
3422 &best_angle_delta, bsize,
3423 rate_overhead, &best_rd);
hui su4aa50c12015-11-10 12:09:59 -08003424 }
3425 }
3426 } else {
3427 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
3428 ++angle_delta) {
3429 mbmi->angle_delta[1] = angle_delta;
hui su5a7c8d82016-02-08 10:39:17 -08003430 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly,
3431 distortion, skippable,
3432 &best_angle_delta, bsize,
3433 rate_overhead, &best_rd);
hui su4aa50c12015-11-10 12:09:59 -08003434 }
3435 }
3436
3437 mbmi->angle_delta[1] = best_angle_delta;
3438 if (*rate_tokenonly != INT_MAX)
3439 super_block_uvrd(cpi, x, &this_rate_tokenonly,
3440 &this_distortion, &s, &this_sse, bsize, INT_MAX);
3441 return *rate_tokenonly != INT_MAX;
3442}
hui sube3559b2015-10-07 09:29:02 -07003443#endif // CONFIG_EXT_INTRA
3444
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003445static int64_t rd_pick_intra_sbuv_mode(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003446 PICK_MODE_CONTEXT *ctx,
3447 int *rate, int *rate_tokenonly,
3448 int64_t *distortion, int *skippable,
3449 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
3450 MACROBLOCKD *xd = &x->e_mbd;
hui sube3559b2015-10-07 09:29:02 -07003451 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Jingning Han3ee6db62015-08-05 19:00:31 -07003452 PREDICTION_MODE mode;
3453 PREDICTION_MODE mode_selected = DC_PRED;
3454 int64_t best_rd = INT64_MAX, this_rd;
3455 int this_rate_tokenonly, this_rate, s;
3456 int64_t this_distortion, this_sse;
hui sube3559b2015-10-07 09:29:02 -07003457#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08003458 int is_directional_mode, rate_overhead, best_angle_delta = 0;
hui sube3559b2015-10-07 09:29:02 -07003459 EXT_INTRA_MODE_INFO ext_intra_mode_info;
Jingning Han3ee6db62015-08-05 19:00:31 -07003460
hui sube3559b2015-10-07 09:29:02 -07003461 ext_intra_mode_info.use_ext_intra_mode[1] = 0;
3462 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
3463#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07003464 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
hui suc93e5cc2015-12-07 18:18:57 -08003465 xd->mi[0]->mbmi.palette_mode_info.palette_size[1] = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07003466 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
3467 if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode)))
3468 continue;
3469
hui sube3559b2015-10-07 09:29:02 -07003470 mbmi->uv_mode = mode;
hui su4aa50c12015-11-10 12:09:59 -08003471#if CONFIG_EXT_INTRA
3472 is_directional_mode = (mode != DC_PRED && mode != TM_PRED);
3473 rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
3474 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
3475 mbmi->angle_delta[1] = 0;
3476 if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode) {
3477 if (!rd_pick_intra_angle_sbuv(cpi, x, ctx, &this_rate,
3478 &this_rate_tokenonly, &this_distortion, &s,
3479 bsize, rate_overhead, best_rd))
3480 continue;
3481 } else {
3482 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3483 &this_distortion, &s, &this_sse, bsize, best_rd))
3484 continue;
3485 }
3486 this_rate = this_rate_tokenonly +
3487 cpi->intra_uv_mode_cost[mbmi->mode][mode];
3488 if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode)
3489 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
3490 MAX_ANGLE_DELTAS +
3491 mbmi->angle_delta[1]);
3492 if (mode == DC_PRED && 0)
3493 this_rate += vp10_cost_bit(cpi->common.fc->ext_intra_probs[1], 0);
3494#else
Jingning Han3ee6db62015-08-05 19:00:31 -07003495 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
3496 &this_distortion, &s, &this_sse, bsize, best_rd))
3497 continue;
hui su6ab6ac42015-11-06 13:56:51 -08003498 this_rate = this_rate_tokenonly +
3499 cpi->intra_uv_mode_cost[xd->mi[0]->mbmi.mode][mode];
hui sube3559b2015-10-07 09:29:02 -07003500#endif // CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08003501
Jingning Han3ee6db62015-08-05 19:00:31 -07003502 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3503
3504 if (this_rd < best_rd) {
3505 mode_selected = mode;
hui su4aa50c12015-11-10 12:09:59 -08003506#if CONFIG_EXT_INTRA
3507 best_angle_delta = mbmi->angle_delta[1];
3508#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07003509 best_rd = this_rd;
3510 *rate = this_rate;
3511 *rate_tokenonly = this_rate_tokenonly;
3512 *distortion = this_distortion;
3513 *skippable = s;
3514 if (!x->select_tx_size)
3515 swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE);
3516 }
3517 }
3518
hui sube3559b2015-10-07 09:29:02 -07003519#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08003520 if (mbmi->sb_type >= BLOCK_8X8 && ALLOW_FILTER_INTRA_MODES) {
hui sube3559b2015-10-07 09:29:02 -07003521 if (rd_pick_ext_intra_sbuv(cpi, x, ctx, rate, rate_tokenonly, distortion,
3522 skippable, bsize, &best_rd)) {
3523 mode_selected = mbmi->uv_mode;
3524 ext_intra_mode_info = mbmi->ext_intra_mode_info;
3525 }
3526 }
3527
3528 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
3529 ext_intra_mode_info.use_ext_intra_mode[1];
3530 if (ext_intra_mode_info.use_ext_intra_mode[1])
3531 mbmi->ext_intra_mode_info.ext_intra_mode[1] =
3532 ext_intra_mode_info.ext_intra_mode[1];
hui su4aa50c12015-11-10 12:09:59 -08003533 mbmi->angle_delta[1] = best_angle_delta;
hui sube3559b2015-10-07 09:29:02 -07003534#endif // CONFIG_EXT_INTRA
3535 mbmi->uv_mode = mode_selected;
Jingning Han3ee6db62015-08-05 19:00:31 -07003536 return best_rd;
3537}
3538
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003539static int64_t rd_sbuv_dcpred(const VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003540 int *rate, int *rate_tokenonly,
3541 int64_t *distortion, int *skippable,
3542 BLOCK_SIZE bsize) {
Jingning Han3ee6db62015-08-05 19:00:31 -07003543 int64_t unused;
3544
3545 x->e_mbd.mi[0]->mbmi.uv_mode = DC_PRED;
3546 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
3547 super_block_uvrd(cpi, x, rate_tokenonly, distortion,
3548 skippable, &unused, bsize, INT64_MAX);
hui su6ab6ac42015-11-06 13:56:51 -08003549 *rate = *rate_tokenonly +
3550 cpi->intra_uv_mode_cost[x->e_mbd.mi[0]->mbmi.mode][DC_PRED];
Jingning Han3ee6db62015-08-05 19:00:31 -07003551 return RDCOST(x->rdmult, x->rddiv, *rate, *distortion);
3552}
3553
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003554static void choose_intra_uv_mode(VP10_COMP *cpi, MACROBLOCK *const x,
Jingning Han3ee6db62015-08-05 19:00:31 -07003555 PICK_MODE_CONTEXT *ctx,
3556 BLOCK_SIZE bsize, TX_SIZE max_tx_size,
3557 int *rate_uv, int *rate_uv_tokenonly,
3558 int64_t *dist_uv, int *skip_uv,
3559 PREDICTION_MODE *mode_uv) {
3560 // Use an estimated rd for uv_intra based on DC_PRED if the
3561 // appropriate speed flag is set.
3562 if (cpi->sf.use_uv_intra_rd_estimate) {
3563 rd_sbuv_dcpred(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv,
3564 skip_uv, bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize);
3565 // Else do a proper rd search for each possible transform size that may
3566 // be considered in the main rd loop.
3567 } else {
3568 rd_pick_intra_sbuv_mode(cpi, x, ctx,
3569 rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
3570 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
3571 }
3572 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
3573}
3574
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003575static int cost_mv_ref(const VP10_COMP *cpi, PREDICTION_MODE mode,
Yue Chen1ac85872016-01-07 15:13:52 -08003576#if CONFIG_REF_MV && CONFIG_EXT_INTER
3577 int is_compound,
3578#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003579 int16_t mode_context) {
Jingning Han1dc18072015-12-02 10:59:01 -08003580#if CONFIG_REF_MV
3581 int mode_cost = 0;
Yue Chen968bbc72016-01-19 16:45:45 -08003582#if CONFIG_EXT_INTER
3583 int16_t mode_ctx = is_compound ? mode_context :
3584 (mode_context & NEWMV_CTX_MASK);
3585#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003586 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
Yue Chen968bbc72016-01-19 16:45:45 -08003587#endif // CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003588 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
Jingning Han1dc18072015-12-02 10:59:01 -08003589
3590 assert(is_inter_mode(mode));
3591
Yue Chen1ac85872016-01-07 15:13:52 -08003592#if CONFIG_EXT_INTER
Yue Chen968bbc72016-01-19 16:45:45 -08003593 if (is_compound) {
3594 return cpi->inter_compound_mode_cost[mode_context]
3595 [INTER_COMPOUND_OFFSET(mode)];
3596 } else {
3597 if (mode == NEWMV || mode == NEWFROMNEARMV) {
Yue Chen1ac85872016-01-07 15:13:52 -08003598#else
Jingning Han1dc18072015-12-02 10:59:01 -08003599 if (mode == NEWMV) {
Yue Chen1ac85872016-01-07 15:13:52 -08003600#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08003601 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
Yue Chen1ac85872016-01-07 15:13:52 -08003602#if CONFIG_EXT_INTER
3603 if (!is_compound)
3604 mode_cost += cpi->new2mv_mode_cost[mode == NEWFROMNEARMV];
3605#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08003606 return mode_cost;
3607 } else {
3608 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
3609 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003610
3611 if (is_all_zero_mv)
3612 return mode_cost;
3613
Jingning Han1dc18072015-12-02 10:59:01 -08003614 if (mode == ZEROMV) {
3615 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
3616 return mode_cost;
3617 } else {
3618 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003619 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
Jingning Han387a10e2015-12-09 09:07:39 -08003620
3621 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET))
3622 mode_ctx = 6;
3623 if (mode_context & (1 << SKIP_NEARMV_OFFSET))
3624 mode_ctx = 7;
3625 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET))
3626 mode_ctx = 8;
3627
Jingning Han1dc18072015-12-02 10:59:01 -08003628 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
3629 return mode_cost;
3630 }
3631 }
Yue Chen968bbc72016-01-19 16:45:45 -08003632#if CONFIG_EXT_INTER
3633 }
3634#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08003635#else
Jingning Han3ee6db62015-08-05 19:00:31 -07003636 assert(is_inter_mode(mode));
Yue Chen968bbc72016-01-19 16:45:45 -08003637#if CONFIG_EXT_INTER
3638 if (is_inter_compound_mode(mode)) {
3639 return cpi->inter_compound_mode_cost[mode_context]
3640 [INTER_COMPOUND_OFFSET(mode)];
3641 } else {
3642#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003643 return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
Yue Chen968bbc72016-01-19 16:45:45 -08003644#if CONFIG_EXT_INTER
3645 }
3646#endif // CONFIG_EXT_INTER
Jingning Han1dc18072015-12-02 10:59:01 -08003647#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07003648}
3649
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003650static int set_and_cost_bmi_mvs(VP10_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd,
Jingning Han3ee6db62015-08-05 19:00:31 -07003651 int i,
3652 PREDICTION_MODE mode, int_mv this_mv[2],
3653 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
3654 int_mv seg_mvs[MAX_REF_FRAMES],
Yue Chen1ac85872016-01-07 15:13:52 -08003655#if CONFIG_EXT_INTER
3656 int_mv compound_seg_newmvs[2],
3657#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003658 int_mv *best_ref_mv[2], const int *mvjcost,
3659 int *mvcost[2]) {
3660 MODE_INFO *const mic = xd->mi[0];
3661 const MB_MODE_INFO *const mbmi = &mic->mbmi;
3662 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
3663 int thismvcost = 0;
3664 int idx, idy;
3665 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
3666 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
3667 const int is_compound = has_second_ref(mbmi);
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003668 int mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
Jingning Han3ee6db62015-08-05 19:00:31 -07003669
3670 switch (mode) {
3671 case NEWMV:
Yue Chen1ac85872016-01-07 15:13:52 -08003672#if CONFIG_EXT_INTER
3673 case NEWFROMNEARMV:
Yue Chen1ac85872016-01-07 15:13:52 -08003674#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003675 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08003676#if CONFIG_EXT_INTER
3677 if (!cpi->common.allow_high_precision_mv ||
3678 !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
3679 lower_mv_precision(&this_mv[0].as_mv, 0);
3680#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003681 thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
3682 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yue Chen968bbc72016-01-19 16:45:45 -08003683#if !CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003684 if (is_compound) {
3685 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
3686 thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
3687 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
3688 }
Yue Chen968bbc72016-01-19 16:45:45 -08003689#endif // !CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003690 break;
3691 case NEARMV:
3692 case NEARESTMV:
3693 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
3694 if (is_compound)
3695 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
3696 break;
3697 case ZEROMV:
3698 this_mv[0].as_int = 0;
3699 if (is_compound)
3700 this_mv[1].as_int = 0;
3701 break;
Yue Chen968bbc72016-01-19 16:45:45 -08003702#if CONFIG_EXT_INTER
3703 case NEW_NEWMV:
3704 if (compound_seg_newmvs[0].as_int == INVALID_MV ||
3705 compound_seg_newmvs[1].as_int == INVALID_MV) {
3706 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
3707 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
3708 } else {
3709 this_mv[0].as_int = compound_seg_newmvs[0].as_int;
3710 this_mv[1].as_int = compound_seg_newmvs[1].as_int;
3711 }
3712 if (!cpi->common.allow_high_precision_mv ||
3713 !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
3714 lower_mv_precision(&this_mv[0].as_mv, 0);
3715 if (!cpi->common.allow_high_precision_mv ||
3716 !vp10_use_mv_hp(&best_ref_mv[1]->as_mv))
3717 lower_mv_precision(&this_mv[1].as_mv, 0);
3718 thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv,
3719 &best_ref_mv[0]->as_mv,
3720 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
3721 thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv,
3722 &best_ref_mv[1]->as_mv,
3723 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
3724 break;
3725 case NEW_NEARMV:
3726 case NEW_NEARESTMV:
3727 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
3728 if (!cpi->common.allow_high_precision_mv ||
3729 !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
3730 lower_mv_precision(&this_mv[0].as_mv, 0);
3731 thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
3732 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
3733 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
3734 break;
3735 case NEAR_NEWMV:
3736 case NEAREST_NEWMV:
3737 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
3738 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
3739 if (!cpi->common.allow_high_precision_mv ||
3740 !vp10_use_mv_hp(&best_ref_mv[1]->as_mv))
3741 lower_mv_precision(&this_mv[1].as_mv, 0);
3742 thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
3743 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
3744 break;
3745 case NEAREST_NEARMV:
3746 case NEAR_NEARESTMV:
3747 case NEAREST_NEARESTMV:
3748 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
3749 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
3750 break;
3751 case ZERO_ZEROMV:
3752 this_mv[0].as_int = 0;
3753 this_mv[1].as_int = 0;
3754 break;
3755#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003756 default:
3757 break;
3758 }
3759
3760 mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
3761 if (is_compound)
3762 mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
3763
3764 mic->bmi[i].as_mode = mode;
3765
Jingning Han876c8b02016-02-17 16:10:38 -08003766#if CONFIG_REF_MV
3767 if (mode == NEWMV) {
3768 mic->bmi[i].pred_mv[0].as_int =
3769 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_int;
3770 if (is_compound)
3771 mic->bmi[i].pred_mv[1].as_int =
3772 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_int;
3773 } else {
3774 mic->bmi[i].pred_mv[0].as_int = this_mv[0].as_int;
3775 if (is_compound)
3776 mic->bmi[i].pred_mv[1].as_int = this_mv[1].as_int;
3777 }
3778#endif
3779
Jingning Han3ee6db62015-08-05 19:00:31 -07003780 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
3781 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
3782 memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
3783
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003784#if CONFIG_REF_MV
Yue Chen968bbc72016-01-19 16:45:45 -08003785#if CONFIG_EXT_INTER
3786 if (is_compound)
3787 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
3788 else
3789#endif // CONFIG_EXT_INTER
Jingning Han387a10e2015-12-09 09:07:39 -08003790 mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
3791 mbmi->ref_frame, mbmi->sb_type, i);
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003792#endif
Yue Chen1ac85872016-01-07 15:13:52 -08003793#if CONFIG_REF_MV && CONFIG_EXT_INTER
3794 return cost_mv_ref(cpi, mode, is_compound, mode_ctx) + thismvcost;
3795#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003796 return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
Yue Chen1ac85872016-01-07 15:13:52 -08003797#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003798}
3799
Yaowu Xu26a9afc2015-08-13 09:42:27 -07003800static int64_t encode_inter_mb_segment(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07003801 MACROBLOCK *x,
3802 int64_t best_yrd,
3803 int i,
3804 int *labelyrate,
3805 int64_t *distortion, int64_t *sse,
3806 ENTROPY_CONTEXT *ta,
3807 ENTROPY_CONTEXT *tl,
Yaowu Xu7c514e22015-09-28 15:55:46 -07003808 int ir, int ic,
Jingning Han3ee6db62015-08-05 19:00:31 -07003809 int mi_row, int mi_col) {
3810 int k;
3811 MACROBLOCKD *xd = &x->e_mbd;
3812 struct macroblockd_plane *const pd = &xd->plane[0];
3813 struct macroblock_plane *const p = &x->plane[0];
3814 MODE_INFO *const mi = xd->mi[0];
3815 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
3816 const int width = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
3817 const int height = 4 * num_4x4_blocks_high_lookup[plane_bsize];
3818 int idx, idy;
Yaowu Xu7c514e22015-09-28 15:55:46 -07003819 void (*fwd_txm4x4)(const int16_t *input, tran_low_t *output, int stride);
Jingning Han3ee6db62015-08-05 19:00:31 -07003820
3821 const uint8_t *const src =
3822 &p->src.buf[vp10_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
3823 uint8_t *const dst = &pd->dst.buf[vp10_raster_block_offset(BLOCK_8X8, i,
3824 pd->dst.stride)];
3825 int64_t thisdistortion = 0, thissse = 0;
Yaowu Xu7c514e22015-09-28 15:55:46 -07003826 int thisrate = 0;
hui sub3cc3a02015-08-24 14:37:54 -07003827 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, i, TX_4X4);
Debargha Mukherjee9fc691e2015-09-03 02:58:12 -07003828 const scan_order *so = get_scan(TX_4X4, tx_type, 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07003829
Yaowu Xu7c514e22015-09-28 15:55:46 -07003830 vp10_build_inter_predictor_sub8x8(xd, 0, i, ir, ic, mi_row, mi_col);
3831
Jingning Han3ee6db62015-08-05 19:00:31 -07003832#if CONFIG_VP9_HIGHBITDEPTH
3833 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04003834 fwd_txm4x4 = xd->lossless[mi->mbmi.segment_id] ? vp10_highbd_fwht4x4
3835 : vpx_highbd_fdct4x4;
Jingning Han3ee6db62015-08-05 19:00:31 -07003836 } else {
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04003837 fwd_txm4x4 = xd->lossless[mi->mbmi.segment_id] ? vp10_fwht4x4 : vpx_fdct4x4;
Jingning Han3ee6db62015-08-05 19:00:31 -07003838 }
3839#else
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04003840 fwd_txm4x4 = xd->lossless[mi->mbmi.segment_id] ? vp10_fwht4x4 : vpx_fdct4x4;
Jingning Han3ee6db62015-08-05 19:00:31 -07003841#endif // CONFIG_VP9_HIGHBITDEPTH
Jingning Han3ee6db62015-08-05 19:00:31 -07003842
3843#if CONFIG_VP9_HIGHBITDEPTH
3844 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3845 vpx_highbd_subtract_block(
3846 height, width, vp10_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
3847 8, src, p->src.stride, dst, pd->dst.stride, xd->bd);
3848 } else {
3849 vpx_subtract_block(
3850 height, width, vp10_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
3851 8, src, p->src.stride, dst, pd->dst.stride);
3852 }
3853#else
3854 vpx_subtract_block(height, width,
3855 vp10_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
3856 8, src, p->src.stride, dst, pd->dst.stride);
3857#endif // CONFIG_VP9_HIGHBITDEPTH
3858
3859 k = i;
3860 for (idy = 0; idy < height / 4; ++idy) {
3861 for (idx = 0; idx < width / 4; ++idx) {
Yue Chenef8f7c12016-03-04 09:48:57 -08003862 int64_t dist, ssz, rd, rd1, rd2;
Jingning Han3ee6db62015-08-05 19:00:31 -07003863 tran_low_t* coeff;
Jingning Han2cdc1272015-10-09 09:57:42 -07003864#if CONFIG_VAR_TX
3865 int coeff_ctx;
3866#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07003867 k += (idy * 2 + idx);
Jingning Han2cdc1272015-10-09 09:57:42 -07003868#if CONFIG_VAR_TX
3869 coeff_ctx = combine_entropy_contexts(*(ta + (k & 1)),
3870 *(tl + (k >> 1)));
3871#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07003872 coeff = BLOCK_OFFSET(p->coeff, k);
Yaowu Xu7c514e22015-09-28 15:55:46 -07003873 fwd_txm4x4(vp10_raster_block_offset_int16(BLOCK_8X8, k, p->src_diff),
3874 coeff, 8);
Jingning Han3ee6db62015-08-05 19:00:31 -07003875 vp10_regular_quantize_b_4x4(x, 0, k, so->scan, so->iscan);
Yue Chenef8f7c12016-03-04 09:48:57 -08003876 dist_block(cpi, x, 0, k, idy + (i >> 1), idx + (i & 0x1), TX_4X4,
3877 &dist, &ssz);
3878 thisdistortion += dist;
Jingning Han3ee6db62015-08-05 19:00:31 -07003879 thissse += ssz;
Jingning Han2cdc1272015-10-09 09:57:42 -07003880#if CONFIG_VAR_TX
3881 thisrate += cost_coeffs(x, 0, k, coeff_ctx,
3882 TX_4X4,
Jingning Han3ee6db62015-08-05 19:00:31 -07003883 so->scan, so->neighbors,
3884 cpi->sf.use_fast_coef_costing);
Jingning Han2cdc1272015-10-09 09:57:42 -07003885 *(ta + (k & 1)) = !(p->eobs[k] == 0);
3886 *(tl + (k >> 1)) = !(p->eobs[k] == 0);
3887#else
3888 thisrate += cost_coeffs(x, 0, k, ta + (k & 1), tl + (k >> 1),
3889 TX_4X4,
3890 so->scan, so->neighbors,
3891 cpi->sf.use_fast_coef_costing);
3892#endif
Yue Chenef8f7c12016-03-04 09:48:57 -08003893 rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion);
3894 rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse);
James Zern5e16d392015-08-17 18:19:22 -07003895 rd = VPXMIN(rd1, rd2);
Jingning Han3ee6db62015-08-05 19:00:31 -07003896 if (rd >= best_yrd)
3897 return INT64_MAX;
3898 }
3899 }
3900
Yue Chenef8f7c12016-03-04 09:48:57 -08003901 *distortion = thisdistortion;
Jingning Han3ee6db62015-08-05 19:00:31 -07003902 *labelyrate = thisrate;
Yue Chenef8f7c12016-03-04 09:48:57 -08003903 *sse = thissse;
Jingning Han3ee6db62015-08-05 19:00:31 -07003904
3905 return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
3906}
3907
3908typedef struct {
3909 int eobs;
3910 int brate;
3911 int byrate;
3912 int64_t bdist;
3913 int64_t bsse;
3914 int64_t brdcost;
3915 int_mv mvs[2];
Yue Chen1ac85872016-01-07 15:13:52 -08003916#if CONFIG_EXT_INTER
3917 int_mv ref_mv[2];
3918#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003919 ENTROPY_CONTEXT ta[2];
3920 ENTROPY_CONTEXT tl[2];
3921} SEG_RDSTAT;
3922
3923typedef struct {
3924 int_mv *ref_mv[2];
3925 int_mv mvp;
3926
3927 int64_t segment_rd;
3928 int r;
3929 int64_t d;
3930 int64_t sse;
3931 int segment_yrate;
3932 PREDICTION_MODE modes[4];
Yue Chen968bbc72016-01-19 16:45:45 -08003933#if CONFIG_EXT_INTER
3934 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
3935#else
Jingning Han3ee6db62015-08-05 19:00:31 -07003936 SEG_RDSTAT rdstat[4][INTER_MODES];
Yue Chen968bbc72016-01-19 16:45:45 -08003937#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003938 int mvthresh;
3939} BEST_SEG_INFO;
3940
3941static INLINE int mv_check_bounds(const MACROBLOCK *x, const MV *mv) {
3942 return (mv->row >> 3) < x->mv_row_min ||
3943 (mv->row >> 3) > x->mv_row_max ||
3944 (mv->col >> 3) < x->mv_col_min ||
3945 (mv->col >> 3) > x->mv_col_max;
3946}
3947
3948static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
3949 MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
3950 struct macroblock_plane *const p = &x->plane[0];
3951 struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
3952
3953 p->src.buf = &p->src.buf[vp10_raster_block_offset(BLOCK_8X8, i,
3954 p->src.stride)];
3955 assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
3956 pd->pre[0].buf = &pd->pre[0].buf[vp10_raster_block_offset(BLOCK_8X8, i,
3957 pd->pre[0].stride)];
3958 if (has_second_ref(mbmi))
3959 pd->pre[1].buf = &pd->pre[1].buf[vp10_raster_block_offset(BLOCK_8X8, i,
3960 pd->pre[1].stride)];
3961}
3962
3963static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
3964 struct buf_2d orig_pre[2]) {
3965 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
3966 x->plane[0].src = orig_src;
3967 x->e_mbd.plane[0].pre[0] = orig_pre[0];
3968 if (has_second_ref(mbmi))
3969 x->e_mbd.plane[0].pre[1] = orig_pre[1];
3970}
3971
Jingning Han3ee6db62015-08-05 19:00:31 -07003972// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
3973// TODO(aconverse): Find out if this is still productive then clean up or remove
3974static int check_best_zero_mv(
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003975 const VP10_COMP *cpi, const int16_t mode_context[MAX_REF_FRAMES],
Yue Chen968bbc72016-01-19 16:45:45 -08003976#if CONFIG_REF_MV && CONFIG_EXT_INTER
3977 const int16_t compound_mode_context[MAX_REF_FRAMES],
3978#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07003979 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES], int this_mode,
Jingning Han387a10e2015-12-09 09:07:39 -08003980 const MV_REFERENCE_FRAME ref_frames[2],
3981 const BLOCK_SIZE bsize, int block) {
Geza Lore7ded0382016-02-22 10:55:32 +00003982
3983#if !CONFIG_EXT_INTER
3984 assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
3985#endif
3986
Jingning Han3ee6db62015-08-05 19:00:31 -07003987 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
3988 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
Geza Lore7ded0382016-02-22 10:55:32 +00003989 (ref_frames[1] <= INTRA_FRAME ||
Jingning Han3ee6db62015-08-05 19:00:31 -07003990 frame_mv[this_mode][ref_frames[1]].as_int == 0)) {
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003991#if CONFIG_REF_MV
Jingning Han387a10e2015-12-09 09:07:39 -08003992 int16_t rfc = vp10_mode_context_analyzer(mode_context,
3993 ref_frames, bsize, block);
Jingning Hanaa5d53e2015-12-07 15:54:59 -08003994#else
3995 int16_t rfc = mode_context[ref_frames[0]];
3996#endif
Yue Chen1ac85872016-01-07 15:13:52 -08003997#if CONFIG_REF_MV && CONFIG_EXT_INTER
3998 int c1 = cost_mv_ref(cpi, NEARMV, ref_frames[1] > INTRA_FRAME, rfc);
3999 int c2 = cost_mv_ref(cpi, NEARESTMV, ref_frames[1] > INTRA_FRAME, rfc);
4000 int c3 = cost_mv_ref(cpi, ZEROMV, ref_frames[1] > INTRA_FRAME, rfc);
4001#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004002 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
4003 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
4004 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
Yue Chen1ac85872016-01-07 15:13:52 -08004005#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004006
Jingning Han387a10e2015-12-09 09:07:39 -08004007#if !CONFIG_REF_MV
4008 (void)bsize;
4009 (void)block;
4010#endif
4011
Jingning Han3ee6db62015-08-05 19:00:31 -07004012 if (this_mode == NEARMV) {
4013 if (c1 > c3) return 0;
4014 } else if (this_mode == NEARESTMV) {
4015 if (c2 > c3) return 0;
4016 } else {
4017 assert(this_mode == ZEROMV);
Geza Lore7ded0382016-02-22 10:55:32 +00004018 if (ref_frames[1] <= INTRA_FRAME) {
Jingning Han3ee6db62015-08-05 19:00:31 -07004019 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
4020 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
4021 return 0;
4022 } else {
4023 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
4024 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
4025 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
4026 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
4027 return 0;
4028 }
4029 }
4030 }
Yue Chen968bbc72016-01-19 16:45:45 -08004031#if CONFIG_EXT_INTER
4032 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
4033 this_mode == NEAR_NEARESTMV || this_mode == ZERO_ZEROMV) &&
4034 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
4035 frame_mv[this_mode][ref_frames[1]].as_int == 0) {
4036#if CONFIG_REF_MV
4037 int16_t rfc = compound_mode_context[ref_frames[0]];
4038 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, 1, rfc);
4039 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, 1, rfc);
4040 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, 1, rfc);
4041 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, 1, rfc);
4042#else
4043 int16_t rfc = mode_context[ref_frames[0]];
4044 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
4045 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
4046 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
4047 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
4048#endif
4049
4050 if (this_mode == NEAREST_NEARMV) {
4051 if (c1 > c3) return 0;
4052 } else if (this_mode == NEAREST_NEARESTMV) {
4053 if (c2 > c3) return 0;
4054 } else if (this_mode == NEAR_NEARESTMV) {
4055 if (c4 > c3) return 0;
4056 } else {
4057 assert(this_mode == ZERO_ZEROMV);
Geza Lore7ded0382016-02-22 10:55:32 +00004058 if ((c3 >= c2 &&
4059 frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
4060 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
4061 (c3 >= c1 &&
4062 frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
4063 frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
4064 (c3 >= c4 &&
4065 frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
4066 frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
4067 return 0;
Yue Chen968bbc72016-01-19 16:45:45 -08004068 }
4069 }
4070#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004071 return 1;
4072}
4073
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004074static void joint_motion_search(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07004075 BLOCK_SIZE bsize,
4076 int_mv *frame_mv,
4077 int mi_row, int mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08004078#if CONFIG_EXT_INTER
4079 int_mv* ref_mv_sub8x8[2],
4080#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07004081 int_mv single_newmv[MAX_REF_FRAMES],
Yunqing Wang342a3682016-02-16 14:33:18 -08004082 int *rate_mv,
4083 const int block) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07004084 const VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07004085 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
4086 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
4087 MACROBLOCKD *xd = &x->e_mbd;
4088 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4089 const int refs[2] = {mbmi->ref_frame[0],
4090 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]};
4091 int_mv ref_mv[2];
4092 int ite, ref;
Angie Chiang10ad97b2016-02-01 12:49:15 -08004093 const INTERP_FILTER interp_filter = mbmi->interp_filter;
Jingning Han3ee6db62015-08-05 19:00:31 -07004094 struct scale_factors sf;
4095
4096 // Do joint motion search in compound mode to get more accurate mv.
4097 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
4098 int last_besterr[2] = {INT_MAX, INT_MAX};
4099 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
4100 vp10_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
4101 vp10_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
4102 };
4103
4104 // Prediction buffer from second frame.
4105#if CONFIG_VP9_HIGHBITDEPTH
4106 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[64 * 64]);
4107 uint8_t *second_pred;
4108#else
4109 DECLARE_ALIGNED(16, uint8_t, second_pred[64 * 64]);
4110#endif // CONFIG_VP9_HIGHBITDEPTH
4111
4112 for (ref = 0; ref < 2; ++ref) {
Yue Chen1ac85872016-01-07 15:13:52 -08004113#if CONFIG_EXT_INTER
4114 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
4115 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
4116 else
4117#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004118 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
4119
4120 if (scaled_ref_frame[ref]) {
4121 int i;
4122 // Swap out the reference frame for a version that's been scaled to
4123 // match the resolution of the current frame, allowing the existing
4124 // motion search code to be used without additional modifications.
4125 for (i = 0; i < MAX_MB_PLANE; i++)
4126 backup_yv12[ref][i] = xd->plane[i].pre[ref];
4127 vp10_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
4128 NULL);
4129 }
4130
4131 frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
4132 }
4133
4134 // Since we have scaled the reference frames to match the size of the current
4135 // frame we must use a unit scaling factor during mode selection.
4136#if CONFIG_VP9_HIGHBITDEPTH
4137 vp10_setup_scale_factors_for_frame(&sf, cm->width, cm->height,
Debargha Mukherjee85514c42015-10-30 09:19:36 -07004138 cm->width, cm->height,
4139 cm->use_highbitdepth);
Jingning Han3ee6db62015-08-05 19:00:31 -07004140#else
4141 vp10_setup_scale_factors_for_frame(&sf, cm->width, cm->height,
Debargha Mukherjee85514c42015-10-30 09:19:36 -07004142 cm->width, cm->height);
Jingning Han3ee6db62015-08-05 19:00:31 -07004143#endif // CONFIG_VP9_HIGHBITDEPTH
4144
4145 // Allow joint search multiple times iteratively for each reference frame
4146 // and break out of the search loop if it couldn't find a better mv.
4147 for (ite = 0; ite < 4; ite++) {
4148 struct buf_2d ref_yv12[2];
4149 int bestsme = INT_MAX;
4150 int sadpb = x->sadperbit16;
4151 MV tmp_mv;
4152 int search_range = 3;
4153
4154 int tmp_col_min = x->mv_col_min;
4155 int tmp_col_max = x->mv_col_max;
4156 int tmp_row_min = x->mv_row_min;
4157 int tmp_row_max = x->mv_row_max;
4158 int id = ite % 2; // Even iterations search in the first reference frame,
4159 // odd iterations search in the second. The predictor
4160 // found for the 'other' reference frame is factored in.
4161
4162 // Initialized here because of compiler problem in Visual Studio.
4163 ref_yv12[0] = xd->plane[0].pre[0];
4164 ref_yv12[1] = xd->plane[0].pre[1];
4165
4166 // Get the prediction block from the 'other' reference frame.
4167#if CONFIG_VP9_HIGHBITDEPTH
4168 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
4169 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
4170 vp10_highbd_build_inter_predictor(ref_yv12[!id].buf,
4171 ref_yv12[!id].stride,
4172 second_pred, pw,
4173 &frame_mv[refs[!id]].as_mv,
4174 &sf, pw, ph, 0,
Angie Chiang10ad97b2016-02-01 12:49:15 -08004175 interp_filter, MV_PRECISION_Q3,
Jingning Han3ee6db62015-08-05 19:00:31 -07004176 mi_col * MI_SIZE, mi_row * MI_SIZE,
4177 xd->bd);
4178 } else {
4179 second_pred = (uint8_t *)second_pred_alloc_16;
4180 vp10_build_inter_predictor(ref_yv12[!id].buf,
4181 ref_yv12[!id].stride,
4182 second_pred, pw,
4183 &frame_mv[refs[!id]].as_mv,
4184 &sf, pw, ph, 0,
Angie Chiang10ad97b2016-02-01 12:49:15 -08004185 interp_filter, MV_PRECISION_Q3,
Jingning Han3ee6db62015-08-05 19:00:31 -07004186 mi_col * MI_SIZE, mi_row * MI_SIZE);
4187 }
4188#else
4189 vp10_build_inter_predictor(ref_yv12[!id].buf,
4190 ref_yv12[!id].stride,
4191 second_pred, pw,
4192 &frame_mv[refs[!id]].as_mv,
4193 &sf, pw, ph, 0,
Angie Chiang10ad97b2016-02-01 12:49:15 -08004194 interp_filter, MV_PRECISION_Q3,
Jingning Han3ee6db62015-08-05 19:00:31 -07004195 mi_col * MI_SIZE, mi_row * MI_SIZE);
4196#endif // CONFIG_VP9_HIGHBITDEPTH
4197
4198 // Do compound motion search on the current reference frame.
4199 if (id)
4200 xd->plane[0].pre[0] = ref_yv12[id];
4201 vp10_set_mv_search_range(x, &ref_mv[id].as_mv);
4202
4203 // Use the mv result from the single mode as mv predictor.
4204 tmp_mv = frame_mv[refs[id]].as_mv;
4205
4206 tmp_mv.col >>= 3;
4207 tmp_mv.row >>= 3;
4208
Jingning Han03c01bc2016-02-19 10:41:04 -08004209#if CONFIG_REF_MV
4210 vp10_set_mvcost(x, refs[id]);
4211#endif
4212
Jingning Han3ee6db62015-08-05 19:00:31 -07004213 // Small-range full-pixel motion search.
4214 bestsme = vp10_refining_search_8p_c(x, &tmp_mv, sadpb,
4215 search_range,
4216 &cpi->fn_ptr[bsize],
4217 &ref_mv[id].as_mv, second_pred);
4218 if (bestsme < INT_MAX)
4219 bestsme = vp10_get_mvpred_av_var(x, &tmp_mv, &ref_mv[id].as_mv,
4220 second_pred, &cpi->fn_ptr[bsize], 1);
4221
4222 x->mv_col_min = tmp_col_min;
4223 x->mv_col_max = tmp_col_max;
4224 x->mv_row_min = tmp_row_min;
4225 x->mv_row_max = tmp_row_max;
4226
4227 if (bestsme < INT_MAX) {
4228 int dis; /* TODO: use dis in distortion calculation later. */
4229 unsigned int sse;
Yunqing Wang342a3682016-02-16 14:33:18 -08004230#if CONFIG_AFFINE_MOTION
4231 // Use up-sampled reference frames.
4232 struct macroblockd_plane *const pd = &xd->plane[0];
4233 struct buf_2d backup_pred = pd->pre[0];
4234 const YV12_BUFFER_CONFIG *upsampled_ref =
4235 get_upsampled_ref(cpi, refs[id]);
4236
4237 // Set pred for Y plane
4238 setup_pred_plane(&pd->pre[0], upsampled_ref->y_buffer,
4239 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3),
4240 NULL, pd->subsampling_x, pd->subsampling_y);
4241
4242 // If bsize < BLOCK_8X8, adjust pred pointer for this block
4243 if (bsize < BLOCK_8X8)
4244 pd->pre[0].buf =
4245 &pd->pre[0].buf[(vp10_raster_block_offset(BLOCK_8X8, block,
4246 pd->pre[0].stride)) << 3];
4247
4248 bestsme = cpi->find_fractional_mv_step(
4249 x, &tmp_mv,
4250 &ref_mv[id].as_mv,
4251 cpi->common.allow_high_precision_mv,
4252 x->errorperbit,
4253 &cpi->fn_ptr[bsize],
4254 0, cpi->sf.mv.subpel_iters_per_step,
4255 NULL,
4256 x->nmvjointcost, x->mvcost,
4257 &dis, &sse, second_pred,
4258 pw, ph, 1);
4259
4260 // Restore the reference frames.
4261 pd->pre[0] = backup_pred;
4262#else
4263 (void) block;
Jingning Han3ee6db62015-08-05 19:00:31 -07004264 bestsme = cpi->find_fractional_mv_step(
4265 x, &tmp_mv,
4266 &ref_mv[id].as_mv,
4267 cpi->common.allow_high_precision_mv,
4268 x->errorperbit,
4269 &cpi->fn_ptr[bsize],
4270 0, cpi->sf.mv.subpel_iters_per_step,
4271 NULL,
4272 x->nmvjointcost, x->mvcost,
4273 &dis, &sse, second_pred,
4274 pw, ph);
Yunqing Wang342a3682016-02-16 14:33:18 -08004275#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07004276 }
4277
4278 // Restore the pointer to the first (possibly scaled) prediction buffer.
4279 if (id)
4280 xd->plane[0].pre[0] = ref_yv12[0];
4281
4282 if (bestsme < last_besterr[id]) {
4283 frame_mv[refs[id]].as_mv = tmp_mv;
4284 last_besterr[id] = bestsme;
4285 } else {
4286 break;
4287 }
4288 }
4289
4290 *rate_mv = 0;
4291
4292 for (ref = 0; ref < 2; ++ref) {
4293 if (scaled_ref_frame[ref]) {
4294 // Restore the prediction frame pointers to their unscaled versions.
4295 int i;
4296 for (i = 0; i < MAX_MB_PLANE; i++)
4297 xd->plane[i].pre[ref] = backup_yv12[ref][i];
4298 }
4299
Yue Chen1ac85872016-01-07 15:13:52 -08004300#if CONFIG_EXT_INTER
4301 if (bsize >= BLOCK_8X8)
4302#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004303 *rate_mv += vp10_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
4304 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
4305 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yue Chen1ac85872016-01-07 15:13:52 -08004306#if CONFIG_EXT_INTER
4307 else
4308 *rate_mv += vp10_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
4309 &ref_mv_sub8x8[ref]->as_mv,
4310 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
4311#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004312 }
4313}
4314
Yaowu Xu26a9afc2015-08-13 09:42:27 -07004315static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07004316 int_mv *best_ref_mv,
4317 int_mv *second_best_ref_mv,
4318 int64_t best_rd, int *returntotrate,
4319 int *returnyrate,
4320 int64_t *returndistortion,
4321 int *skippable, int64_t *psse,
4322 int mvthresh,
Yue Chen1ac85872016-01-07 15:13:52 -08004323#if CONFIG_EXT_INTER
4324 int_mv seg_mvs[4][2][MAX_REF_FRAMES],
4325 int_mv compound_seg_newmvs[4][2],
4326#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004327 int_mv seg_mvs[4][MAX_REF_FRAMES],
Yue Chen1ac85872016-01-07 15:13:52 -08004328#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004329 BEST_SEG_INFO *bsi_buf, int filter_idx,
4330 int mi_row, int mi_col) {
4331 int i;
4332 BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
4333 MACROBLOCKD *xd = &x->e_mbd;
4334 MODE_INFO *mi = xd->mi[0];
4335 MB_MODE_INFO *mbmi = &mi->mbmi;
4336 int mode_idx;
4337 int k, br = 0, idx, idy;
4338 int64_t bd = 0, block_sse = 0;
4339 PREDICTION_MODE this_mode;
Yaowu Xufc7cbd12015-08-13 09:36:53 -07004340 VP10_COMMON *cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07004341 struct macroblock_plane *const p = &x->plane[0];
4342 struct macroblockd_plane *const pd = &xd->plane[0];
4343 const int label_count = 4;
4344 int64_t this_segment_rd = 0;
4345 int label_mv_thresh;
4346 int segmentyrate = 0;
4347 const BLOCK_SIZE bsize = mbmi->sb_type;
4348 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
4349 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
4350 ENTROPY_CONTEXT t_above[2], t_left[2];
4351 int subpelmv = 1, have_ref = 0;
4352 const int has_second_rf = has_second_ref(mbmi);
4353 const int inter_mode_mask = cpi->sf.inter_mode_mask[bsize];
4354 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4355
4356 vp10_zero(*bsi);
4357
4358 bsi->segment_rd = best_rd;
4359 bsi->ref_mv[0] = best_ref_mv;
4360 bsi->ref_mv[1] = second_best_ref_mv;
4361 bsi->mvp.as_int = best_ref_mv->as_int;
4362 bsi->mvthresh = mvthresh;
4363
4364 for (i = 0; i < 4; i++)
4365 bsi->modes[i] = ZEROMV;
4366
4367 memcpy(t_above, pd->above_context, sizeof(t_above));
4368 memcpy(t_left, pd->left_context, sizeof(t_left));
4369
4370 // 64 makes this threshold really big effectively
4371 // making it so that we very rarely check mvs on
4372 // segments. setting this to 1 would make mv thresh
4373 // roughly equal to what it is for macroblocks
4374 label_mv_thresh = 1 * bsi->mvthresh / label_count;
4375
4376 // Segmentation method overheads
4377 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
4378 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
4379 // TODO(jingning,rbultje): rewrite the rate-distortion optimization
4380 // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
4381 int_mv mode_mv[MB_MODE_COUNT][2];
4382 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
4383 PREDICTION_MODE mode_selected = ZEROMV;
4384 int64_t best_rd = INT64_MAX;
4385 const int i = idy * 2 + idx;
4386 int ref;
Yue Chen1ac85872016-01-07 15:13:52 -08004387#if CONFIG_EXT_INTER
4388 int mv_idx;
4389 int_mv ref_mvs_sub8x8[2][2];
4390#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004391
4392 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
4393 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
Yue Chen1ac85872016-01-07 15:13:52 -08004394#if CONFIG_EXT_INTER
4395 int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
4396 vp10_update_mv_context(cm, xd, mi, frame, mv_ref_list, i,
4397 mi_row, mi_col, NULL);
4398#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004399 frame_mv[ZEROMV][frame].as_int = 0;
4400 vp10_append_sub8x8_mvs_for_idx(cm, xd, i, ref, mi_row, mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08004401#if CONFIG_EXT_INTER
4402 mv_ref_list,
4403#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004404 &frame_mv[NEARESTMV][frame],
Jingning Han40cedd62015-11-25 13:42:59 -08004405 &frame_mv[NEARMV][frame]);
Yue Chen1ac85872016-01-07 15:13:52 -08004406#if CONFIG_EXT_INTER
4407 mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
4408 mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
4409 vp10_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
4410 &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
Yue Chen968bbc72016-01-19 16:45:45 -08004411
4412 if (has_second_rf) {
4413 frame_mv[ZERO_ZEROMV][frame].as_int = 0;
4414 frame_mv[NEAREST_NEARESTMV][frame].as_int =
4415 frame_mv[NEARESTMV][frame].as_int;
4416
4417 if (ref == 0) {
4418 frame_mv[NEAREST_NEARMV][frame].as_int =
4419 frame_mv[NEARESTMV][frame].as_int;
4420 frame_mv[NEAR_NEARESTMV][frame].as_int =
4421 frame_mv[NEARMV][frame].as_int;
4422 frame_mv[NEAREST_NEWMV][frame].as_int =
4423 frame_mv[NEARESTMV][frame].as_int;
4424 frame_mv[NEAR_NEWMV][frame].as_int =
4425 frame_mv[NEARMV][frame].as_int;
4426 } else if (ref == 1) {
4427 frame_mv[NEAREST_NEARMV][frame].as_int =
4428 frame_mv[NEARMV][frame].as_int;
4429 frame_mv[NEAR_NEARESTMV][frame].as_int =
4430 frame_mv[NEARESTMV][frame].as_int;
4431 frame_mv[NEW_NEARESTMV][frame].as_int =
4432 frame_mv[NEARESTMV][frame].as_int;
4433 frame_mv[NEW_NEARMV][frame].as_int =
4434 frame_mv[NEARMV][frame].as_int;
4435 }
4436 }
Yue Chen1ac85872016-01-07 15:13:52 -08004437#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004438 }
4439
4440 // search for the best motion vector on this segment
Yue Chen1ac85872016-01-07 15:13:52 -08004441#if CONFIG_EXT_INTER
Yue Chen968bbc72016-01-19 16:45:45 -08004442 for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
4443 this_mode <= (has_second_rf ? NEW_NEWMV : NEWFROMNEARMV);
4444 ++this_mode) {
Yue Chen1ac85872016-01-07 15:13:52 -08004445#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004446 for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
Yue Chen1ac85872016-01-07 15:13:52 -08004447#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004448 const struct buf_2d orig_src = x->plane[0].src;
4449 struct buf_2d orig_pre[2];
4450
4451 mode_idx = INTER_OFFSET(this_mode);
Yue Chen1ac85872016-01-07 15:13:52 -08004452#if CONFIG_EXT_INTER
4453 mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
Yue Chen968bbc72016-01-19 16:45:45 -08004454
Yue Chen1ac85872016-01-07 15:13:52 -08004455 for (ref = 0; ref < 1 + has_second_rf; ++ref)
4456 bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[mv_idx][ref].as_int;
4457#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004458 bsi->rdstat[i][mode_idx].brdcost = INT64_MAX;
4459 if (!(inter_mode_mask & (1 << this_mode)))
4460 continue;
4461
Yue Chen968bbc72016-01-19 16:45:45 -08004462 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
4463#if CONFIG_REF_MV && CONFIG_EXT_INTER
4464 mbmi_ext->compound_mode_context,
4465#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4466 frame_mv,
Jingning Han387a10e2015-12-09 09:07:39 -08004467 this_mode, mbmi->ref_frame, bsize, i))
Jingning Han3ee6db62015-08-05 19:00:31 -07004468 continue;
4469
4470 memcpy(orig_pre, pd->pre, sizeof(orig_pre));
4471 memcpy(bsi->rdstat[i][mode_idx].ta, t_above,
4472 sizeof(bsi->rdstat[i][mode_idx].ta));
4473 memcpy(bsi->rdstat[i][mode_idx].tl, t_left,
4474 sizeof(bsi->rdstat[i][mode_idx].tl));
4475
4476 // motion search for newmv (single predictor case only)
Yue Chen1ac85872016-01-07 15:13:52 -08004477 if (!has_second_rf &&
4478#if CONFIG_EXT_INTER
4479 have_newmv_in_inter_mode(this_mode) &&
4480 seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV
4481#else
4482 this_mode == NEWMV &&
4483 seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV
4484#endif // CONFIG_EXT_INTER
4485 ) {
4486#if CONFIG_EXT_INTER
4487 MV *const new_mv = &mode_mv[this_mode][0].as_mv;
4488#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004489 MV *const new_mv = &mode_mv[NEWMV][0].as_mv;
Yue Chen1ac85872016-01-07 15:13:52 -08004490#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004491 int step_param = 0;
paulwilkins4e692bb2015-12-08 15:48:24 +00004492 int bestsme = INT_MAX;
Jingning Han3ee6db62015-08-05 19:00:31 -07004493 int sadpb = x->sadperbit4;
4494 MV mvp_full;
4495 int max_mv;
4496 int cost_list[5];
4497
4498 /* Is the best so far sufficiently good that we cant justify doing
4499 * and new motion search. */
4500 if (best_rd < label_mv_thresh)
4501 break;
4502
4503 if (cpi->oxcf.mode != BEST) {
Yue Chen1ac85872016-01-07 15:13:52 -08004504#if CONFIG_EXT_INTER
4505 bsi->mvp.as_int = bsi->ref_mv[0]->as_int;
4506#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004507 // use previous block's result as next block's MV predictor.
4508 if (i > 0) {
4509 bsi->mvp.as_int = mi->bmi[i - 1].as_mv[0].as_int;
4510 if (i == 2)
4511 bsi->mvp.as_int = mi->bmi[i - 2].as_mv[0].as_int;
4512 }
Yue Chen1ac85872016-01-07 15:13:52 -08004513#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004514 }
4515 if (i == 0)
4516 max_mv = x->max_mv_context[mbmi->ref_frame[0]];
4517 else
James Zern5e16d392015-08-17 18:19:22 -07004518 max_mv =
4519 VPXMAX(abs(bsi->mvp.as_mv.row), abs(bsi->mvp.as_mv.col)) >> 3;
Jingning Han3ee6db62015-08-05 19:00:31 -07004520
4521 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
4522 // Take wtd average of the step_params based on the last frame's
4523 // max mv magnitude and the best ref mvs of the current block for
4524 // the given reference.
4525 step_param = (vp10_init_search_range(max_mv) +
4526 cpi->mv_step_param) / 2;
4527 } else {
4528 step_param = cpi->mv_step_param;
4529 }
4530
4531 mvp_full.row = bsi->mvp.as_mv.row >> 3;
4532 mvp_full.col = bsi->mvp.as_mv.col >> 3;
4533
4534 if (cpi->sf.adaptive_motion_search) {
4535 mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
4536 mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
James Zern5e16d392015-08-17 18:19:22 -07004537 step_param = VPXMAX(step_param, 8);
Jingning Han3ee6db62015-08-05 19:00:31 -07004538 }
4539
4540 // adjust src pointer for this block
4541 mi_buf_shift(x, i);
4542
4543 vp10_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
4544
Jingning Han03c01bc2016-02-19 10:41:04 -08004545#if CONFIG_REF_MV
4546 vp10_set_mvcost(x, mbmi->ref_frame[0]);
4547#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07004548 bestsme = vp10_full_pixel_search(
4549 cpi, x, bsize, &mvp_full, step_param, sadpb,
4550 cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
4551 &bsi->ref_mv[0]->as_mv, new_mv,
4552 INT_MAX, 1);
4553
Jingning Han3ee6db62015-08-05 19:00:31 -07004554 if (bestsme < INT_MAX) {
4555 int distortion;
Yunqing Wang342a3682016-02-16 14:33:18 -08004556#if CONFIG_AFFINE_MOTION
4557 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
4558 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
4559 // Use up-sampled reference frames.
4560 struct macroblockd_plane *const pd = &xd->plane[0];
4561 struct buf_2d backup_pred = pd->pre[0];
4562 const YV12_BUFFER_CONFIG *upsampled_ref =
4563 get_upsampled_ref(cpi, mbmi->ref_frame[0]);
4564
4565 // Set pred for Y plane
4566 setup_pred_plane(&pd->pre[0], upsampled_ref->y_buffer,
4567 upsampled_ref->y_stride,
4568 (mi_row << 3), (mi_col << 3),
4569 NULL, pd->subsampling_x, pd->subsampling_y);
4570
4571 // adjust pred pointer for this block
4572 pd->pre[0].buf =
4573 &pd->pre[0].buf[(vp10_raster_block_offset(BLOCK_8X8, i,
4574 pd->pre[0].stride)) << 3];
4575
4576 cpi->find_fractional_mv_step(
4577 x,
4578 new_mv,
4579 &bsi->ref_mv[0]->as_mv,
4580 cm->allow_high_precision_mv,
4581 x->errorperbit, &cpi->fn_ptr[bsize],
4582 cpi->sf.mv.subpel_force_stop,
4583 cpi->sf.mv.subpel_iters_per_step,
4584 cond_cost_list(cpi, cost_list),
4585 x->nmvjointcost, x->mvcost,
4586 &distortion,
4587 &x->pred_sse[mbmi->ref_frame[0]],
4588 NULL, pw, ph, 1);
4589
4590 // Restore the reference frames.
4591 pd->pre[0] = backup_pred;
4592#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004593 cpi->find_fractional_mv_step(
4594 x,
4595 new_mv,
4596 &bsi->ref_mv[0]->as_mv,
4597 cm->allow_high_precision_mv,
4598 x->errorperbit, &cpi->fn_ptr[bsize],
4599 cpi->sf.mv.subpel_force_stop,
4600 cpi->sf.mv.subpel_iters_per_step,
4601 cond_cost_list(cpi, cost_list),
4602 x->nmvjointcost, x->mvcost,
4603 &distortion,
4604 &x->pred_sse[mbmi->ref_frame[0]],
4605 NULL, 0, 0);
Yunqing Wang342a3682016-02-16 14:33:18 -08004606#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07004607
4608 // save motion search result for use in compound prediction
Yue Chen1ac85872016-01-07 15:13:52 -08004609#if CONFIG_EXT_INTER
4610 seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_mv = *new_mv;
4611#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004612 seg_mvs[i][mbmi->ref_frame[0]].as_mv = *new_mv;
Yue Chen1ac85872016-01-07 15:13:52 -08004613#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004614 }
4615
4616 if (cpi->sf.adaptive_motion_search)
4617 x->pred_mv[mbmi->ref_frame[0]] = *new_mv;
4618
4619 // restore src pointers
4620 mi_buf_restore(x, orig_src, orig_pre);
4621 }
4622
4623 if (has_second_rf) {
Yue Chen1ac85872016-01-07 15:13:52 -08004624#if CONFIG_EXT_INTER
4625 if (seg_mvs[i][mv_idx][mbmi->ref_frame[1]].as_int == INVALID_MV ||
4626 seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
4627#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004628 if (seg_mvs[i][mbmi->ref_frame[1]].as_int == INVALID_MV ||
4629 seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yue Chen1ac85872016-01-07 15:13:52 -08004630#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004631 continue;
4632 }
4633
Yue Chen968bbc72016-01-19 16:45:45 -08004634 if (has_second_rf &&
4635#if CONFIG_EXT_INTER
4636 this_mode == NEW_NEWMV &&
4637#else
4638 this_mode == NEWMV &&
4639#endif // CONFIG_EXT_INTER
Debargha Mukherjeebab29122016-02-26 00:18:03 -08004640 mbmi->interp_filter == EIGHTTAP_REGULAR) {
Jingning Han3ee6db62015-08-05 19:00:31 -07004641 // adjust src pointers
4642 mi_buf_shift(x, i);
4643 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
4644 int rate_mv;
4645 joint_motion_search(cpi, x, bsize, frame_mv[this_mode],
Yue Chen1ac85872016-01-07 15:13:52 -08004646 mi_row, mi_col,
4647#if CONFIG_EXT_INTER
4648 bsi->ref_mv,
4649 seg_mvs[i][mv_idx],
4650#else
4651 seg_mvs[i],
4652#endif // CONFIG_EXT_INTER
Yunqing Wang342a3682016-02-16 14:33:18 -08004653 &rate_mv, i);
Yue Chen1ac85872016-01-07 15:13:52 -08004654#if CONFIG_EXT_INTER
4655 compound_seg_newmvs[i][0].as_int =
4656 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
4657 compound_seg_newmvs[i][1].as_int =
4658 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
4659#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004660 seg_mvs[i][mbmi->ref_frame[0]].as_int =
4661 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
4662 seg_mvs[i][mbmi->ref_frame[1]].as_int =
4663 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08004664#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004665 }
4666 // restore src pointers
4667 mi_buf_restore(x, orig_src, orig_pre);
4668 }
4669
4670 bsi->rdstat[i][mode_idx].brate =
4671 set_and_cost_bmi_mvs(cpi, x, xd, i, this_mode, mode_mv[this_mode],
Yue Chen1ac85872016-01-07 15:13:52 -08004672 frame_mv,
4673#if CONFIG_EXT_INTER
4674 seg_mvs[i][mv_idx],
4675 compound_seg_newmvs[i],
4676#else
4677 seg_mvs[i],
4678#endif // CONFIG_EXT_INTER
4679 bsi->ref_mv,
Jingning Han3ee6db62015-08-05 19:00:31 -07004680 x->nmvjointcost, x->mvcost);
4681
4682 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
4683 bsi->rdstat[i][mode_idx].mvs[ref].as_int =
4684 mode_mv[this_mode][ref].as_int;
4685 if (num_4x4_blocks_wide > 1)
4686 bsi->rdstat[i + 1][mode_idx].mvs[ref].as_int =
4687 mode_mv[this_mode][ref].as_int;
4688 if (num_4x4_blocks_high > 1)
4689 bsi->rdstat[i + 2][mode_idx].mvs[ref].as_int =
4690 mode_mv[this_mode][ref].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08004691#if CONFIG_EXT_INTER
4692 bsi->rdstat[i][mode_idx].ref_mv[ref].as_int =
4693 bsi->ref_mv[ref]->as_int;
4694 if (num_4x4_blocks_wide > 1)
4695 bsi->rdstat[i + 1][mode_idx].ref_mv[ref].as_int =
4696 bsi->ref_mv[ref]->as_int;
4697 if (num_4x4_blocks_high > 1)
4698 bsi->rdstat[i + 2][mode_idx].ref_mv[ref].as_int =
4699 bsi->ref_mv[ref]->as_int;
4700#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004701 }
4702
4703 // Trap vectors that reach beyond the UMV borders
4704 if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
4705 (has_second_rf &&
4706 mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
4707 continue;
4708
4709 if (filter_idx > 0) {
4710 BEST_SEG_INFO *ref_bsi = bsi_buf;
4711 subpelmv = 0;
4712 have_ref = 1;
4713
4714 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
4715 subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
Yue Chen1ac85872016-01-07 15:13:52 -08004716#if CONFIG_EXT_INTER
4717 if (have_newmv_in_inter_mode(this_mode))
4718 have_ref &= (
4719 (mode_mv[this_mode][ref].as_int ==
4720 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int) &&
4721 (bsi->ref_mv[ref]->as_int ==
4722 ref_bsi->rdstat[i][mode_idx].ref_mv[ref].as_int));
4723 else
4724#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004725 have_ref &= mode_mv[this_mode][ref].as_int ==
4726 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
4727 }
4728
4729 if (filter_idx > 1 && !subpelmv && !have_ref) {
4730 ref_bsi = bsi_buf + 1;
4731 have_ref = 1;
4732 for (ref = 0; ref < 1 + has_second_rf; ++ref)
Yue Chen1ac85872016-01-07 15:13:52 -08004733#if CONFIG_EXT_INTER
4734 if (have_newmv_in_inter_mode(this_mode))
4735 have_ref &= (
4736 (mode_mv[this_mode][ref].as_int ==
4737 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int) &&
4738 (bsi->ref_mv[ref]->as_int ==
4739 ref_bsi->rdstat[i][mode_idx].ref_mv[ref].as_int));
4740 else
4741#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004742 have_ref &= mode_mv[this_mode][ref].as_int ==
4743 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
4744 }
4745
4746 if (!subpelmv && have_ref &&
4747 ref_bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) {
4748 memcpy(&bsi->rdstat[i][mode_idx], &ref_bsi->rdstat[i][mode_idx],
4749 sizeof(SEG_RDSTAT));
4750 if (num_4x4_blocks_wide > 1)
4751 bsi->rdstat[i + 1][mode_idx].eobs =
4752 ref_bsi->rdstat[i + 1][mode_idx].eobs;
4753 if (num_4x4_blocks_high > 1)
4754 bsi->rdstat[i + 2][mode_idx].eobs =
4755 ref_bsi->rdstat[i + 2][mode_idx].eobs;
4756
4757 if (bsi->rdstat[i][mode_idx].brdcost < best_rd) {
4758 mode_selected = this_mode;
4759 best_rd = bsi->rdstat[i][mode_idx].brdcost;
4760 }
4761 continue;
4762 }
4763 }
4764
4765 bsi->rdstat[i][mode_idx].brdcost =
4766 encode_inter_mb_segment(cpi, x,
4767 bsi->segment_rd - this_segment_rd, i,
4768 &bsi->rdstat[i][mode_idx].byrate,
4769 &bsi->rdstat[i][mode_idx].bdist,
4770 &bsi->rdstat[i][mode_idx].bsse,
4771 bsi->rdstat[i][mode_idx].ta,
4772 bsi->rdstat[i][mode_idx].tl,
Yaowu Xu7c514e22015-09-28 15:55:46 -07004773 idy, idx,
Jingning Han3ee6db62015-08-05 19:00:31 -07004774 mi_row, mi_col);
4775 if (bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) {
4776 bsi->rdstat[i][mode_idx].brdcost += RDCOST(x->rdmult, x->rddiv,
4777 bsi->rdstat[i][mode_idx].brate, 0);
4778 bsi->rdstat[i][mode_idx].brate += bsi->rdstat[i][mode_idx].byrate;
4779 bsi->rdstat[i][mode_idx].eobs = p->eobs[i];
4780 if (num_4x4_blocks_wide > 1)
4781 bsi->rdstat[i + 1][mode_idx].eobs = p->eobs[i + 1];
4782 if (num_4x4_blocks_high > 1)
4783 bsi->rdstat[i + 2][mode_idx].eobs = p->eobs[i + 2];
4784 }
4785
4786 if (bsi->rdstat[i][mode_idx].brdcost < best_rd) {
4787 mode_selected = this_mode;
4788 best_rd = bsi->rdstat[i][mode_idx].brdcost;
4789 }
4790 } /*for each 4x4 mode*/
4791
4792 if (best_rd == INT64_MAX) {
4793 int iy, midx;
4794 for (iy = i + 1; iy < 4; ++iy)
Yue Chen968bbc72016-01-19 16:45:45 -08004795#if CONFIG_EXT_INTER
4796 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
4797#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004798 for (midx = 0; midx < INTER_MODES; ++midx)
Yue Chen968bbc72016-01-19 16:45:45 -08004799#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004800 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
4801 bsi->segment_rd = INT64_MAX;
4802 return INT64_MAX;
4803 }
4804
4805 mode_idx = INTER_OFFSET(mode_selected);
4806 memcpy(t_above, bsi->rdstat[i][mode_idx].ta, sizeof(t_above));
4807 memcpy(t_left, bsi->rdstat[i][mode_idx].tl, sizeof(t_left));
4808
Yue Chen1ac85872016-01-07 15:13:52 -08004809#if CONFIG_EXT_INTER
4810 mv_idx = (mode_selected == NEWFROMNEARMV) ? 1 : 0;
4811 bsi->ref_mv[0]->as_int = bsi->rdstat[i][mode_idx].ref_mv[0].as_int;
4812 if (has_second_rf)
4813 bsi->ref_mv[1]->as_int = bsi->rdstat[i][mode_idx].ref_mv[1].as_int;
4814#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004815 set_and_cost_bmi_mvs(cpi, x, xd, i, mode_selected, mode_mv[mode_selected],
Yue Chen1ac85872016-01-07 15:13:52 -08004816 frame_mv,
4817#if CONFIG_EXT_INTER
4818 seg_mvs[i][mv_idx],
4819 compound_seg_newmvs[i],
4820#else
4821 seg_mvs[i],
4822#endif // CONFIG_EXT_INTER
4823 bsi->ref_mv, x->nmvjointcost, x->mvcost);
Jingning Han3ee6db62015-08-05 19:00:31 -07004824
4825 br += bsi->rdstat[i][mode_idx].brate;
4826 bd += bsi->rdstat[i][mode_idx].bdist;
4827 block_sse += bsi->rdstat[i][mode_idx].bsse;
4828 segmentyrate += bsi->rdstat[i][mode_idx].byrate;
4829 this_segment_rd += bsi->rdstat[i][mode_idx].brdcost;
4830
4831 if (this_segment_rd > bsi->segment_rd) {
4832 int iy, midx;
4833 for (iy = i + 1; iy < 4; ++iy)
Yue Chen968bbc72016-01-19 16:45:45 -08004834#if CONFIG_EXT_INTER
4835 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
4836#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004837 for (midx = 0; midx < INTER_MODES; ++midx)
Yue Chen968bbc72016-01-19 16:45:45 -08004838#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004839 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
4840 bsi->segment_rd = INT64_MAX;
4841 return INT64_MAX;
4842 }
4843 }
4844 } /* for each label */
4845
4846 bsi->r = br;
4847 bsi->d = bd;
4848 bsi->segment_yrate = segmentyrate;
4849 bsi->segment_rd = this_segment_rd;
4850 bsi->sse = block_sse;
4851
4852 // update the coding decisions
4853 for (k = 0; k < 4; ++k)
4854 bsi->modes[k] = mi->bmi[k].as_mode;
4855
4856 if (bsi->segment_rd > best_rd)
4857 return INT64_MAX;
4858 /* set it to the best */
4859 for (i = 0; i < 4; i++) {
4860 mode_idx = INTER_OFFSET(bsi->modes[i]);
4861 mi->bmi[i].as_mv[0].as_int = bsi->rdstat[i][mode_idx].mvs[0].as_int;
4862 if (has_second_ref(mbmi))
4863 mi->bmi[i].as_mv[1].as_int = bsi->rdstat[i][mode_idx].mvs[1].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08004864#if CONFIG_EXT_INTER
4865 mi->bmi[i].ref_mv[0].as_int = bsi->rdstat[i][mode_idx].ref_mv[0].as_int;
4866 if (has_second_rf)
4867 mi->bmi[i].ref_mv[1].as_int = bsi->rdstat[i][mode_idx].ref_mv[1].as_int;
4868#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07004869 x->plane[0].eobs[i] = bsi->rdstat[i][mode_idx].eobs;
4870 mi->bmi[i].as_mode = bsi->modes[i];
4871 }
4872
4873 /*
4874 * used to set mbmi->mv.as_int
4875 */
4876 *returntotrate = bsi->r;
4877 *returndistortion = bsi->d;
4878 *returnyrate = bsi->segment_yrate;
4879 *skippable = vp10_is_skippable_in_plane(x, BLOCK_8X8, 0);
4880 *psse = bsi->sse;
4881 mbmi->mode = bsi->modes[3];
4882
4883 return bsi->segment_rd;
4884}
4885
Yaowu Xufc7cbd12015-08-13 09:36:53 -07004886static void estimate_ref_frame_costs(const VP10_COMMON *cm,
Jingning Han3ee6db62015-08-05 19:00:31 -07004887 const MACROBLOCKD *xd,
4888 int segment_id,
4889 unsigned int *ref_costs_single,
4890 unsigned int *ref_costs_comp,
4891 vpx_prob *comp_mode_p) {
4892 int seg_ref_active = segfeature_active(&cm->seg, segment_id,
4893 SEG_LVL_REF_FRAME);
4894 if (seg_ref_active) {
4895 memset(ref_costs_single, 0, MAX_REF_FRAMES * sizeof(*ref_costs_single));
4896 memset(ref_costs_comp, 0, MAX_REF_FRAMES * sizeof(*ref_costs_comp));
4897 *comp_mode_p = 128;
4898 } else {
4899 vpx_prob intra_inter_p = vp10_get_intra_inter_prob(cm, xd);
4900 vpx_prob comp_inter_p = 128;
4901
4902 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
4903 comp_inter_p = vp10_get_reference_mode_prob(cm, xd);
4904 *comp_mode_p = comp_inter_p;
4905 } else {
4906 *comp_mode_p = 128;
4907 }
4908
4909 ref_costs_single[INTRA_FRAME] = vp10_cost_bit(intra_inter_p, 0);
4910
4911 if (cm->reference_mode != COMPOUND_REFERENCE) {
4912 vpx_prob ref_single_p1 = vp10_get_pred_prob_single_ref_p1(cm, xd);
4913 vpx_prob ref_single_p2 = vp10_get_pred_prob_single_ref_p2(cm, xd);
Zoe Liu3ec16012015-11-12 02:12:17 -08004914#if CONFIG_EXT_REFS
4915 vpx_prob ref_single_p3 = vp10_get_pred_prob_single_ref_p3(cm, xd);
4916 vpx_prob ref_single_p4 = vp10_get_pred_prob_single_ref_p4(cm, xd);
4917 vpx_prob ref_single_p5 = vp10_get_pred_prob_single_ref_p5(cm, xd);
4918#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07004919 unsigned int base_cost = vp10_cost_bit(intra_inter_p, 1);
4920
Zoe Liu3ec16012015-11-12 02:12:17 -08004921 ref_costs_single[LAST_FRAME] =
4922#if CONFIG_EXT_REFS
4923 ref_costs_single[LAST2_FRAME] =
4924 ref_costs_single[LAST3_FRAME] =
4925 ref_costs_single[LAST4_FRAME] =
4926#endif // CONFIG_EXT_REFS
4927 ref_costs_single[GOLDEN_FRAME] =
Jingning Han3ee6db62015-08-05 19:00:31 -07004928 ref_costs_single[ALTREF_FRAME] = base_cost;
Zoe Liu3ec16012015-11-12 02:12:17 -08004929
4930#if CONFIG_EXT_REFS
4931 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p1, 0);
4932 ref_costs_single[LAST2_FRAME] += vp10_cost_bit(ref_single_p1, 0);
4933 ref_costs_single[LAST3_FRAME] += vp10_cost_bit(ref_single_p1, 0);
4934 ref_costs_single[LAST4_FRAME] += vp10_cost_bit(ref_single_p1, 0);
4935 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p1, 1);
4936 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p1, 1);
4937
4938 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p3, 0);
4939 ref_costs_single[LAST2_FRAME] += vp10_cost_bit(ref_single_p3, 0);
4940 ref_costs_single[LAST3_FRAME] += vp10_cost_bit(ref_single_p3, 1);
4941 ref_costs_single[LAST4_FRAME] += vp10_cost_bit(ref_single_p3, 1);
4942 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p2, 0);
4943 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p2, 1);
4944
4945 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p4, 0);
4946 ref_costs_single[LAST2_FRAME] += vp10_cost_bit(ref_single_p4, 1);
4947 ref_costs_single[LAST3_FRAME] += vp10_cost_bit(ref_single_p5, 0);
4948 ref_costs_single[LAST4_FRAME] += vp10_cost_bit(ref_single_p5, 1);
4949#else
Jingning Han3ee6db62015-08-05 19:00:31 -07004950 ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p1, 0);
4951 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p1, 1);
4952 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p1, 1);
4953 ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p2, 0);
4954 ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p2, 1);
Zoe Liu3ec16012015-11-12 02:12:17 -08004955#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07004956 } else {
4957 ref_costs_single[LAST_FRAME] = 512;
Zoe Liu3ec16012015-11-12 02:12:17 -08004958#if CONFIG_EXT_REFS
4959 ref_costs_single[LAST2_FRAME] = 512;
4960 ref_costs_single[LAST3_FRAME] = 512;
4961 ref_costs_single[LAST4_FRAME] = 512;
4962#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07004963 ref_costs_single[GOLDEN_FRAME] = 512;
4964 ref_costs_single[ALTREF_FRAME] = 512;
4965 }
Zoe Liu3ec16012015-11-12 02:12:17 -08004966
Jingning Han3ee6db62015-08-05 19:00:31 -07004967 if (cm->reference_mode != SINGLE_REFERENCE) {
4968 vpx_prob ref_comp_p = vp10_get_pred_prob_comp_ref_p(cm, xd);
Zoe Liu3ec16012015-11-12 02:12:17 -08004969#if CONFIG_EXT_REFS
4970 vpx_prob ref_comp_p1 = vp10_get_pred_prob_comp_ref_p1(cm, xd);
4971 vpx_prob ref_comp_p2 = vp10_get_pred_prob_comp_ref_p2(cm, xd);
4972 vpx_prob ref_comp_p3 = vp10_get_pred_prob_comp_ref_p3(cm, xd);
4973#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07004974 unsigned int base_cost = vp10_cost_bit(intra_inter_p, 1);
4975
Zoe Liu3ec16012015-11-12 02:12:17 -08004976 ref_costs_comp[LAST_FRAME] =
4977#if CONFIG_EXT_REFS
4978 ref_costs_comp[LAST2_FRAME] =
4979 ref_costs_comp[LAST3_FRAME] =
4980 ref_costs_comp[LAST4_FRAME] =
4981#endif // CONFIG_EXT_REFS
4982 ref_costs_comp[GOLDEN_FRAME] = base_cost;
4983
4984#if CONFIG_EXT_REFS
4985 ref_costs_comp[LAST_FRAME] += vp10_cost_bit(ref_comp_p, 0);
4986 ref_costs_comp[LAST2_FRAME] += vp10_cost_bit(ref_comp_p, 0);
4987 ref_costs_comp[LAST3_FRAME] += vp10_cost_bit(ref_comp_p, 1);
4988 ref_costs_comp[LAST4_FRAME] += vp10_cost_bit(ref_comp_p, 1);
4989 ref_costs_comp[GOLDEN_FRAME] += vp10_cost_bit(ref_comp_p, 1);
4990
4991 ref_costs_comp[LAST_FRAME] += vp10_cost_bit(ref_comp_p1, 1);
4992 ref_costs_comp[LAST2_FRAME] += vp10_cost_bit(ref_comp_p1, 0);
4993 ref_costs_comp[LAST3_FRAME] += vp10_cost_bit(ref_comp_p2, 0);
4994 ref_costs_comp[LAST4_FRAME] += vp10_cost_bit(ref_comp_p2, 0);
4995 ref_costs_comp[GOLDEN_FRAME] += vp10_cost_bit(ref_comp_p2, 1);
4996
4997 ref_costs_comp[LAST3_FRAME] += vp10_cost_bit(ref_comp_p3, 1);
4998 ref_costs_comp[LAST4_FRAME] += vp10_cost_bit(ref_comp_p3, 0);
4999#else
5000 ref_costs_comp[LAST_FRAME] += vp10_cost_bit(ref_comp_p, 0);
5001 ref_costs_comp[GOLDEN_FRAME] += vp10_cost_bit(ref_comp_p, 1);
5002#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07005003 } else {
5004 ref_costs_comp[LAST_FRAME] = 512;
Zoe Liu3ec16012015-11-12 02:12:17 -08005005#if CONFIG_EXT_REFS
5006 ref_costs_comp[LAST2_FRAME] = 512;
5007 ref_costs_comp[LAST3_FRAME] = 512;
5008 ref_costs_comp[LAST4_FRAME] = 512;
5009#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07005010 ref_costs_comp[GOLDEN_FRAME] = 512;
5011 }
5012 }
5013}
5014
5015static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
5016 int mode_index,
5017 int64_t comp_pred_diff[REFERENCE_MODES],
5018 int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS],
5019 int skippable) {
5020 MACROBLOCKD *const xd = &x->e_mbd;
5021
5022 // Take a snapshot of the coding context so it can be
5023 // restored if we decide to encode this way
5024 ctx->skip = x->skip;
5025 ctx->skippable = skippable;
5026 ctx->best_mode_index = mode_index;
5027 ctx->mic = *xd->mi[0];
5028 ctx->mbmi_ext = *x->mbmi_ext;
5029 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
5030 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
5031 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
5032
5033 memcpy(ctx->best_filter_diff, best_filter_diff,
5034 sizeof(*best_filter_diff) * SWITCHABLE_FILTER_CONTEXTS);
5035}
5036
Zoe Liu3ec16012015-11-12 02:12:17 -08005037static void setup_buffer_inter(
5038 VP10_COMP *cpi, MACROBLOCK *x,
5039 MV_REFERENCE_FRAME ref_frame,
5040 BLOCK_SIZE block_size,
5041 int mi_row, int mi_col,
5042 int_mv frame_nearest_mv[MAX_REF_FRAMES],
5043 int_mv frame_near_mv[MAX_REF_FRAMES],
5044 struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE]) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07005045 const VP10_COMMON *cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07005046 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
5047 MACROBLOCKD *const xd = &x->e_mbd;
5048 MODE_INFO *const mi = xd->mi[0];
5049 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
5050 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
5051 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
5052
5053 assert(yv12 != NULL);
5054
5055 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
5056 // use the UV scaling factors.
5057 vp10_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
5058
5059 // Gets an initial list of candidate vectors from neighbours and orders them
Jingning Hane5c57c52015-11-23 15:05:18 -08005060 vp10_find_mv_refs(cm, xd, mi, ref_frame,
5061#if CONFIG_REF_MV
5062 &mbmi_ext->ref_mv_count[ref_frame],
5063 mbmi_ext->ref_mv_stack[ref_frame],
Yue Chen968bbc72016-01-19 16:45:45 -08005064#if CONFIG_EXT_INTER
5065 mbmi_ext->compound_mode_context,
5066#endif // CONFIG_EXT_INTER
Jingning Hane5c57c52015-11-23 15:05:18 -08005067#endif
5068 candidates, mi_row, mi_col,
5069 NULL, NULL, mbmi_ext->mode_context);
Jingning Han3ee6db62015-08-05 19:00:31 -07005070
5071 // Candidate refinement carried out at encoder and decoder
Ronald S. Bultje5b4805d2015-10-02 11:51:54 -04005072 vp10_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
5073 &frame_nearest_mv[ref_frame],
5074 &frame_near_mv[ref_frame]);
Jingning Han3ee6db62015-08-05 19:00:31 -07005075
5076 // Further refinement that is encode side only to test the top few candidates
5077 // in full and choose the best as the centre point for subsequent searches.
5078 // The current implementation doesn't support scaling.
5079 if (!vp10_is_scaled(sf) && block_size >= BLOCK_8X8)
5080 vp10_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride,
5081 ref_frame, block_size);
5082}
5083
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005084static void single_motion_search(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07005085 BLOCK_SIZE bsize,
5086 int mi_row, int mi_col,
Yue Chen1ac85872016-01-07 15:13:52 -08005087#if CONFIG_EXT_INTER
5088 int ref_idx,
5089 int mv_idx,
5090#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005091 int_mv *tmp_mv, int *rate_mv) {
5092 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xufc7cbd12015-08-13 09:36:53 -07005093 const VP10_COMMON *cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07005094 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5095 struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0, 0}};
5096 int bestsme = INT_MAX;
5097 int step_param;
5098 int sadpb = x->sadperbit16;
5099 MV mvp_full;
Yue Chen1ac85872016-01-07 15:13:52 -08005100#if CONFIG_EXT_INTER
5101 int ref = mbmi->ref_frame[ref_idx];
5102 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
5103#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005104 int ref = mbmi->ref_frame[0];
5105 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
Yue Chen1ac85872016-01-07 15:13:52 -08005106#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005107
5108 int tmp_col_min = x->mv_col_min;
5109 int tmp_col_max = x->mv_col_max;
5110 int tmp_row_min = x->mv_row_min;
5111 int tmp_row_max = x->mv_row_max;
5112 int cost_list[5];
5113
5114 const YV12_BUFFER_CONFIG *scaled_ref_frame = vp10_get_scaled_ref_frame(cpi,
5115 ref);
5116
5117 MV pred_mv[3];
5118 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
5119 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
5120 pred_mv[2] = x->pred_mv[ref];
5121
Jingning Han03c01bc2016-02-19 10:41:04 -08005122#if CONFIG_REF_MV
5123 vp10_set_mvcost(x, ref);
5124#endif
5125
Jingning Han3ee6db62015-08-05 19:00:31 -07005126 if (scaled_ref_frame) {
5127 int i;
5128 // Swap out the reference frame for a version that's been scaled to
5129 // match the resolution of the current frame, allowing the existing
5130 // motion search code to be used without additional modifications.
5131 for (i = 0; i < MAX_MB_PLANE; i++)
5132 backup_yv12[i] = xd->plane[i].pre[0];
5133
5134 vp10_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
5135 }
5136
5137 vp10_set_mv_search_range(x, &ref_mv);
5138
5139 // Work out the size of the first step in the mv step search.
James Zern5e16d392015-08-17 18:19:22 -07005140 // 0 here is maximum length first step. 1 is VPXMAX >> 1 etc.
Jingning Han3ee6db62015-08-05 19:00:31 -07005141 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
5142 // Take wtd average of the step_params based on the last frame's
5143 // max mv magnitude and that based on the best ref mvs of the current
5144 // block for the given reference.
5145 step_param = (vp10_init_search_range(x->max_mv_context[ref]) +
5146 cpi->mv_step_param) / 2;
5147 } else {
5148 step_param = cpi->mv_step_param;
5149 }
5150
5151 if (cpi->sf.adaptive_motion_search && bsize < BLOCK_64X64) {
James Zern5e16d392015-08-17 18:19:22 -07005152 int boffset =
5153 2 * (b_width_log2_lookup[BLOCK_64X64] -
5154 VPXMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
5155 step_param = VPXMAX(step_param, boffset);
Jingning Han3ee6db62015-08-05 19:00:31 -07005156 }
5157
5158 if (cpi->sf.adaptive_motion_search) {
5159 int bwl = b_width_log2_lookup[bsize];
5160 int bhl = b_height_log2_lookup[bsize];
5161 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
5162
5163 if (tlevel < 5)
5164 step_param += 2;
5165
5166 // prev_mv_sad is not setup for dynamically scaled frames.
5167 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
5168 int i;
5169 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
5170 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
5171 x->pred_mv[ref].row = 0;
5172 x->pred_mv[ref].col = 0;
5173 tmp_mv->as_int = INVALID_MV;
5174
5175 if (scaled_ref_frame) {
5176 int i;
5177 for (i = 0; i < MAX_MB_PLANE; ++i)
5178 xd->plane[i].pre[0] = backup_yv12[i];
5179 }
5180 return;
5181 }
5182 }
5183 }
5184 }
5185
5186 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
5187
5188 mvp_full.col >>= 3;
5189 mvp_full.row >>= 3;
5190
5191 bestsme = vp10_full_pixel_search(cpi, x, bsize, &mvp_full, step_param, sadpb,
5192 cond_cost_list(cpi, cost_list),
5193 &ref_mv, &tmp_mv->as_mv, INT_MAX, 1);
5194
5195 x->mv_col_min = tmp_col_min;
5196 x->mv_col_max = tmp_col_max;
5197 x->mv_row_min = tmp_row_min;
5198 x->mv_row_max = tmp_row_max;
5199
5200 if (bestsme < INT_MAX) {
5201 int dis; /* TODO: use dis in distortion calculation later. */
Yunqing Wang342a3682016-02-16 14:33:18 -08005202#if CONFIG_AFFINE_MOTION
5203 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
5204 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
5205 // Use up-sampled reference frames.
5206 struct macroblockd_plane *const pd = &xd->plane[0];
5207 struct buf_2d backup_pred = pd->pre[0];
5208 const YV12_BUFFER_CONFIG *upsampled_ref = get_upsampled_ref(cpi, ref);
5209
5210 // Set pred for Y plane
5211 setup_pred_plane(&pd->pre[0], upsampled_ref->y_buffer,
5212 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3),
5213 NULL, pd->subsampling_x, pd->subsampling_y);
5214
5215 bestsme = cpi->find_fractional_mv_step(x, &tmp_mv->as_mv, &ref_mv,
5216 cm->allow_high_precision_mv,
5217 x->errorperbit,
5218 &cpi->fn_ptr[bsize],
5219 cpi->sf.mv.subpel_force_stop,
5220 cpi->sf.mv.subpel_iters_per_step,
5221 cond_cost_list(cpi, cost_list),
5222 x->nmvjointcost, x->mvcost,
5223 &dis, &x->pred_sse[ref], NULL,
5224 pw, ph, 1);
5225
5226 // Restore the reference frames.
5227 pd->pre[0] = backup_pred;
5228#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005229 cpi->find_fractional_mv_step(x, &tmp_mv->as_mv, &ref_mv,
5230 cm->allow_high_precision_mv,
5231 x->errorperbit,
5232 &cpi->fn_ptr[bsize],
5233 cpi->sf.mv.subpel_force_stop,
5234 cpi->sf.mv.subpel_iters_per_step,
5235 cond_cost_list(cpi, cost_list),
5236 x->nmvjointcost, x->mvcost,
5237 &dis, &x->pred_sse[ref], NULL, 0, 0);
Yunqing Wang342a3682016-02-16 14:33:18 -08005238#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07005239 }
5240 *rate_mv = vp10_mv_bit_cost(&tmp_mv->as_mv, &ref_mv,
5241 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5242
5243 if (cpi->sf.adaptive_motion_search)
5244 x->pred_mv[ref] = tmp_mv->as_mv;
5245
5246 if (scaled_ref_frame) {
5247 int i;
5248 for (i = 0; i < MAX_MB_PLANE; i++)
5249 xd->plane[i].pre[0] = backup_yv12[i];
5250 }
5251}
5252
Jingning Han3ee6db62015-08-05 19:00:31 -07005253static INLINE void restore_dst_buf(MACROBLOCKD *xd,
5254 uint8_t *orig_dst[MAX_MB_PLANE],
5255 int orig_dst_stride[MAX_MB_PLANE]) {
5256 int i;
5257 for (i = 0; i < MAX_MB_PLANE; i++) {
5258 xd->plane[i].dst.buf = orig_dst[i];
5259 xd->plane[i].dst.stride = orig_dst_stride[i];
5260 }
5261}
5262
5263// In some situations we want to discount tha pparent cost of a new motion
5264// vector. Where there is a subtle motion field and especially where there is
5265// low spatial complexity then it can be hard to cover the cost of a new motion
5266// vector in a single block, even if that motion vector reduces distortion.
5267// However, once established that vector may be usable through the nearest and
5268// near mv modes to reduce distortion in subsequent blocks and also improve
5269// visual quality.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07005270static int discount_newmv_test(const VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07005271 int this_mode,
5272 int_mv this_mv,
5273 int_mv (*mode_mv)[MAX_REF_FRAMES],
5274 int ref_frame) {
5275 return (!cpi->rc.is_src_frame_alt_ref &&
5276 (this_mode == NEWMV) &&
5277 (this_mv.as_int != 0) &&
5278 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
5279 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
5280 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
5281 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
5282}
5283
Ronald S. Bultje5b4805d2015-10-02 11:51:54 -04005284#define LEFT_TOP_MARGIN ((VP9_ENC_BORDER_IN_PIXELS - VP9_INTERP_EXTEND) << 3)
5285#define RIGHT_BOTTOM_MARGIN ((VP9_ENC_BORDER_IN_PIXELS -\
5286 VP9_INTERP_EXTEND) << 3)
5287
5288// TODO(jingning): this mv clamping function should be block size dependent.
5289static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
5290 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
5291 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
5292 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
5293 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
5294}
Angie Chiangc0035cc2016-02-10 14:20:56 -08005295static INTERP_FILTER predict_interp_filter(const VP10_COMP *cpi,
5296 const MACROBLOCK *x,
5297 const BLOCK_SIZE bsize,
5298 const int mi_row,
5299 const int mi_col,
5300 INTERP_FILTER
5301 (*single_filter)[MAX_REF_FRAMES]
5302 ) {
Jingning Han3ee6db62015-08-05 19:00:31 -07005303 INTERP_FILTER best_filter = SWITCHABLE;
Angie Chiangc0035cc2016-02-10 14:20:56 -08005304 const VP10_COMMON *cm = &cpi->common;
5305 const MACROBLOCKD *xd = &x->e_mbd;
Jingning Han3ee6db62015-08-05 19:00:31 -07005306 int bsl = mi_width_log2_lookup[bsize];
5307 int pred_filter_search = cpi->sf.cb_pred_filter_search ?
5308 (((mi_row + mi_col) >> bsl) +
Yue Chend1cad9c2016-01-27 14:18:53 -08005309 get_chessboard_index(cm->current_video_frame)) & 0x1 : 0;
Angie Chiangc0035cc2016-02-10 14:20:56 -08005310 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5311 const int is_comp_pred = has_second_ref(mbmi);
5312 const int this_mode = mbmi->mode;
5313 int refs[2] = { mbmi->ref_frame[0],
Yue Chend1cad9c2016-01-27 14:18:53 -08005314 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Jingning Han3ee6db62015-08-05 19:00:31 -07005315 if (pred_filter_search) {
5316 INTERP_FILTER af = SWITCHABLE, lf = SWITCHABLE;
5317 if (xd->up_available)
5318 af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
5319 if (xd->left_available)
5320 lf = xd->mi[-1]->mbmi.interp_filter;
5321
Yue Chen1ac85872016-01-07 15:13:52 -08005322#if CONFIG_EXT_INTER
Yue Chen968bbc72016-01-19 16:45:45 -08005323 if ((this_mode != NEWMV && this_mode != NEWFROMNEARMV &&
5324 this_mode != NEW_NEWMV) || (af == lf))
Yue Chen1ac85872016-01-07 15:13:52 -08005325#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005326 if ((this_mode != NEWMV) || (af == lf))
Yue Chen1ac85872016-01-07 15:13:52 -08005327#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005328 best_filter = af;
5329 }
Jingning Han3ee6db62015-08-05 19:00:31 -07005330 if (is_comp_pred) {
Jingning Han3ee6db62015-08-05 19:00:31 -07005331 if (cpi->sf.adaptive_mode_search) {
Yue Chen968bbc72016-01-19 16:45:45 -08005332#if CONFIG_EXT_INTER
5333 switch (this_mode) {
5334 case NEAREST_NEARESTMV:
5335 if (single_filter[NEARESTMV][refs[0]] ==
5336 single_filter[NEARESTMV][refs[1]])
5337 best_filter = single_filter[NEARESTMV][refs[0]];
5338 break;
5339 case NEAREST_NEARMV:
5340 if (single_filter[NEARESTMV][refs[0]] ==
5341 single_filter[NEARMV][refs[1]])
5342 best_filter = single_filter[NEARESTMV][refs[0]];
5343 break;
5344 case NEAR_NEARESTMV:
5345 if (single_filter[NEARMV][refs[0]] ==
5346 single_filter[NEARESTMV][refs[1]])
5347 best_filter = single_filter[NEARMV][refs[0]];
5348 break;
5349 case ZERO_ZEROMV:
5350 if (single_filter[ZEROMV][refs[0]] ==
5351 single_filter[ZEROMV][refs[1]])
5352 best_filter = single_filter[ZEROMV][refs[0]];
5353 break;
5354 case NEW_NEWMV:
5355 if (single_filter[NEWMV][refs[0]] ==
5356 single_filter[NEWMV][refs[1]])
5357 best_filter = single_filter[NEWMV][refs[0]];
5358 break;
5359 case NEAREST_NEWMV:
5360 if (single_filter[NEARESTMV][refs[0]] ==
5361 single_filter[NEWMV][refs[1]])
5362 best_filter = single_filter[NEARESTMV][refs[0]];
5363 break;
5364 case NEAR_NEWMV:
5365 if (single_filter[NEARMV][refs[0]] ==
5366 single_filter[NEWMV][refs[1]])
5367 best_filter = single_filter[NEARMV][refs[0]];
5368 break;
5369 case NEW_NEARESTMV:
5370 if (single_filter[NEWMV][refs[0]] ==
5371 single_filter[NEARESTMV][refs[1]])
5372 best_filter = single_filter[NEWMV][refs[0]];
5373 break;
5374 case NEW_NEARMV:
5375 if (single_filter[NEWMV][refs[0]] ==
5376 single_filter[NEARMV][refs[1]])
5377 best_filter = single_filter[NEWMV][refs[0]];
5378 break;
5379 default:
5380 if (single_filter[this_mode][refs[0]] ==
5381 single_filter[this_mode][refs[1]])
5382 best_filter = single_filter[this_mode][refs[0]];
5383 break;
5384 }
5385#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005386 if (single_filter[this_mode][refs[0]] ==
5387 single_filter[this_mode][refs[1]])
5388 best_filter = single_filter[this_mode][refs[0]];
Yue Chen968bbc72016-01-19 16:45:45 -08005389#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005390 }
5391 }
Angie Chiangc0035cc2016-02-10 14:20:56 -08005392 if (cm->interp_filter != BILINEAR) {
5393 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
Debargha Mukherjeebab29122016-02-26 00:18:03 -08005394 best_filter = EIGHTTAP_REGULAR;
Angie Chiangc0035cc2016-02-10 14:20:56 -08005395 }
5396#if CONFIG_EXT_INTERP
5397 else if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE) {
Debargha Mukherjeebab29122016-02-26 00:18:03 -08005398 best_filter = EIGHTTAP_REGULAR;
Angie Chiangc0035cc2016-02-10 14:20:56 -08005399 }
5400#endif
5401 }
5402 return best_filter;
5403}
5404
5405static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
5406 BLOCK_SIZE bsize,
5407 int *rate2, int64_t *distortion,
5408 int *skippable,
5409 int *rate_y, int *rate_uv,
5410 int *disable_skip,
5411 int_mv (*mode_mv)[MAX_REF_FRAMES],
5412 int mi_row, int mi_col,
Yue Chend1cad9c2016-01-27 14:18:53 -08005413#if CONFIG_OBMC
5414 uint8_t *dst_buf1[3],
5415 int dst_stride1[3],
5416 uint8_t *dst_buf2[3],
5417 int dst_stride2[3],
5418#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005419#if CONFIG_EXT_INTER
5420 int_mv single_newmvs[2][MAX_REF_FRAMES],
Geza Lore7ded0382016-02-22 10:55:32 +00005421 int single_newmvs_rate[2][MAX_REF_FRAMES],
5422 int *compmode_interintra_cost,
Angie Chiangc0035cc2016-02-10 14:20:56 -08005423#else
5424 int_mv single_newmv[MAX_REF_FRAMES],
5425#endif // CONFIG_EXT_INTER
5426 INTERP_FILTER (*single_filter)[MAX_REF_FRAMES],
5427 int (*single_skippable)[MAX_REF_FRAMES],
5428 int64_t *psse,
5429 const int64_t ref_best_rd,
5430 int64_t *mask_filter,
5431 int64_t filter_cache[]) {
5432 VP10_COMMON *cm = &cpi->common;
5433 MACROBLOCKD *xd = &x->e_mbd;
5434 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5435 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
5436 const int is_comp_pred = has_second_ref(mbmi);
5437 const int this_mode = mbmi->mode;
5438 int_mv *frame_mv = mode_mv[this_mode];
5439 int i;
5440 int refs[2] = { mbmi->ref_frame[0],
5441 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
5442 int_mv cur_mv[2];
5443#if CONFIG_EXT_INTER
5444 int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
5445 int_mv single_newmv[MAX_REF_FRAMES];
Geza Lore7ded0382016-02-22 10:55:32 +00005446 const int * const intra_mode_cost =
5447 cpi->mbmode_cost[size_group_lookup[bsize]];
5448 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
Angie Chiangc0035cc2016-02-10 14:20:56 -08005449#if CONFIG_REF_MV
5450 uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
5451#endif
5452#endif // CONFIG_EXT_INTER
5453#if CONFIG_VP9_HIGHBITDEPTH
5454 DECLARE_ALIGNED(16, uint16_t, tmp_buf16[MAX_MB_PLANE * 64 * 64]);
5455 uint8_t *tmp_buf;
5456#else
5457 DECLARE_ALIGNED(16, uint8_t, tmp_buf[MAX_MB_PLANE * 64 * 64]);
5458#endif // CONFIG_VP9_HIGHBITDEPTH
Geza Lore7ded0382016-02-22 10:55:32 +00005459#if CONFIG_EXT_INTER
5460 const int tmp_buf_sz = CU_SIZE * CU_SIZE;
5461#endif // CONFIG_EXT_INTER
Yue Chend1cad9c2016-01-27 14:18:53 -08005462#if CONFIG_OBMC
Yue Chen907f88c2016-02-16 12:22:11 -08005463 int allow_obmc = is_obmc_allowed(mbmi);
5464 int best_obmc_flag = 0;
Yue Chend1cad9c2016-01-27 14:18:53 -08005465#if CONFIG_VP9_HIGHBITDEPTH
5466 DECLARE_ALIGNED(16, uint16_t, tmp_buf1_16[MAX_MB_PLANE * 64 * 64]);
Yue Chena6142622016-02-18 12:35:14 -08005467 DECLARE_ALIGNED(16, uint16_t, tmp_buf2_16[MAX_MB_PLANE * 64 * 64]);
5468 uint8_t *tmp_buf1, *tmp_buf2;
5469 uint8_t *obmc_tmp_buf1[3];
5470 uint8_t *obmc_tmp_buf2[3];
Yue Chend1cad9c2016-01-27 14:18:53 -08005471#else
5472 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * 64 * 64]);
Yue Chena6142622016-02-18 12:35:14 -08005473 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * 64 * 64]);
5474 uint8_t *obmc_tmp_buf1[3] = {tmp_buf1, tmp_buf1 + 4096, tmp_buf1 + 8192};
5475 uint8_t *obmc_tmp_buf2[3] = {tmp_buf2, tmp_buf2 + 4096, tmp_buf2 + 8192};
Yue Chend1cad9c2016-01-27 14:18:53 -08005476#endif // CONFIG_VP9_HIGHBITDEPTH
5477 int obmc_tmp_stride[3] = {64, 64, 64};
Yue Chena6142622016-02-18 12:35:14 -08005478
5479 uint8_t skip_txfm_bestfilter[2][MAX_MB_PLANE << 2] = {{0}, {0}};
5480 int64_t bsse_bestfilter[2][MAX_MB_PLANE << 2] = {{0}, {0}};
5481 int skip_txfm_sb_bestfilter[2] = {0};
5482 int64_t skip_sse_sb_bestfilter[2] = {INT64_MAX};
5483
5484 int rate2_nocoeff, best_rate2 = INT_MAX,
5485 best_skippable, best_xskip, best_disable_skip = 0;
5486#if CONFIG_SUPERTX
5487 int best_rate_y, best_rate_uv;
5488#endif // CONFIG_SUPERTX
5489#if CONFIG_VAR_TX
5490 uint8_t best_blk_skip[3][256];
5491#endif // CONFIG_VAR_TX
5492 int64_t best_distortion = INT64_MAX;
5493 unsigned int best_pred_var = UINT_MAX;
5494 MB_MODE_INFO best_mbmi;
Yue Chend1cad9c2016-01-27 14:18:53 -08005495#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005496 int pred_exists = 0;
5497 int intpel_mv;
5498 int64_t rd, tmp_rd, best_rd = INT64_MAX;
5499 int best_needs_copy = 0;
5500 uint8_t *orig_dst[MAX_MB_PLANE];
5501 int orig_dst_stride[MAX_MB_PLANE];
5502 int rs = 0;
5503 INTERP_FILTER best_filter = SWITCHABLE;
5504 uint8_t skip_txfm[MAX_MB_PLANE << 2] = {0};
5505 int64_t bsse[MAX_MB_PLANE << 2] = {0};
5506
5507 int skip_txfm_sb = 0;
5508 int64_t skip_sse_sb = INT64_MAX;
5509 int64_t distortion_y = 0, distortion_uv = 0;
5510 int16_t mode_ctx = mbmi_ext->mode_context[refs[0]];
5511
Geza Lore7ded0382016-02-22 10:55:32 +00005512#if CONFIG_EXT_INTER
5513 *compmode_interintra_cost = 0;
5514
5515 // is_comp_interintra_pred implies !is_comp_pred
5516 assert(!is_comp_interintra_pred || (!is_comp_pred));
5517 // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
5518 assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
5519#endif // CONFIG_EXT_INTER
5520
Yue Chend1cad9c2016-01-27 14:18:53 -08005521#if CONFIG_OBMC
5522 tmp_rd = 0;
5523#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005524#if CONFIG_REF_MV
5525#if CONFIG_EXT_INTER
5526 if (is_comp_pred)
5527 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
5528 else
5529#endif // CONFIG_EXT_INTER
5530 mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
5531 mbmi->ref_frame, bsize, -1);
5532#endif
5533
5534#if CONFIG_VP9_HIGHBITDEPTH
5535 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5536 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf16);
Yue Chend1cad9c2016-01-27 14:18:53 -08005537#if CONFIG_OBMC
5538 tmp_buf1 = CONVERT_TO_BYTEPTR(tmp_buf1_16);
Yue Chena6142622016-02-18 12:35:14 -08005539 tmp_buf2 = CONVERT_TO_BYTEPTR(tmp_buf2_16);
Yue Chend1cad9c2016-01-27 14:18:53 -08005540#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005541 } else {
5542 tmp_buf = (uint8_t *)tmp_buf16;
Yue Chend1cad9c2016-01-27 14:18:53 -08005543#if CONFIG_OBMC
5544 tmp_buf1 = (uint8_t *)tmp_buf1_16;
Yue Chena6142622016-02-18 12:35:14 -08005545 tmp_buf2 = (uint8_t *)tmp_buf2_16;
Yue Chend1cad9c2016-01-27 14:18:53 -08005546#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005547 }
Yue Chend1cad9c2016-01-27 14:18:53 -08005548#if CONFIG_OBMC
Yue Chena6142622016-02-18 12:35:14 -08005549 obmc_tmp_buf1[0] = tmp_buf1;
5550 obmc_tmp_buf1[1] = tmp_buf1 + 4096;
5551 obmc_tmp_buf1[2] = tmp_buf1 + 8192;
5552 obmc_tmp_buf2[0] = tmp_buf2;
5553 obmc_tmp_buf2[1] = tmp_buf2 + 4096;
5554 obmc_tmp_buf2[2] = tmp_buf2 + 8192;
Yue Chend1cad9c2016-01-27 14:18:53 -08005555#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005556#endif // CONFIG_VP9_HIGHBITDEPTH
5557
5558 if (is_comp_pred) {
5559 if (frame_mv[refs[0]].as_int == INVALID_MV ||
5560 frame_mv[refs[1]].as_int == INVALID_MV)
5561 return INT64_MAX;
5562 }
Jingning Han3ee6db62015-08-05 19:00:31 -07005563
Yue Chen1ac85872016-01-07 15:13:52 -08005564#if CONFIG_EXT_INTER
5565 if (have_newmv_in_inter_mode(this_mode)) {
5566#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005567 if (this_mode == NEWMV) {
Yue Chen1ac85872016-01-07 15:13:52 -08005568#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005569 int rate_mv;
5570 if (is_comp_pred) {
Yue Chen1ac85872016-01-07 15:13:52 -08005571#if CONFIG_EXT_INTER
5572 for (i = 0; i < 2; ++i) {
5573 single_newmv[refs[i]].as_int =
Yue Chen968bbc72016-01-19 16:45:45 -08005574 single_newmvs[mv_idx][refs[i]].as_int;
Yue Chen1ac85872016-01-07 15:13:52 -08005575 }
Yue Chen968bbc72016-01-19 16:45:45 -08005576
5577 if (this_mode == NEW_NEWMV) {
5578 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
5579 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
5580
5581 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
5582 joint_motion_search(cpi, x, bsize, frame_mv,
Yunqing Wang342a3682016-02-16 14:33:18 -08005583 mi_row, mi_col, NULL, single_newmv, &rate_mv, 0);
Yue Chen968bbc72016-01-19 16:45:45 -08005584 } else {
5585 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
5586 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
5587 x->nmvjointcost, x->mvcost,
5588 MV_COST_WEIGHT);
5589 rate_mv += vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
5590 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
5591 x->nmvjointcost, x->mvcost,
5592 MV_COST_WEIGHT);
5593 }
5594 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
5595 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
5596 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
5597 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
5598 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5599 } else {
5600 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
5601 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
5602 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
5603 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5604 }
5605#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005606 // Initialize mv using single prediction mode result.
5607 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
5608 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
5609
5610 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
5611 joint_motion_search(cpi, x, bsize, frame_mv,
Yue Chen1ac85872016-01-07 15:13:52 -08005612 mi_row, mi_col,
Yunqing Wang342a3682016-02-16 14:33:18 -08005613 single_newmv, &rate_mv, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07005614 } else {
5615 rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
5616 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
5617 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5618 rate_mv += vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
5619 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
5620 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5621 }
Yue Chen968bbc72016-01-19 16:45:45 -08005622#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005623 } else {
5624 int_mv tmp_mv;
Geza Lore7ded0382016-02-22 10:55:32 +00005625
Yue Chen1ac85872016-01-07 15:13:52 -08005626#if CONFIG_EXT_INTER
Geza Lore7ded0382016-02-22 10:55:32 +00005627 if (is_comp_interintra_pred) {
5628 tmp_mv = single_newmvs[mv_idx][refs[0]];
5629 rate_mv = single_newmvs_rate[mv_idx][refs[0]];
5630 } else {
5631 single_motion_search(cpi, x, bsize, mi_row, mi_col,
5632 0, mv_idx, &tmp_mv, &rate_mv);
5633 single_newmvs[mv_idx][refs[0]] = tmp_mv;
5634 single_newmvs_rate[mv_idx][refs[0]] = rate_mv;
5635 }
5636#else
5637 single_motion_search(cpi, x, bsize, mi_row, mi_col, &tmp_mv, &rate_mv);
5638 single_newmv[refs[0]] = tmp_mv;
Yue Chen1ac85872016-01-07 15:13:52 -08005639#endif // CONFIG_EXT_INTER
Geza Lore7ded0382016-02-22 10:55:32 +00005640
Jingning Han3ee6db62015-08-05 19:00:31 -07005641 if (tmp_mv.as_int == INVALID_MV)
5642 return INT64_MAX;
5643
Geza Lore7ded0382016-02-22 10:55:32 +00005644 frame_mv[refs[0]] = tmp_mv;
5645 xd->mi[0]->bmi[0].as_mv[0] = tmp_mv;
Jingning Han3ee6db62015-08-05 19:00:31 -07005646
5647 // Estimate the rate implications of a new mv but discount this
5648 // under certain circumstances where we want to help initiate a weak
5649 // motion field, where the distortion gain for a single block may not
5650 // be enough to overcome the cost of a new mv.
5651 if (discount_newmv_test(cpi, this_mode, tmp_mv, mode_mv, refs[0])) {
Geza Lore7ded0382016-02-22 10:55:32 +00005652 rate_mv = VPXMAX((rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Jingning Han3ee6db62015-08-05 19:00:31 -07005653 }
5654 }
Geza Lore7ded0382016-02-22 10:55:32 +00005655 *rate2 += rate_mv;
Jingning Han3ee6db62015-08-05 19:00:31 -07005656 }
5657
5658 for (i = 0; i < is_comp_pred + 1; ++i) {
5659 cur_mv[i] = frame_mv[refs[i]];
5660 // Clip "next_nearest" so that it does not extend to far out of image
Yue Chen1ac85872016-01-07 15:13:52 -08005661#if CONFIG_EXT_INTER
5662 if (this_mode != NEWMV && this_mode != NEWFROMNEARMV)
5663#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005664 if (this_mode != NEWMV)
Yue Chen1ac85872016-01-07 15:13:52 -08005665#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005666 clamp_mv2(&cur_mv[i].as_mv, xd);
5667
5668 if (mv_check_bounds(x, &cur_mv[i].as_mv))
5669 return INT64_MAX;
5670 mbmi->mv[i].as_int = cur_mv[i].as_int;
5671 }
5672
Jingning Han33cc1bd2016-01-12 15:06:59 -08005673#if CONFIG_REF_MV
Yue Chen968bbc72016-01-19 16:45:45 -08005674#if CONFIG_EXT_INTER
5675 if (this_mode == NEAREST_NEARESTMV) {
5676#else
Jingning Han33cc1bd2016-01-12 15:06:59 -08005677 if (this_mode == NEARESTMV && is_comp_pred) {
5678 uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
Yue Chen968bbc72016-01-19 16:45:45 -08005679#endif // CONFIG_EXT_INTER
Jingning Han3944cfb2016-01-13 09:03:15 -08005680 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
Jingning Han33cc1bd2016-01-12 15:06:59 -08005681 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
5682 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
5683
5684 for (i = 0; i < 2; ++i) {
5685 lower_mv_precision(&cur_mv[i].as_mv, cm->allow_high_precision_mv);
5686 clamp_mv2(&cur_mv[i].as_mv, xd);
5687 if (mv_check_bounds(x, &cur_mv[i].as_mv))
5688 return INT64_MAX;
5689 mbmi->mv[i].as_int = cur_mv[i].as_int;
5690 }
5691 }
5692 }
5693
Yue Chen968bbc72016-01-19 16:45:45 -08005694#if CONFIG_EXT_INTER
5695 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
5696 if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
5697 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
5698
5699 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
5700 clamp_mv2(&cur_mv[0].as_mv, xd);
5701 if (mv_check_bounds(x, &cur_mv[0].as_mv))
5702 return INT64_MAX;
5703 mbmi->mv[0].as_int = cur_mv[0].as_int;
5704 }
5705
5706 if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
5707 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
5708
5709 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
5710 clamp_mv2(&cur_mv[1].as_mv, xd);
5711 if (mv_check_bounds(x, &cur_mv[1].as_mv))
5712 return INT64_MAX;
5713 mbmi->mv[1].as_int = cur_mv[1].as_int;
5714 }
5715 }
5716
5717 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
5718 if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV) {
5719 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][1].this_mv;
5720
5721 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
5722 clamp_mv2(&cur_mv[0].as_mv, xd);
5723 if (mv_check_bounds(x, &cur_mv[0].as_mv))
5724 return INT64_MAX;
5725 mbmi->mv[0].as_int = cur_mv[0].as_int;
5726 }
5727
5728 if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV) {
5729 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][1].comp_mv;
5730
5731 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
5732 clamp_mv2(&cur_mv[1].as_mv, xd);
5733 if (mv_check_bounds(x, &cur_mv[1].as_mv))
5734 return INT64_MAX;
5735 mbmi->mv[1].as_int = cur_mv[1].as_int;
5736 }
5737 }
5738#else
Jingning Han33cc1bd2016-01-12 15:06:59 -08005739 if (this_mode == NEARMV && is_comp_pred) {
5740 uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
5741 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
Jingning Han95247be2016-02-17 09:27:08 -08005742 int ref_mv_idx = mbmi->ref_mv_idx + 1;
5743 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
5744 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
Jingning Han33cc1bd2016-01-12 15:06:59 -08005745
5746 for (i = 0; i < 2; ++i) {
5747 lower_mv_precision(&cur_mv[i].as_mv, cm->allow_high_precision_mv);
5748 clamp_mv2(&cur_mv[i].as_mv, xd);
5749 if (mv_check_bounds(x, &cur_mv[i].as_mv))
5750 return INT64_MAX;
5751 mbmi->mv[i].as_int = cur_mv[i].as_int;
5752 }
5753 }
5754 }
Yue Chen968bbc72016-01-19 16:45:45 -08005755#endif // CONFIG_EXT_INTER
Jingning Han33cc1bd2016-01-12 15:06:59 -08005756#endif
5757
Jingning Han3ee6db62015-08-05 19:00:31 -07005758 // do first prediction into the destination buffer. Do the next
5759 // prediction into a temporary buffer. Then keep track of which one
5760 // of these currently holds the best predictor, and use the other
5761 // one for future predictions. In the end, copy from tmp_buf to
5762 // dst if necessary.
5763 for (i = 0; i < MAX_MB_PLANE; i++) {
5764 orig_dst[i] = xd->plane[i].dst.buf;
5765 orig_dst_stride[i] = xd->plane[i].dst.stride;
5766 }
5767
5768 // We don't include the cost of the second reference here, because there
5769 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
5770 // words if you present them in that order, the second one is always known
5771 // if the first is known.
5772 //
5773 // Under some circumstances we discount the cost of new mv mode to encourage
5774 // initiation of a motion field.
5775 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]],
5776 mode_mv, refs[0])) {
Yue Chen1ac85872016-01-07 15:13:52 -08005777#if CONFIG_REF_MV && CONFIG_EXT_INTER
5778 *rate2 += VPXMIN(cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx),
5779 cost_mv_ref(cpi, NEARESTMV, is_comp_pred, mode_ctx));
5780#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08005781 *rate2 += VPXMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
5782 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
Yue Chen1ac85872016-01-07 15:13:52 -08005783#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005784 } else {
Yue Chen1ac85872016-01-07 15:13:52 -08005785#if CONFIG_REF_MV && CONFIG_EXT_INTER
5786 *rate2 += cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx);
5787#else
Jingning Hanaa5d53e2015-12-07 15:54:59 -08005788 *rate2 += cost_mv_ref(cpi, this_mode, mode_ctx);
Yue Chen1ac85872016-01-07 15:13:52 -08005789#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005790 }
5791
5792 if (RDCOST(x->rdmult, x->rddiv, *rate2, 0) > ref_best_rd &&
Yue Chen968bbc72016-01-19 16:45:45 -08005793#if CONFIG_EXT_INTER
5794 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV)
5795#else
Jingning Han3ee6db62015-08-05 19:00:31 -07005796 mbmi->mode != NEARESTMV)
Yue Chen968bbc72016-01-19 16:45:45 -08005797#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005798 return INT64_MAX;
5799
5800 pred_exists = 0;
5801 // Are all MVs integer pel for Y and UV
5802 intpel_mv = !mv_has_subpel(&mbmi->mv[0].as_mv);
5803 if (is_comp_pred)
5804 intpel_mv &= !mv_has_subpel(&mbmi->mv[1].as_mv);
5805
5806 // Search for best switchable filter by checking the variance of
5807 // pred error irrespective of whether the filter will be used
5808 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
5809 filter_cache[i] = INT64_MAX;
5810
Angie Chiangc0035cc2016-02-10 14:20:56 -08005811 best_filter = predict_interp_filter(cpi, x, bsize, mi_row, mi_col,
5812 single_filter);
5813 if (cm->interp_filter != BILINEAR && best_filter == SWITCHABLE) {
5814 int newbest;
5815 int tmp_rate_sum = 0;
5816 int64_t tmp_dist_sum = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07005817
Angie Chiangc0035cc2016-02-10 14:20:56 -08005818 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
5819 int j;
5820 int64_t rs_rd;
5821 int tmp_skip_sb = 0;
5822 int64_t tmp_skip_sse = INT64_MAX;
Yue Chend1cad9c2016-01-27 14:18:53 -08005823#if CONFIG_OBMC
5824 int obmc_flag = 0;
5825 int tmp_skip_sb_obmc = 0;
5826 int64_t tmp_skip_sse_obmc = INT64_MAX;
Yue Chena6142622016-02-18 12:35:14 -08005827 int64_t rdobmc = INT64_MAX;
5828 uint8_t *obmc_tmp_buf[3];
5829 uint8_t tmp_skip_txfm[MAX_MB_PLANE << 2] = {0};
5830 int64_t tmp_bsse[MAX_MB_PLANE << 2] = {0};
Yue Chend1cad9c2016-01-27 14:18:53 -08005831#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07005832
Angie Chiangc0035cc2016-02-10 14:20:56 -08005833 mbmi->interp_filter = i;
5834 rs = vp10_get_switchable_rate(cpi, xd);
5835 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07005836
Angie Chiangc0035cc2016-02-10 14:20:56 -08005837 if (i > 0 && intpel_mv && IsInterpolatingFilter(i)) {
5838 rd = RDCOST(x->rdmult, x->rddiv, tmp_rate_sum, tmp_dist_sum);
5839 filter_cache[i] = rd;
5840 filter_cache[SWITCHABLE_FILTERS] =
5841 VPXMIN(filter_cache[SWITCHABLE_FILTERS], rd + rs_rd);
5842 if (cm->interp_filter == SWITCHABLE)
5843 rd += rs_rd;
Yue Chend1cad9c2016-01-27 14:18:53 -08005844#if CONFIG_OBMC
5845 if (allow_obmc) {
5846 obmc_flag = best_obmc_flag;
5847 rd += RDCOST(x->rdmult, x->rddiv,
5848 cpi->obmc_cost[bsize][obmc_flag], 0);
5849 }
5850#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005851 *mask_filter = VPXMAX(*mask_filter, rd);
5852 } else {
5853 int rate_sum = 0;
5854 int64_t dist_sum = 0;
Yue Chend1cad9c2016-01-27 14:18:53 -08005855#if CONFIG_OBMC
5856 int rate_sum_obmc = 0;
5857 int64_t dist_sum_obmc = 0;
5858#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005859 if (i > 0 && cpi->sf.adaptive_interp_filter_search &&
5860 (cpi->sf.interp_filter_search_mask & (1 << i))) {
5861 rate_sum = INT_MAX;
5862 dist_sum = INT64_MAX;
5863 continue;
Jingning Han3ee6db62015-08-05 19:00:31 -07005864 }
5865
Angie Chiangc0035cc2016-02-10 14:20:56 -08005866 if ((cm->interp_filter == SWITCHABLE &&
5867 (!i || best_needs_copy)) ||
Geza Lore7ded0382016-02-22 10:55:32 +00005868#if CONFIG_EXT_INTER
5869 is_comp_interintra_pred ||
5870#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07005871 (cm->interp_filter != SWITCHABLE &&
Angie Chiangc0035cc2016-02-10 14:20:56 -08005872 (cm->interp_filter == mbmi->interp_filter ||
5873 (i == 0 && intpel_mv && IsInterpolatingFilter(i))))) {
5874 restore_dst_buf(xd, orig_dst, orig_dst_stride);
Yue Chena6142622016-02-18 12:35:14 -08005875#if CONFIG_OBMC
5876 for (j = 0; j < MAX_MB_PLANE; j++) {
5877 obmc_tmp_buf[j] = obmc_tmp_buf1[j];
5878 }
5879#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005880 } else {
5881 for (j = 0; j < MAX_MB_PLANE; j++) {
5882 xd->plane[j].dst.buf = tmp_buf + j * 64 * 64;
5883 xd->plane[j].dst.stride = 64;
Yue Chena6142622016-02-18 12:35:14 -08005884#if CONFIG_OBMC
5885 obmc_tmp_buf[j] = obmc_tmp_buf2[j];
5886#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005887 }
5888 }
5889 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
5890 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
5891 &tmp_skip_sb, &tmp_skip_sse);
Jingning Han3ee6db62015-08-05 19:00:31 -07005892
Angie Chiangc0035cc2016-02-10 14:20:56 -08005893 rd = RDCOST(x->rdmult, x->rddiv, rate_sum, dist_sum);
Yue Chend1cad9c2016-01-27 14:18:53 -08005894#if CONFIG_OBMC
5895 if (allow_obmc) {
5896 rd += RDCOST(x->rdmult, x->rddiv, cpi->obmc_cost[bsize][0], 0);
5897 memcpy(tmp_skip_txfm, x->skip_txfm, sizeof(tmp_skip_txfm));
5898 memcpy(tmp_bsse, x->bsse, sizeof(tmp_bsse));
5899
5900 vp10_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, 1,
5901 obmc_tmp_buf, obmc_tmp_stride,
5902 dst_buf1, dst_stride1,
5903 dst_buf2, dst_stride2);
5904 for (j = 0; j < MAX_MB_PLANE; ++j) {
5905 xd->plane[j].dst.buf = obmc_tmp_buf[j];
5906 xd->plane[j].dst.stride = obmc_tmp_stride[j];
5907 }
5908 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum_obmc, &dist_sum_obmc,
5909 &tmp_skip_sb_obmc, &tmp_skip_sse_obmc);
5910 rdobmc = RDCOST(x->rdmult, x->rddiv,
5911 rate_sum_obmc + cpi->obmc_cost[bsize][1],
5912 dist_sum_obmc);
5913
5914 if ((double)rdobmc <= 0.99 * (double)rd) {
5915 obmc_flag = 1;
5916 rd = rdobmc;
5917 rate_sum = rate_sum_obmc;
5918 dist_sum = dist_sum_obmc;
Yue Chend1cad9c2016-01-27 14:18:53 -08005919 }
5920 }
5921#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005922 filter_cache[i] = rd;
5923 filter_cache[SWITCHABLE_FILTERS] =
5924 VPXMIN(filter_cache[SWITCHABLE_FILTERS], rd + rs_rd);
5925 if (cm->interp_filter == SWITCHABLE)
5926 rd += rs_rd;
5927 *mask_filter = VPXMAX(*mask_filter, rd);
5928
5929 if (i == 0 && intpel_mv && IsInterpolatingFilter(i)) {
5930 tmp_rate_sum = rate_sum;
5931 tmp_dist_sum = dist_sum;
Jingning Han3ee6db62015-08-05 19:00:31 -07005932 }
5933 }
Angie Chiangc0035cc2016-02-10 14:20:56 -08005934
5935 if (i == 0 && cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
5936 if (rd / 2 > ref_best_rd) {
5937 restore_dst_buf(xd, orig_dst, orig_dst_stride);
5938 return INT64_MAX;
5939 }
5940 }
5941 newbest = i == 0 || rd < best_rd;
5942
5943 if (newbest) {
Yue Chena6142622016-02-18 12:35:14 -08005944#if CONFIG_OBMC
5945 if (allow_obmc)
5946 best_obmc_flag = obmc_flag;
5947#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005948 best_rd = rd;
5949 best_filter = mbmi->interp_filter;
5950 if (cm->interp_filter == SWITCHABLE && i &&
5951 !(intpel_mv && IsInterpolatingFilter(i)))
5952 best_needs_copy = !best_needs_copy;
5953 }
5954
5955 if ((cm->interp_filter == SWITCHABLE && newbest) ||
5956 (cm->interp_filter != SWITCHABLE &&
5957 cm->interp_filter == mbmi->interp_filter)) {
5958 pred_exists = 1;
5959 tmp_rd = best_rd;
5960
Yue Chena6142622016-02-18 12:35:14 -08005961#if CONFIG_OBMC
5962 if (allow_obmc) {
5963 skip_txfm_sb_bestfilter[0] = tmp_skip_sb;
5964 skip_sse_sb_bestfilter[0] = tmp_skip_sse;
5965 memcpy(skip_txfm_bestfilter[0], tmp_skip_txfm, sizeof(skip_txfm));
5966 memcpy(bsse_bestfilter[0], tmp_bsse, sizeof(bsse));
5967
5968 skip_txfm_sb_bestfilter[1] = tmp_skip_sb_obmc;
5969 skip_sse_sb_bestfilter[1] = tmp_skip_sse_obmc;
5970 memcpy(skip_txfm_bestfilter[1], x->skip_txfm, sizeof(skip_txfm));
5971 memcpy(bsse_bestfilter[1], x->bsse, sizeof(bsse));
5972 if (best_obmc_flag) {
5973 tmp_skip_sb = tmp_skip_sb_obmc;
5974 tmp_skip_sse = tmp_skip_sse_obmc;
5975 } else {
5976 memcpy(x->skip_txfm, tmp_skip_txfm, sizeof(tmp_skip_txfm));
5977 memcpy(x->bsse, tmp_bsse, sizeof(tmp_bsse));
5978 }
5979 } else {
5980 skip_txfm_sb_bestfilter[0] = tmp_skip_sb;
5981 skip_sse_sb_bestfilter[0] = tmp_skip_sse;
5982 memcpy(skip_txfm_bestfilter[0], x->skip_txfm, sizeof(skip_txfm));
5983 memcpy(bsse_bestfilter[0], x->bsse, sizeof(bsse));
5984 }
5985#endif // CONFIG_OBMC
Angie Chiangc0035cc2016-02-10 14:20:56 -08005986 skip_txfm_sb = tmp_skip_sb;
5987 skip_sse_sb = tmp_skip_sse;
5988 memcpy(skip_txfm, x->skip_txfm, sizeof(skip_txfm));
5989 memcpy(bsse, x->bsse, sizeof(bsse));
5990 }
Jingning Han3ee6db62015-08-05 19:00:31 -07005991 }
Angie Chiangc0035cc2016-02-10 14:20:56 -08005992 restore_dst_buf(xd, orig_dst, orig_dst_stride);
Jingning Han3ee6db62015-08-05 19:00:31 -07005993 }
Debargha Mukherjee85514c42015-10-30 09:19:36 -07005994
Jingning Han3ee6db62015-08-05 19:00:31 -07005995 // Set the appropriate filter
5996 mbmi->interp_filter = cm->interp_filter != SWITCHABLE ?
5997 cm->interp_filter : best_filter;
5998 rs = cm->interp_filter == SWITCHABLE ? vp10_get_switchable_rate(cpi, xd) : 0;
Geza Lore7ded0382016-02-22 10:55:32 +00005999
6000#if CONFIG_EXT_INTER
6001 if (is_comp_interintra_pred) {
6002 PREDICTION_MODE interintra_mode, best_interintra_mode = DC_PRED;
6003 int64_t best_interintra_rd = INT64_MAX;
6004 int rmode, rate_sum;
6005 int64_t dist_sum;
6006 int j;
6007 mbmi->ref_frame[1] = NONE;
6008 for (j = 0; j < MAX_MB_PLANE; j++) {
6009 xd->plane[j].dst.buf = tmp_buf + j * tmp_buf_sz;
6010 xd->plane[j].dst.stride = CU_SIZE;
6011 }
6012 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
6013 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6014 mbmi->ref_frame[1] = INTRA_FRAME;
6015
6016 for (interintra_mode = DC_PRED; interintra_mode <= TM_PRED;
6017 ++interintra_mode) {
6018 mbmi->interintra_mode = interintra_mode;
6019 mbmi->interintra_uv_mode = interintra_mode;
6020 rmode = intra_mode_cost[mbmi->interintra_mode];
6021 vp10_build_interintra_predictors(xd,
6022 tmp_buf,
6023 tmp_buf + tmp_buf_sz,
6024 tmp_buf + 2 * tmp_buf_sz,
6025 CU_SIZE,
6026 CU_SIZE,
6027 CU_SIZE,
6028 bsize);
6029 model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
6030 &skip_txfm_sb, &skip_sse_sb);
6031 rd = RDCOST(x->rdmult, x->rddiv, rmode + rate_sum, dist_sum);
6032 if (rd < best_interintra_rd) {
6033 best_interintra_rd = rd;
6034 best_interintra_mode = interintra_mode;
6035 }
6036 }
6037 mbmi->interintra_mode = best_interintra_mode;
6038 mbmi->interintra_uv_mode = best_interintra_mode;
6039 if (ref_best_rd < INT64_MAX &&
6040 best_interintra_rd / 2 > ref_best_rd) {
6041 return INT64_MAX;
6042 }
6043
6044 pred_exists = 0;
6045 tmp_rd = best_interintra_rd;
6046
6047 *compmode_interintra_cost =
6048 vp10_cost_bit(cm->fc->interintra_prob[bsize], 1);
6049 *compmode_interintra_cost += intra_mode_cost[mbmi->interintra_mode];
6050 } else if (is_interintra_allowed(mbmi)) {
6051 *compmode_interintra_cost =
6052 vp10_cost_bit(cm->fc->interintra_prob[bsize], 0);
6053 }
6054#endif // CONFIG_EXT_INTER
6055
Yue Chend1cad9c2016-01-27 14:18:53 -08006056#if CONFIG_OBMC
6057 if (allow_obmc)
6058 mbmi->obmc = best_obmc_flag;
6059 else
6060 mbmi->obmc = 0;
6061#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006062
6063 if (pred_exists) {
Yue Chena6142622016-02-18 12:35:14 -08006064#if !CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006065 if (best_needs_copy) {
6066 // again temporarily set the buffers to local memory to prevent a memcpy
6067 for (i = 0; i < MAX_MB_PLANE; i++) {
6068 xd->plane[i].dst.buf = tmp_buf + i * 64 * 64;
6069 xd->plane[i].dst.stride = 64;
6070 }
6071 }
Yue Chena6142622016-02-18 12:35:14 -08006072#endif // !CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006073 rd = tmp_rd + RDCOST(x->rdmult, x->rddiv, rs, 0);
Yue Chend1cad9c2016-01-27 14:18:53 -08006074#if CONFIG_OBMC
6075 if (allow_obmc)
6076 rd += RDCOST(x->rdmult, x->rddiv,
6077 cpi->obmc_cost[bsize][mbmi->obmc], 0);
6078#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006079 } else {
6080 int tmp_rate;
6081 int64_t tmp_dist;
Yue Chend1cad9c2016-01-27 14:18:53 -08006082#if CONFIG_OBMC
Yue Chena6142622016-02-18 12:35:14 -08006083 int64_t rdobmc = INT64_MAX;
Yue Chen907f88c2016-02-16 12:22:11 -08006084 restore_dst_buf(xd, orig_dst, orig_dst_stride);
Yue Chend1cad9c2016-01-27 14:18:53 -08006085#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006086 // Handles the special case when a filter that is not in the
6087 // switchable list (ex. bilinear) is indicated at the frame level, or
6088 // skip condition holds.
6089 vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
6090 model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist,
6091 &skip_txfm_sb, &skip_sse_sb);
6092 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
Yue Chend1cad9c2016-01-27 14:18:53 -08006093#if CONFIG_OBMC
Yue Chena6142622016-02-18 12:35:14 -08006094 skip_txfm_sb_bestfilter[0] = skip_txfm_sb;
6095 skip_sse_sb_bestfilter[0] = skip_sse_sb;
6096 memcpy(skip_txfm_bestfilter[0], x->skip_txfm, sizeof(skip_txfm));
6097 memcpy(bsse_bestfilter[0], x->bsse, sizeof(bsse));
6098 if (allow_obmc) {
6099 rd += RDCOST(x->rdmult, x->rddiv, cpi->obmc_cost[bsize][0], 0);
6100 vp10_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, 1,
6101 obmc_tmp_buf1, obmc_tmp_stride,
6102 dst_buf1, dst_stride1,
6103 dst_buf2, dst_stride2);
6104 for (i = 0; i < MAX_MB_PLANE; ++i) {
6105 xd->plane[i].dst.buf = obmc_tmp_buf1[i];
6106 xd->plane[i].dst.stride = obmc_tmp_stride[i];
Yue Chend1cad9c2016-01-27 14:18:53 -08006107 }
Yue Chena6142622016-02-18 12:35:14 -08006108 model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist,
6109 &skip_txfm_sb, &skip_sse_sb);
6110 rdobmc = RDCOST(x->rdmult, x->rddiv,
6111 rs + tmp_rate + cpi->obmc_cost[bsize][1], tmp_dist);
6112
6113 skip_txfm_sb_bestfilter[1] = skip_txfm_sb;
6114 skip_sse_sb_bestfilter[1] = skip_sse_sb;
6115 memcpy(skip_txfm_bestfilter[1], x->skip_txfm, sizeof(skip_txfm));
6116 memcpy(bsse_bestfilter[1], x->bsse, sizeof(bsse));
6117 if ((double)rdobmc <= 0.99 * (double)rd)
6118 rd = rdobmc;
Yue Chend1cad9c2016-01-27 14:18:53 -08006119 }
6120#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006121 memcpy(skip_txfm, x->skip_txfm, sizeof(skip_txfm));
6122 memcpy(bsse, x->bsse, sizeof(bsse));
6123 }
6124
6125 if (!is_comp_pred)
6126 single_filter[this_mode][refs[0]] = mbmi->interp_filter;
6127
6128 if (cpi->sf.adaptive_mode_search)
6129 if (is_comp_pred)
Yue Chen968bbc72016-01-19 16:45:45 -08006130#if CONFIG_EXT_INTER
6131 switch (this_mode) {
6132 case NEAREST_NEARESTMV:
6133 if (single_skippable[NEARESTMV][refs[0]] &&
6134 single_skippable[NEARESTMV][refs[1]])
6135 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6136 break;
6137 case ZERO_ZEROMV:
6138 if (single_skippable[ZEROMV][refs[0]] &&
6139 single_skippable[ZEROMV][refs[1]])
6140 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6141 break;
6142 case NEW_NEWMV:
6143 if (single_skippable[NEWMV][refs[0]] &&
6144 single_skippable[NEWMV][refs[1]])
6145 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6146 break;
6147 case NEAREST_NEWMV:
6148 if (single_skippable[NEARESTMV][refs[0]] &&
6149 single_skippable[NEWMV][refs[1]])
6150 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6151 break;
6152 case NEAR_NEWMV:
6153 if (single_skippable[NEARMV][refs[0]] &&
6154 single_skippable[NEWMV][refs[1]])
6155 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6156 break;
6157 case NEW_NEARESTMV:
6158 if (single_skippable[NEWMV][refs[0]] &&
6159 single_skippable[NEARESTMV][refs[1]])
6160 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6161 break;
6162 case NEW_NEARMV:
6163 if (single_skippable[NEWMV][refs[0]] &&
6164 single_skippable[NEARMV][refs[1]])
6165 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6166 break;
6167 case NEAREST_NEARMV:
6168 if (single_skippable[NEARESTMV][refs[0]] &&
6169 single_skippable[NEARMV][refs[1]])
6170 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6171 break;
6172 case NEAR_NEARESTMV:
6173 if (single_skippable[NEARMV][refs[0]] &&
6174 single_skippable[NEARESTMV][refs[1]])
6175 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6176 break;
6177 default:
6178 if (single_skippable[this_mode][refs[0]] &&
6179 single_skippable[this_mode][refs[1]])
6180 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
6181 break;
6182 }
6183#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006184 if (single_skippable[this_mode][refs[0]] &&
6185 single_skippable[this_mode][refs[1]])
6186 memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
Yue Chen968bbc72016-01-19 16:45:45 -08006187#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006188
6189 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
6190 // if current pred_error modeled rd is substantially more than the best
6191 // so far, do not bother doing full rd
6192 if (rd / 2 > ref_best_rd) {
6193 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6194 return INT64_MAX;
6195 }
6196 }
6197
6198 if (cm->interp_filter == SWITCHABLE)
6199 *rate2 += rs;
Yue Chend1cad9c2016-01-27 14:18:53 -08006200#if CONFIG_OBMC
Yue Chena6142622016-02-18 12:35:14 -08006201 rate2_nocoeff = *rate2;
Yue Chend1cad9c2016-01-27 14:18:53 -08006202#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006203
6204 memcpy(x->skip_txfm, skip_txfm, sizeof(skip_txfm));
6205 memcpy(x->bsse, bsse, sizeof(bsse));
6206
Yue Chena6142622016-02-18 12:35:14 -08006207
6208#if CONFIG_OBMC
6209 best_rd = INT64_MAX;
6210 for (mbmi->obmc = 0; mbmi->obmc <= allow_obmc; mbmi->obmc++) {
6211 int64_t tmp_rd;
6212
6213 if (pred_exists) {
6214 if (best_needs_copy) {
6215 if (mbmi->obmc) {
6216 for (i = 0; i < MAX_MB_PLANE; i++) {
6217 xd->plane[i].dst.buf = obmc_tmp_buf2[i];
6218 xd->plane[i].dst.stride = 64;
6219 }
6220 } else {
6221 for (i = 0; i < MAX_MB_PLANE; i++) {
6222 xd->plane[i].dst.buf = tmp_buf + i * 64 * 64;
6223 xd->plane[i].dst.stride = 64;
6224 }
6225 }
6226 } else {
6227 if (mbmi->obmc) {
6228 for (i = 0; i < MAX_MB_PLANE; i++) {
6229 xd->plane[i].dst.buf = obmc_tmp_buf1[i];
6230 xd->plane[i].dst.stride = 64;
6231 }
6232 } else {
6233 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6234 }
6235 }
6236 } else {
6237 if (mbmi->obmc) {
6238 for (i = 0; i < MAX_MB_PLANE; i++) {
6239 xd->plane[i].dst.buf = obmc_tmp_buf1[i];
6240 xd->plane[i].dst.stride = 64;
6241 }
6242 } else {
6243 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6244 }
6245 }
6246#if CONFIG_VP9_HIGHBITDEPTH
6247 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6248 x->pred_variance = vp10_high_get_sby_perpixel_variance(cpi,
6249 &xd->plane[0].dst, bsize, xd->bd);
6250 } else {
6251 x->pred_variance =
6252 vp10_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
6253 }
6254#else
6255 x->pred_variance =
6256 vp10_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
6257#endif // CONFIG_VP9_HIGHBITDEPTH
6258
6259 skip_txfm_sb = skip_txfm_sb_bestfilter[mbmi->obmc];
6260 skip_sse_sb = skip_sse_sb_bestfilter[mbmi->obmc];
6261 memcpy(x->skip_txfm, skip_txfm_bestfilter[mbmi->obmc],
6262 sizeof(skip_txfm));
6263 memcpy(x->bsse, bsse_bestfilter[mbmi->obmc], sizeof(bsse));
6264 x->skip = 0;
6265
6266 *rate2 = rate2_nocoeff;
6267 *distortion = 0;
6268 if (allow_obmc)
6269 *rate2 += cpi->obmc_cost[bsize][mbmi->obmc];
6270#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006271 if (!skip_txfm_sb) {
6272 int skippable_y, skippable_uv;
6273 int64_t sseuv = INT64_MAX;
6274 int64_t rdcosty = INT64_MAX;
6275
6276 // Y cost and distortion
6277 vp10_subtract_plane(x, bsize, 0);
Jingning Han2cdc1272015-10-09 09:57:42 -07006278#if CONFIG_VAR_TX
Jingning Hanf0dee772015-10-26 12:32:30 -07006279 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
Jingning Han4b594d32015-11-02 12:05:47 -08006280 select_tx_type_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
6281 bsize, ref_best_rd);
Jingning Han2cdc1272015-10-09 09:57:42 -07006282 } else {
Jingning Han0f34e352015-11-15 20:52:51 -08006283 int idx, idy;
Jingning Han2cdc1272015-10-09 09:57:42 -07006284 super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
6285 bsize, ref_best_rd);
Jingning Han0f34e352015-11-15 20:52:51 -08006286 for (idy = 0; idy < xd->n8_h; ++idy)
6287 for (idx = 0; idx < xd->n8_w; ++idx)
6288 mbmi->inter_tx_size[idy * 8 + idx] = mbmi->tx_size;
Jingning Han2cdc1272015-10-09 09:57:42 -07006289 }
6290#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006291 super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
6292 bsize, ref_best_rd);
Debargha Mukherjee9a8a6a12016-01-22 14:52:38 -08006293#endif // CONFIG_VAR_TX
Jingning Han704985e2015-10-08 12:05:03 -07006294
Jingning Han3ee6db62015-08-05 19:00:31 -07006295 if (*rate_y == INT_MAX) {
6296 *rate2 = INT_MAX;
6297 *distortion = INT64_MAX;
Yue Chena6142622016-02-18 12:35:14 -08006298#if CONFIG_OBMC
6299 continue;
6300#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006301 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6302 return INT64_MAX;
Yue Chena6142622016-02-18 12:35:14 -08006303#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006304 }
6305
6306 *rate2 += *rate_y;
6307 *distortion += distortion_y;
6308
6309 rdcosty = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
James Zern5e16d392015-08-17 18:19:22 -07006310 rdcosty = VPXMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, *psse));
Jingning Han3ee6db62015-08-05 19:00:31 -07006311
Jingning Hana8dad552015-10-08 16:46:10 -07006312#if CONFIG_VAR_TX
6313 if (!inter_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv,
6314 &sseuv, bsize, ref_best_rd - rdcosty)) {
6315#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006316 if (!super_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv,
6317 &sseuv, bsize, ref_best_rd - rdcosty)) {
Debargha Mukherjee9a8a6a12016-01-22 14:52:38 -08006318#endif // CONFIG_VAR_TX
Jingning Han3ee6db62015-08-05 19:00:31 -07006319 *rate2 = INT_MAX;
6320 *distortion = INT64_MAX;
Yue Chena6142622016-02-18 12:35:14 -08006321#if CONFIG_OBMC
6322 continue;
6323#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006324 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6325 return INT64_MAX;
Yue Chena6142622016-02-18 12:35:14 -08006326#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006327 }
6328
6329 *psse += sseuv;
6330 *rate2 += *rate_uv;
6331 *distortion += distortion_uv;
6332 *skippable = skippable_y && skippable_uv;
Yue Chena6142622016-02-18 12:35:14 -08006333#if CONFIG_OBMC
6334 if (*skippable) {
6335 *rate2 -= *rate_uv + *rate_y;
6336 *rate_y = 0;
6337 *rate_uv = 0;
6338 *rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
6339 mbmi->skip = 0;
6340 // here mbmi->skip temporarily plays a role as what this_skip2 does
6341 } else if (!xd->lossless[mbmi->segment_id] &&
6342 (RDCOST(x->rdmult, x->rddiv, *rate_y + *rate_uv +
6343 vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0), *distortion) >=
6344 RDCOST(x->rdmult, x->rddiv,
6345 vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1), *psse))) {
6346 *rate2 -= *rate_uv + *rate_y;
6347 *rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
6348 *distortion = *psse;
6349 *rate_y = 0;
6350 *rate_uv = 0;
6351 mbmi->skip = 1;
6352 } else {
6353 *rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
6354 mbmi->skip = 0;
6355 }
6356 *disable_skip = 0;
6357#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006358 } else {
6359 x->skip = 1;
6360 *disable_skip = 1;
6361
6362 // The cost of skip bit needs to be added.
Yue Chena6142622016-02-18 12:35:14 -08006363#if CONFIG_OBMC
6364 mbmi->skip = xd->lossless[mbmi->segment_id] ? 0 : 1;
6365 if (xd->lossless[mbmi->segment_id])
6366 *rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
6367 else
6368#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006369 *rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
6370
6371 *distortion = skip_sse_sb;
6372 }
Yue Chena6142622016-02-18 12:35:14 -08006373#if CONFIG_OBMC
6374 tmp_rd = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
6375 if (mbmi->obmc == 0 || (tmp_rd < best_rd)) {
6376 best_mbmi = *mbmi;
6377 best_rd = tmp_rd;
6378 best_rate2 = *rate2;
6379#if CONFIG_SUPERTX
6380 best_rate_y = *rate_y;
6381 best_rate_uv = *rate_uv;
6382#endif // CONFIG_SUPERTX
6383#if CONFIG_VAR_TX
6384 for (i = 0; i < MAX_MB_PLANE; ++i)
6385 memcpy(best_blk_skip[i], x->blk_skip[i],
6386 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
6387#endif // CONFIG_VAR_TX
6388 best_distortion = *distortion;
6389 best_skippable = *skippable;
6390 best_xskip = x->skip;
6391 best_disable_skip = *disable_skip;
6392 best_pred_var = x->pred_variance;
6393 }
6394 }
6395
6396 if (best_rd == INT64_MAX) {
6397 *rate2 = INT_MAX;
6398 *distortion = INT64_MAX;
6399 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6400 return INT64_MAX;
6401 }
6402 *mbmi = best_mbmi;
6403 *rate2 = best_rate2;
6404#if CONFIG_SUPERTX
6405 *rate_y = best_rate_y;
6406 *rate_uv = best_rate_uv;
6407#endif // CONFIG_SUPERTX
6408#if CONFIG_VAR_TX
6409 for (i = 0; i < MAX_MB_PLANE; ++i)
6410 memcpy(x->blk_skip[i], best_blk_skip[i],
6411 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
6412#endif // CONFIG_VAR_TX
6413 *distortion = best_distortion;
6414 *skippable = best_skippable;
6415 x->skip = best_xskip;
6416 *disable_skip = best_disable_skip;
6417 x->pred_variance = best_pred_var;
6418#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006419
6420 if (!is_comp_pred)
6421 single_skippable[this_mode][refs[0]] = *skippable;
6422
6423 restore_dst_buf(xd, orig_dst, orig_dst_stride);
6424 return 0; // The rate-distortion cost will be re-calculated by caller.
6425}
6426
Yaowu Xu26a9afc2015-08-13 09:42:27 -07006427void vp10_rd_pick_intra_mode_sb(VP10_COMP *cpi, MACROBLOCK *x,
Jingning Han3ee6db62015-08-05 19:00:31 -07006428 RD_COST *rd_cost, BLOCK_SIZE bsize,
6429 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07006430 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07006431 MACROBLOCKD *const xd = &x->e_mbd;
6432 struct macroblockd_plane *const pd = xd->plane;
6433 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
6434 int y_skip = 0, uv_skip = 0;
6435 int64_t dist_y = 0, dist_uv = 0;
6436 TX_SIZE max_uv_tx_size;
Jingning Han3ee6db62015-08-05 19:00:31 -07006437 ctx->skip = 0;
6438 xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
6439 xd->mi[0]->mbmi.ref_frame[1] = NONE;
6440
6441 if (bsize >= BLOCK_8X8) {
6442 if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly,
6443 &dist_y, &y_skip, bsize,
6444 best_rd) >= best_rd) {
6445 rd_cost->rate = INT_MAX;
6446 return;
6447 }
6448 } else {
6449 y_skip = 0;
6450 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
6451 &dist_y, best_rd) >= best_rd) {
6452 rd_cost->rate = INT_MAX;
6453 return;
6454 }
6455 }
6456 max_uv_tx_size = get_uv_tx_size_impl(xd->mi[0]->mbmi.tx_size, bsize,
6457 pd[1].subsampling_x,
6458 pd[1].subsampling_y);
6459 rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv, &rate_uv_tokenonly,
James Zern5e16d392015-08-17 18:19:22 -07006460 &dist_uv, &uv_skip, VPXMAX(BLOCK_8X8, bsize),
Jingning Han3ee6db62015-08-05 19:00:31 -07006461 max_uv_tx_size);
6462
6463 if (y_skip && uv_skip) {
6464 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
6465 vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
6466 rd_cost->dist = dist_y + dist_uv;
6467 } else {
6468 rd_cost->rate = rate_y + rate_uv +
6469 vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
6470 rd_cost->dist = dist_y + dist_uv;
6471 }
6472
6473 ctx->mic = *xd->mi[0];
6474 ctx->mbmi_ext = *x->mbmi_ext;
6475 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
6476}
6477
6478// This function is designed to apply a bias or adjustment to an rd value based
6479// on the relative variance of the source and reconstruction.
6480#define LOW_VAR_THRESH 16
6481#define VLOW_ADJ_MAX 25
6482#define VHIGH_ADJ_MAX 8
Yaowu Xu26a9afc2015-08-13 09:42:27 -07006483static void rd_variance_adjustment(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07006484 MACROBLOCK *x,
6485 BLOCK_SIZE bsize,
6486 int64_t *this_rd,
6487 MV_REFERENCE_FRAME ref_frame,
Yue Chena6142622016-02-18 12:35:14 -08006488#if CONFIG_OBMC
6489 int is_pred_var_available,
6490#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006491 unsigned int source_variance) {
6492 MACROBLOCKD *const xd = &x->e_mbd;
6493 unsigned int recon_variance;
6494 unsigned int absvar_diff = 0;
6495 int64_t var_error = 0;
6496 int64_t var_factor = 0;
6497
6498 if (*this_rd == INT64_MAX)
6499 return;
6500
Yue Chena6142622016-02-18 12:35:14 -08006501#if CONFIG_OBMC
6502 if (is_pred_var_available) {
6503 recon_variance = x->pred_variance;
6504 } else {
6505#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006506#if CONFIG_VP9_HIGHBITDEPTH
6507 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6508 recon_variance =
6509 vp10_high_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize, xd->bd);
6510 } else {
6511 recon_variance =
6512 vp10_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
6513 }
6514#else
6515 recon_variance =
6516 vp10_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
6517#endif // CONFIG_VP9_HIGHBITDEPTH
Yue Chena6142622016-02-18 12:35:14 -08006518#if CONFIG_OBMC
6519 }
6520#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006521
6522 if ((source_variance + recon_variance) > LOW_VAR_THRESH) {
6523 absvar_diff = (source_variance > recon_variance)
6524 ? (source_variance - recon_variance)
6525 : (recon_variance - source_variance);
6526
Alex Converseb1fcd172015-11-19 14:53:51 -08006527 var_error = ((int64_t)200 * source_variance * recon_variance) /
6528 (((int64_t)source_variance * source_variance) +
6529 ((int64_t)recon_variance * recon_variance));
Jingning Han3ee6db62015-08-05 19:00:31 -07006530 var_error = 100 - var_error;
6531 }
6532
6533 // Source variance above a threshold and ref frame is intra.
6534 // This case is targeted mainly at discouraging intra modes that give rise
6535 // to a predictor with a low spatial complexity compared to the source.
6536 if ((source_variance > LOW_VAR_THRESH) && (ref_frame == INTRA_FRAME) &&
6537 (source_variance > recon_variance)) {
James Zern5e16d392015-08-17 18:19:22 -07006538 var_factor = VPXMIN(absvar_diff, VPXMIN(VLOW_ADJ_MAX, var_error));
Jingning Han3ee6db62015-08-05 19:00:31 -07006539 // A second possible case of interest is where the source variance
6540 // is very low and we wish to discourage false texture or motion trails.
6541 } else if ((source_variance < (LOW_VAR_THRESH >> 1)) &&
6542 (recon_variance > source_variance)) {
James Zern5e16d392015-08-17 18:19:22 -07006543 var_factor = VPXMIN(absvar_diff, VPXMIN(VHIGH_ADJ_MAX, var_error));
Jingning Han3ee6db62015-08-05 19:00:31 -07006544 }
6545 *this_rd += (*this_rd * var_factor) / 100;
6546}
6547
6548
6549// Do we have an internal image edge (e.g. formatting bars).
Yaowu Xu26a9afc2015-08-13 09:42:27 -07006550int vp10_internal_image_edge(VP10_COMP *cpi) {
Jingning Han3ee6db62015-08-05 19:00:31 -07006551 return (cpi->oxcf.pass == 2) &&
6552 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
6553 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
6554}
6555
6556// Checks to see if a super block is on a horizontal image edge.
6557// In most cases this is the "real" edge unless there are formatting
6558// bars embedded in the stream.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07006559int vp10_active_h_edge(VP10_COMP *cpi, int mi_row, int mi_step) {
Jingning Han3ee6db62015-08-05 19:00:31 -07006560 int top_edge = 0;
6561 int bottom_edge = cpi->common.mi_rows;
6562 int is_active_h_edge = 0;
6563
6564 // For two pass account for any formatting bars detected.
6565 if (cpi->oxcf.pass == 2) {
6566 TWO_PASS *twopass = &cpi->twopass;
6567
6568 // The inactive region is specified in MBs not mi units.
6569 // The image edge is in the following MB row.
6570 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
6571
6572 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
James Zern5e16d392015-08-17 18:19:22 -07006573 bottom_edge = VPXMAX(top_edge, bottom_edge);
Jingning Han3ee6db62015-08-05 19:00:31 -07006574 }
6575
6576 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
6577 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
6578 is_active_h_edge = 1;
6579 }
6580 return is_active_h_edge;
6581}
6582
6583// Checks to see if a super block is on a vertical image edge.
6584// In most cases this is the "real" edge unless there are formatting
6585// bars embedded in the stream.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07006586int vp10_active_v_edge(VP10_COMP *cpi, int mi_col, int mi_step) {
Jingning Han3ee6db62015-08-05 19:00:31 -07006587 int left_edge = 0;
6588 int right_edge = cpi->common.mi_cols;
6589 int is_active_v_edge = 0;
6590
6591 // For two pass account for any formatting bars detected.
6592 if (cpi->oxcf.pass == 2) {
6593 TWO_PASS *twopass = &cpi->twopass;
6594
6595 // The inactive region is specified in MBs not mi units.
6596 // The image edge is in the following MB row.
6597 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
6598
6599 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
James Zern5e16d392015-08-17 18:19:22 -07006600 right_edge = VPXMAX(left_edge, right_edge);
Jingning Han3ee6db62015-08-05 19:00:31 -07006601 }
6602
6603 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
6604 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
6605 is_active_v_edge = 1;
6606 }
6607 return is_active_v_edge;
6608}
6609
6610// Checks to see if a super block is at the edge of the active image.
6611// In most cases this is the "real" edge unless there are formatting
6612// bars embedded in the stream.
Yaowu Xu26a9afc2015-08-13 09:42:27 -07006613int vp10_active_edge_sb(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07006614 int mi_row, int mi_col) {
6615 return vp10_active_h_edge(cpi, mi_row, MI_BLOCK_SIZE) ||
6616 vp10_active_v_edge(cpi, mi_col, MI_BLOCK_SIZE);
6617}
6618
Yaowu Xu26a9afc2015-08-13 09:42:27 -07006619void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
Jingning Han4fa8e732015-09-10 12:24:06 -07006620 TileDataEnc *tile_data,
6621 MACROBLOCK *x,
6622 int mi_row, int mi_col,
Debargha Mukherjee3787b172015-11-19 16:51:16 -08006623 RD_COST *rd_cost,
6624#if CONFIG_SUPERTX
6625 int *returnrate_nocoef,
6626#endif // CONFIG_SUPERTX
6627 BLOCK_SIZE bsize,
Jingning Han4fa8e732015-09-10 12:24:06 -07006628 PICK_MODE_CONTEXT *ctx,
6629 int64_t best_rd_so_far) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07006630 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07006631 RD_OPT *const rd_opt = &cpi->rd;
6632 SPEED_FEATURES *const sf = &cpi->sf;
6633 MACROBLOCKD *const xd = &x->e_mbd;
6634 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6635 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6636 const struct segmentation *const seg = &cm->seg;
6637 PREDICTION_MODE this_mode;
6638 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
6639 unsigned char segment_id = mbmi->segment_id;
6640 int comp_pred, i, k;
6641 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
Zoe Liu3ec16012015-11-12 02:12:17 -08006642 struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE];
Yue Chen1ac85872016-01-07 15:13:52 -08006643#if CONFIG_EXT_INTER
6644 int_mv single_newmvs[2][MAX_REF_FRAMES] = { { { 0 } }, { { 0 } } };
Geza Lore7ded0382016-02-22 10:55:32 +00006645 int single_newmvs_rate[2][MAX_REF_FRAMES] = { { 0 }, { 0 } };
Yue Chen1ac85872016-01-07 15:13:52 -08006646#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006647 int_mv single_newmv[MAX_REF_FRAMES] = { { 0 } };
Yue Chen1ac85872016-01-07 15:13:52 -08006648#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006649 INTERP_FILTER single_inter_filter[MB_MODE_COUNT][MAX_REF_FRAMES];
6650 int single_skippable[MB_MODE_COUNT][MAX_REF_FRAMES];
Zoe Liu3ec16012015-11-12 02:12:17 -08006651 static const int flag_list[REFS_PER_FRAME + 1] = {
6652 0,
6653 VP9_LAST_FLAG,
6654#if CONFIG_EXT_REFS
6655 VP9_LAST2_FLAG,
6656 VP9_LAST3_FLAG,
6657 VP9_LAST4_FLAG,
6658#endif // CONFIG_EXT_REFS
6659 VP9_GOLD_FLAG,
6660 VP9_ALT_FLAG
6661 };
Jingning Han3ee6db62015-08-05 19:00:31 -07006662 int64_t best_rd = best_rd_so_far;
6663 int64_t best_pred_diff[REFERENCE_MODES];
6664 int64_t best_pred_rd[REFERENCE_MODES];
6665 int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
6666 int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
6667 MB_MODE_INFO best_mbmode;
6668 int best_mode_skippable = 0;
6669 int midx, best_mode_index = -1;
6670 unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
6671 vpx_prob comp_mode_p;
6672 int64_t best_intra_rd = INT64_MAX;
6673 unsigned int best_pred_sse = UINT_MAX;
6674 PREDICTION_MODE best_intra_mode = DC_PRED;
6675 int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES];
6676 int64_t dist_uv[TX_SIZES];
6677 int skip_uv[TX_SIZES];
6678 PREDICTION_MODE mode_uv[TX_SIZES];
hui sube3559b2015-10-07 09:29:02 -07006679#if CONFIG_EXT_INTRA
6680 EXT_INTRA_MODE_INFO ext_intra_mode_info_uv[TX_SIZES];
hui su4aa50c12015-11-10 12:09:59 -08006681 int8_t uv_angle_delta[TX_SIZES];
hui sud7c8bc72015-11-12 19:18:32 -08006682 int is_directional_mode, angle_stats_ready = 0;
hui su4aa50c12015-11-10 12:09:59 -08006683 int rate_overhead, rate_dummy;
hui sud7c8bc72015-11-12 19:18:32 -08006684 uint8_t directional_mode_skip_mask[INTRA_MODES];
hui sube3559b2015-10-07 09:29:02 -07006685#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07006686 const int intra_cost_penalty = vp10_get_intra_cost_penalty(
6687 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
hui su1559afd2015-12-30 10:27:19 -08006688 const int * const intra_mode_cost =
6689 cpi->mbmode_cost[size_group_lookup[bsize]];
Jingning Han3ee6db62015-08-05 19:00:31 -07006690 int best_skip2 = 0;
6691 uint8_t ref_frame_skip_mask[2] = { 0 };
Yue Chen1ac85872016-01-07 15:13:52 -08006692#if CONFIG_EXT_INTER
6693 uint32_t mode_skip_mask[MAX_REF_FRAMES] = { 0 };
6694#else
Jingning Han3ee6db62015-08-05 19:00:31 -07006695 uint16_t mode_skip_mask[MAX_REF_FRAMES] = { 0 };
Yue Chen1ac85872016-01-07 15:13:52 -08006696#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006697 int mode_skip_start = sf->mode_skip_start + 1;
6698 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
6699 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
6700 int64_t mode_threshold[MAX_MODES];
6701 int *mode_map = tile_data->mode_map[bsize];
6702 const int mode_search_skip_flags = sf->mode_search_skip_flags;
6703 int64_t mask_filter = 0;
6704 int64_t filter_cache[SWITCHABLE_FILTER_CONTEXTS];
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08006705 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
Yue Chend1cad9c2016-01-27 14:18:53 -08006706#if CONFIG_OBMC
6707#if CONFIG_VP9_HIGHBITDEPTH
6708 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * 64 * 64]);
6709 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * 64 * 64]);
6710#else
6711 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * 64 * 64]);
6712 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * 64 * 64]);
6713#endif // CONFIG_VP9_HIGHBITDEPTH
6714 uint8_t *dst_buf1[3], *dst_buf2[3];
6715 int dst_stride1[3] = {64, 64, 64};
6716 int dst_stride2[3] = {64, 64, 64};
6717
6718#if CONFIG_VP9_HIGHBITDEPTH
6719 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6720 int len = sizeof(uint16_t);
6721 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
6722 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + 4096 * len);
6723 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 8192 * len);
6724 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
6725 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + 4096 * len);
6726 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 8192 * len);
6727 } else {
6728#endif // CONFIG_VP9_HIGHBITDEPTH
6729 dst_buf1[0] = tmp_buf1;
6730 dst_buf1[1] = tmp_buf1 + 4096;
6731 dst_buf1[2] = tmp_buf1 + 8192;
6732 dst_buf2[0] = tmp_buf2;
6733 dst_buf2[1] = tmp_buf2 + 4096;
6734 dst_buf2[2] = tmp_buf2 + 8192;
6735#if CONFIG_VP9_HIGHBITDEPTH
6736 }
6737#endif // CONFIG_VP9_HIGHBITDEPTH
6738#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07006739
6740 vp10_zero(best_mbmode);
6741
hui sud7c8bc72015-11-12 19:18:32 -08006742#if CONFIG_EXT_INTRA
6743 memset(directional_mode_skip_mask, 0,
6744 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
6745#endif // CONFIG_EXT_INTRA
6746
Jingning Han3ee6db62015-08-05 19:00:31 -07006747 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
6748 filter_cache[i] = INT64_MAX;
6749
6750 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
6751 &comp_mode_p);
6752
6753 for (i = 0; i < REFERENCE_MODES; ++i)
6754 best_pred_rd[i] = INT64_MAX;
6755 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
6756 best_filter_rd[i] = INT64_MAX;
6757 for (i = 0; i < TX_SIZES; i++)
6758 rate_uv_intra[i] = INT_MAX;
6759 for (i = 0; i < MAX_REF_FRAMES; ++i)
6760 x->pred_sse[i] = INT_MAX;
6761 for (i = 0; i < MB_MODE_COUNT; ++i) {
6762 for (k = 0; k < MAX_REF_FRAMES; ++k) {
6763 single_inter_filter[i][k] = SWITCHABLE;
6764 single_skippable[i][k] = 0;
6765 }
6766 }
6767
6768 rd_cost->rate = INT_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08006769#if CONFIG_SUPERTX
6770 *returnrate_nocoef = INT_MAX;
6771#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07006772
6773 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
6774 x->pred_mv_sad[ref_frame] = INT_MAX;
Jingning Han387a10e2015-12-09 09:07:39 -08006775 x->mbmi_ext->mode_context[ref_frame] = 0;
Yue Chen968bbc72016-01-19 16:45:45 -08006776#if CONFIG_REF_MV && CONFIG_EXT_INTER
6777 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
6778#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006779 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
6780 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
6781 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
6782 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
6783 }
6784 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
6785 frame_mv[ZEROMV][ref_frame].as_int = 0;
Yue Chen1ac85872016-01-07 15:13:52 -08006786#if CONFIG_EXT_INTER
6787 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
Yue Chen968bbc72016-01-19 16:45:45 -08006788 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
6789 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
Yue Chen1ac85872016-01-07 15:13:52 -08006790#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006791 }
6792
Jingning Han33cc1bd2016-01-12 15:06:59 -08006793#if CONFIG_REF_MV
6794 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
6795 MODE_INFO *const mi = xd->mi[0];
6796 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
6797 x->mbmi_ext->mode_context[ref_frame] = 0;
6798 vp10_find_mv_refs(cm, xd, mi, ref_frame,
6799#if CONFIG_REF_MV
6800 &mbmi_ext->ref_mv_count[ref_frame],
6801 mbmi_ext->ref_mv_stack[ref_frame],
Yue Chen968bbc72016-01-19 16:45:45 -08006802#if CONFIG_EXT_INTER
6803 mbmi_ext->compound_mode_context,
6804#endif // CONFIG_EXT_INTER
Jingning Han33cc1bd2016-01-12 15:06:59 -08006805#endif
6806 candidates, mi_row, mi_col,
6807 NULL, NULL, mbmi_ext->mode_context);
6808 }
6809#endif
6810
Yue Chend1cad9c2016-01-27 14:18:53 -08006811#if CONFIG_OBMC
6812 vp10_build_prediction_by_above_preds(cpi, xd, mi_row, mi_col, dst_buf1,
6813 dst_stride1);
6814 vp10_build_prediction_by_left_preds(cpi, xd, mi_row, mi_col, dst_buf2,
6815 dst_stride2);
6816 vp10_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
6817#endif // CONFIG_OBMC
6818
Jingning Han3ee6db62015-08-05 19:00:31 -07006819 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
6820 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
6821 // Skip checking missing references in both single and compound reference
6822 // modes. Note that a mode will be skipped iff both reference frames
6823 // are masked out.
6824 ref_frame_skip_mask[0] |= (1 << ref_frame);
6825 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
Jingning Han1eb760e2015-09-10 12:56:41 -07006826 } else {
Jingning Han3ee6db62015-08-05 19:00:31 -07006827 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
6828 // Skip fixed mv modes for poor references
6829 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
6830 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
6831 break;
6832 }
6833 }
6834 }
6835 // If the segment reference frame feature is enabled....
6836 // then do nothing if the current ref frame is not allowed..
6837 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
6838 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
6839 ref_frame_skip_mask[0] |= (1 << ref_frame);
6840 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
6841 }
6842 }
6843
6844 // Disable this drop out case if the ref frame
6845 // segment level feature is enabled for this segment. This is to
6846 // prevent the possibility that we end up unable to pick any mode.
6847 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
6848 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
6849 // unless ARNR filtering is enabled in which case we want
6850 // an unfiltered alternative. We allow near/nearest as well
6851 // because they may result in zero-zero MVs but be cheaper.
6852 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Zoe Liu3ec16012015-11-12 02:12:17 -08006853 ref_frame_skip_mask[0] =
6854 (1 << LAST_FRAME) |
6855#if CONFIG_EXT_REFS
6856 (1 << LAST2_FRAME) |
6857 (1 << LAST3_FRAME) |
6858 (1 << LAST4_FRAME) |
6859#endif // CONFIG_EXT_REFS
6860 (1 << GOLDEN_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07006861 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
6862 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
6863 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != 0)
6864 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
6865 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != 0)
6866 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
Yue Chen968bbc72016-01-19 16:45:45 -08006867#if CONFIG_EXT_INTER
6868 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != 0)
6869 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
6870 if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != 0)
6871 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
6872 if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != 0)
6873 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
6874#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006875 }
6876 }
6877
6878 if (cpi->rc.is_src_frame_alt_ref) {
6879 if (sf->alt_ref_search_fp) {
6880 mode_skip_mask[ALTREF_FRAME] = 0;
6881 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
6882 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
6883 }
6884 }
6885
6886 if (sf->alt_ref_search_fp)
6887 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
6888 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
6889 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
6890
6891 if (sf->adaptive_mode_search) {
6892 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
6893 cpi->rc.frames_since_golden >= 3)
6894 if (x->pred_mv_sad[GOLDEN_FRAME] > (x->pred_mv_sad[LAST_FRAME] << 1))
6895 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
6896 }
6897
6898 if (bsize > sf->max_intra_bsize) {
6899 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
6900 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
6901 }
6902
6903 mode_skip_mask[INTRA_FRAME] |=
6904 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
6905
6906 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i)
6907 mode_threshold[i] = 0;
6908 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
6909 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
6910
6911 midx = sf->schedule_mode_search ? mode_skip_start : 0;
6912 while (midx > 4) {
6913 uint8_t end_pos = 0;
6914 for (i = 5; i < midx; ++i) {
6915 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
6916 uint8_t tmp = mode_map[i];
6917 mode_map[i] = mode_map[i - 1];
6918 mode_map[i - 1] = tmp;
6919 end_pos = i;
6920 }
6921 }
6922 midx = end_pos;
6923 }
6924
hui suc93e5cc2015-12-07 18:18:57 -08006925 mbmi->palette_mode_info.palette_size[0] = 0;
6926 mbmi->palette_mode_info.palette_size[1] = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07006927 for (midx = 0; midx < MAX_MODES; ++midx) {
6928 int mode_index = mode_map[midx];
6929 int mode_excluded = 0;
6930 int64_t this_rd = INT64_MAX;
6931 int disable_skip = 0;
6932 int compmode_cost = 0;
Geza Lore7ded0382016-02-22 10:55:32 +00006933#if CONFIG_EXT_INTER
6934 int compmode_interintra_cost = 0;
6935#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07006936 int rate2 = 0, rate_y = 0, rate_uv = 0;
6937 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
6938 int skippable = 0;
6939 int this_skip2 = 0;
6940 int64_t total_sse = INT64_MAX;
6941 int early_term = 0;
Jingning Han28e03932016-01-20 17:40:47 -08006942#if CONFIG_REF_MV
6943 uint8_t ref_frame_type;
6944#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07006945
6946 this_mode = vp10_mode_order[mode_index].mode;
6947 ref_frame = vp10_mode_order[mode_index].ref_frame[0];
6948 second_ref_frame = vp10_mode_order[mode_index].ref_frame[1];
6949
Yue Chen968bbc72016-01-19 16:45:45 -08006950#if CONFIG_EXT_INTER
Geza Lore7ded0382016-02-22 10:55:32 +00006951 if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
6952 // Mode must by compatible
6953 assert(is_interintra_allowed_mode(this_mode));
6954
6955 if (!is_interintra_allowed_bsize(bsize))
6956 continue;
6957 }
6958
Yue Chen968bbc72016-01-19 16:45:45 -08006959 if (this_mode == NEAREST_NEARESTMV) {
6960 frame_mv[NEAREST_NEARESTMV][ref_frame].as_int =
6961 frame_mv[NEARESTMV][ref_frame].as_int;
6962 frame_mv[NEAREST_NEARESTMV][second_ref_frame].as_int =
6963 frame_mv[NEARESTMV][second_ref_frame].as_int;
6964 } else if (this_mode == NEAREST_NEARMV) {
6965 frame_mv[NEAREST_NEARMV][ref_frame].as_int =
6966 frame_mv[NEARESTMV][ref_frame].as_int;
6967 frame_mv[NEAREST_NEARMV][second_ref_frame].as_int =
6968 frame_mv[NEARMV][second_ref_frame].as_int;
6969 } else if (this_mode == NEAR_NEARESTMV) {
6970 frame_mv[NEAR_NEARESTMV][ref_frame].as_int =
6971 frame_mv[NEARMV][ref_frame].as_int;
6972 frame_mv[NEAR_NEARESTMV][second_ref_frame].as_int =
6973 frame_mv[NEARESTMV][second_ref_frame].as_int;
6974 } else if (this_mode == NEAREST_NEWMV) {
6975 frame_mv[NEAREST_NEWMV][ref_frame].as_int =
6976 frame_mv[NEARESTMV][ref_frame].as_int;
6977 frame_mv[NEAREST_NEWMV][second_ref_frame].as_int =
6978 frame_mv[NEWMV][second_ref_frame].as_int;
6979 } else if (this_mode == NEW_NEARESTMV) {
6980 frame_mv[NEW_NEARESTMV][ref_frame].as_int =
6981 frame_mv[NEWMV][ref_frame].as_int;
6982 frame_mv[NEW_NEARESTMV][second_ref_frame].as_int =
6983 frame_mv[NEARESTMV][second_ref_frame].as_int;
6984 } else if (this_mode == NEAR_NEWMV) {
6985 frame_mv[NEAR_NEWMV][ref_frame].as_int =
6986 frame_mv[NEARMV][ref_frame].as_int;
6987 frame_mv[NEAR_NEWMV][second_ref_frame].as_int =
6988 frame_mv[NEWMV][second_ref_frame].as_int;
6989 } else if (this_mode == NEW_NEARMV) {
6990 frame_mv[NEW_NEARMV][ref_frame].as_int =
6991 frame_mv[NEWMV][ref_frame].as_int;
6992 frame_mv[NEW_NEARMV][second_ref_frame].as_int =
6993 frame_mv[NEARMV][second_ref_frame].as_int;
6994 } else if (this_mode == NEW_NEWMV) {
6995 frame_mv[NEW_NEWMV][ref_frame].as_int =
6996 frame_mv[NEWMV][ref_frame].as_int;
6997 frame_mv[NEW_NEWMV][second_ref_frame].as_int =
6998 frame_mv[NEWMV][second_ref_frame].as_int;
6999 }
7000#endif // CONFIG_EXT_INTER
7001
Jingning Han3ee6db62015-08-05 19:00:31 -07007002 // Look at the reference frame of the best mode so far and set the
7003 // skip mask to look at a subset of the remaining modes.
7004 if (midx == mode_skip_start && best_mode_index >= 0) {
7005 switch (best_mbmode.ref_frame[0]) {
7006 case INTRA_FRAME:
7007 break;
7008 case LAST_FRAME:
7009 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
7010 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7011 break;
Zoe Liu3ec16012015-11-12 02:12:17 -08007012#if CONFIG_EXT_REFS
7013 case LAST2_FRAME:
7014 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
7015 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7016 break;
7017 case LAST3_FRAME:
7018 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
7019 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7020 break;
7021 case LAST4_FRAME:
7022 ref_frame_skip_mask[0] |= LAST4_FRAME_MODE_MASK;
7023 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7024 break;
7025#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07007026 case GOLDEN_FRAME:
7027 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
7028 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
7029 break;
7030 case ALTREF_FRAME:
7031 ref_frame_skip_mask[0] |= ALT_REF_MODE_MASK;
7032 break;
7033 case NONE:
7034 case MAX_REF_FRAMES:
7035 assert(0 && "Invalid Reference frame");
7036 break;
7037 }
7038 }
7039
7040 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
James Zern5e16d392015-08-17 18:19:22 -07007041 (ref_frame_skip_mask[1] & (1 << VPXMAX(0, second_ref_frame))))
Jingning Han3ee6db62015-08-05 19:00:31 -07007042 continue;
7043
7044 if (mode_skip_mask[ref_frame] & (1 << this_mode))
7045 continue;
7046
7047 // Test best rd so far against threshold for trying this mode.
7048 if (best_mode_skippable && sf->schedule_mode_search)
7049 mode_threshold[mode_index] <<= 1;
7050
7051 if (best_rd < mode_threshold[mode_index])
7052 continue;
7053
Jingning Han3ee6db62015-08-05 19:00:31 -07007054 comp_pred = second_ref_frame > INTRA_FRAME;
7055 if (comp_pred) {
7056 if (!cpi->allow_comp_inter_inter)
7057 continue;
7058
7059 // Skip compound inter modes if ARF is not available.
7060 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
7061 continue;
7062
7063 // Do not allow compound prediction if the segment level reference frame
7064 // feature is in use as in this case there can only be one reference.
7065 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
7066 continue;
7067
7068 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
7069 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
7070 continue;
7071
7072 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
7073 } else {
7074 if (ref_frame != INTRA_FRAME)
7075 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
7076 }
7077
7078 if (ref_frame == INTRA_FRAME) {
7079 if (sf->adaptive_mode_search)
7080 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
7081 continue;
7082
7083 if (this_mode != DC_PRED) {
7084 // Disable intra modes other than DC_PRED for blocks with low variance
7085 // Threshold for intra skipping based on source variance
7086 // TODO(debargha): Specialize the threshold for super block sizes
7087 const unsigned int skip_intra_var_thresh = 64;
7088 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
7089 x->source_variance < skip_intra_var_thresh)
7090 continue;
7091 // Only search the oblique modes if the best so far is
7092 // one of the neighboring directional modes
7093 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
7094 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
7095 if (best_mode_index >= 0 &&
7096 best_mbmode.ref_frame[0] > INTRA_FRAME)
7097 continue;
7098 }
7099 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
7100 if (conditional_skipintra(this_mode, best_intra_mode))
7101 continue;
7102 }
7103 }
7104 } else {
7105 const MV_REFERENCE_FRAME ref_frames[2] = {ref_frame, second_ref_frame};
Yue Chen968bbc72016-01-19 16:45:45 -08007106 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
7107#if CONFIG_REF_MV && CONFIG_EXT_INTER
7108 mbmi_ext->compound_mode_context,
7109#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
7110 frame_mv,
Jingning Han387a10e2015-12-09 09:07:39 -08007111 this_mode, ref_frames, bsize, -1))
Jingning Han3ee6db62015-08-05 19:00:31 -07007112 continue;
7113 }
7114
7115 mbmi->mode = this_mode;
7116 mbmi->uv_mode = DC_PRED;
7117 mbmi->ref_frame[0] = ref_frame;
7118 mbmi->ref_frame[1] = second_ref_frame;
hui sube3559b2015-10-07 09:29:02 -07007119#if CONFIG_EXT_INTRA
7120 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
7121 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
7122#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07007123 // Evaluate all sub-pel filters irrespective of whether we can use
7124 // them for this frame.
Debargha Mukherjeebab29122016-02-26 00:18:03 -08007125 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
Jingning Han3ee6db62015-08-05 19:00:31 -07007126 : cm->interp_filter;
7127 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chend1cad9c2016-01-27 14:18:53 -08007128#if CONFIG_OBMC
7129 mbmi->obmc = 0;
7130#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007131
7132 x->skip = 0;
7133 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
7134
7135 // Select prediction reference frames.
7136 for (i = 0; i < MAX_MB_PLANE; i++) {
7137 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
7138 if (comp_pred)
7139 xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
7140 }
7141
Geza Lore7ded0382016-02-22 10:55:32 +00007142#if CONFIG_EXT_INTER
7143 mbmi->interintra_mode = (PREDICTION_MODE)(DC_PRED - 1);
7144 mbmi->interintra_uv_mode = (PREDICTION_MODE)(DC_PRED - 1);
7145#endif // CONFIG_EXT_INTER
7146
Jingning Han3ee6db62015-08-05 19:00:31 -07007147 if (ref_frame == INTRA_FRAME) {
7148 TX_SIZE uv_tx;
7149 struct macroblockd_plane *const pd = &xd->plane[1];
7150 memset(x->skip_txfm, 0, sizeof(x->skip_txfm));
hui su4aa50c12015-11-10 12:09:59 -08007151
hui sube3559b2015-10-07 09:29:02 -07007152#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08007153 is_directional_mode = (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED);
7154 if (is_directional_mode) {
hui sud7c8bc72015-11-12 19:18:32 -08007155 if (!angle_stats_ready) {
7156 const int src_stride = x->plane[0].src.stride;
7157 const uint8_t *src = x->plane[0].src.buf;
7158 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
7159 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
7160 double hist[DIRECTIONAL_MODES];
7161 PREDICTION_MODE mode;
7162
7163#if CONFIG_VP9_HIGHBITDEPTH
7164 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
7165 highbd_angle_estimation(src, src_stride, rows, cols, hist);
7166 else
7167#endif
7168 angle_estimation(src, src_stride, rows, cols, hist);
7169 for (mode = 0; mode < INTRA_MODES; ++mode) {
7170 if (mode != DC_PRED && mode != TM_PRED) {
7171 int index = get_angle_index((double)mode_to_angle_map[mode]);
7172 double score, weight = 1.0;
7173 score = hist[index];
7174 if (index > 0) {
7175 score += hist[index - 1] * 0.5;
7176 weight += 0.5;
7177 }
7178 if (index < DIRECTIONAL_MODES - 1) {
7179 score += hist[index + 1] * 0.5;
7180 weight += 0.5;
7181 }
7182 score /= weight;
7183 if (score < ANGLE_SKIP_THRESH)
7184 directional_mode_skip_mask[mode] = 1;
7185 }
7186 }
7187 angle_stats_ready = 1;
7188 }
7189 if (directional_mode_skip_mask[mbmi->mode])
7190 continue;
hui su4aa50c12015-11-10 12:09:59 -08007191 rate_overhead = write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0) +
hui su1559afd2015-12-30 10:27:19 -08007192 intra_mode_cost[mbmi->mode];
hui su4aa50c12015-11-10 12:09:59 -08007193 rate_y = INT_MAX;
7194 this_rd =
7195 rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
7196 &skippable, bsize, rate_overhead, best_rd);
7197 } else {
7198 mbmi->angle_delta[0] = 0;
7199 super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
7200 NULL, bsize, best_rd);
7201 }
7202
hui sube3559b2015-10-07 09:29:02 -07007203 // TODO(huisu): ext-intra is turned off in lossless mode for now to
7204 // avoid a unit test failure
hui su4aa50c12015-11-10 12:09:59 -08007205 if (mbmi->mode == DC_PRED && !xd->lossless[mbmi->segment_id] &&
7206 ALLOW_FILTER_INTRA_MODES) {
hui sube3559b2015-10-07 09:29:02 -07007207 MB_MODE_INFO mbmi_copy = *mbmi;
hui sube3559b2015-10-07 09:29:02 -07007208
7209 if (rate_y != INT_MAX) {
hui su1559afd2015-12-30 10:27:19 -08007210 int this_rate = rate_y + intra_mode_cost[mbmi->mode] +
hui sube3559b2015-10-07 09:29:02 -07007211 vp10_cost_bit(cm->fc->ext_intra_probs[0], 0);
7212 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, distortion_y);
7213 } else {
7214 this_rd = best_rd;
7215 }
7216
7217 if (!rd_pick_ext_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
7218 &skippable, bsize,
hui su1559afd2015-12-30 10:27:19 -08007219 intra_mode_cost[mbmi->mode], &this_rd))
hui sube3559b2015-10-07 09:29:02 -07007220 *mbmi = mbmi_copy;
7221 }
hui su4aa50c12015-11-10 12:09:59 -08007222#else
7223 super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
7224 NULL, bsize, best_rd);
hui sube3559b2015-10-07 09:29:02 -07007225#endif // CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08007226
Jingning Han3ee6db62015-08-05 19:00:31 -07007227 if (rate_y == INT_MAX)
7228 continue;
Jingning Han3ee6db62015-08-05 19:00:31 -07007229 uv_tx = get_uv_tx_size_impl(mbmi->tx_size, bsize, pd->subsampling_x,
7230 pd->subsampling_y);
7231 if (rate_uv_intra[uv_tx] == INT_MAX) {
7232 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx,
7233 &rate_uv_intra[uv_tx], &rate_uv_tokenonly[uv_tx],
7234 &dist_uv[uv_tx], &skip_uv[uv_tx], &mode_uv[uv_tx]);
hui sube3559b2015-10-07 09:29:02 -07007235#if CONFIG_EXT_INTRA
7236 ext_intra_mode_info_uv[uv_tx] = mbmi->ext_intra_mode_info;
hui su4aa50c12015-11-10 12:09:59 -08007237 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui sube3559b2015-10-07 09:29:02 -07007238#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07007239 }
7240
7241 rate_uv = rate_uv_tokenonly[uv_tx];
7242 distortion_uv = dist_uv[uv_tx];
7243 skippable = skippable && skip_uv[uv_tx];
7244 mbmi->uv_mode = mode_uv[uv_tx];
hui sube3559b2015-10-07 09:29:02 -07007245#if CONFIG_EXT_INTRA
hui su4aa50c12015-11-10 12:09:59 -08007246 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui sube3559b2015-10-07 09:29:02 -07007247 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
7248 ext_intra_mode_info_uv[uv_tx].use_ext_intra_mode[1];
7249 if (ext_intra_mode_info_uv[uv_tx].use_ext_intra_mode[1]) {
7250 mbmi->ext_intra_mode_info.ext_intra_mode[1] =
7251 ext_intra_mode_info_uv[uv_tx].ext_intra_mode[1];
hui sube3559b2015-10-07 09:29:02 -07007252 }
7253#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07007254
hui su1559afd2015-12-30 10:27:19 -08007255 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv_intra[uv_tx];
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08007256
7257 if (!xd->lossless[mbmi->segment_id]) {
7258 // super_block_yrd above includes the cost of the tx_size in the
7259 // tokenonly rate, but for intra blocks, tx_size is always coded
7260 // (prediction granularity), so we account for it in the full rate,
7261 // not the tokenonly rate.
hui su954e5602016-03-07 15:25:50 -08007262 rate_y -=
7263 cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
7264 [mbmi->tx_size];
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08007265 }
hui sube3559b2015-10-07 09:29:02 -07007266#if CONFIG_EXT_INTRA
hui su3b1c7662016-01-12 16:38:58 -08007267 if (is_directional_mode) {
7268 int p_angle;
7269 const int intra_filter_ctx = vp10_get_pred_context_intra_interp(xd);
hui su4aa50c12015-11-10 12:09:59 -08007270 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
7271 MAX_ANGLE_DELTAS +
7272 mbmi->angle_delta[0]);
hui su3b1c7662016-01-12 16:38:58 -08007273 p_angle = mode_to_angle_map[mbmi->mode] +
7274 mbmi->angle_delta[0] * ANGLE_STEP;
7275 if (pick_intra_filter(p_angle))
7276 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
7277 }
hui su4aa50c12015-11-10 12:09:59 -08007278
7279 if (mbmi->mode == DC_PRED && ALLOW_FILTER_INTRA_MODES) {
hui sube3559b2015-10-07 09:29:02 -07007280 rate2 += vp10_cost_bit(cm->fc->ext_intra_probs[0],
7281 mbmi->ext_intra_mode_info.use_ext_intra_mode[0]);
7282 if (mbmi->ext_intra_mode_info.use_ext_intra_mode[0]) {
7283 EXT_INTRA_MODE ext_intra_mode =
7284 mbmi->ext_intra_mode_info.ext_intra_mode[0];
hui su4aa50c12015-11-10 12:09:59 -08007285 rate2 += write_uniform_cost(FILTER_INTRA_MODES, ext_intra_mode);
hui sube3559b2015-10-07 09:29:02 -07007286 }
7287 }
7288#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07007289 if (this_mode != DC_PRED && this_mode != TM_PRED)
7290 rate2 += intra_cost_penalty;
7291 distortion2 = distortion_y + distortion_uv;
7292 } else {
Geza Lore7ded0382016-02-22 10:55:32 +00007293#if CONFIG_EXT_INTER
7294 if (second_ref_frame == INTRA_FRAME) {
7295 mbmi->interintra_mode = best_intra_mode;
7296 mbmi->interintra_uv_mode = best_intra_mode;
7297#if CONFIG_EXT_INTRA
7298 // TODO(debargha|geza.lore):
7299 // Should we use ext_intra modes for interintra?
7300 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
7301 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
7302 mbmi->angle_delta[0] = 0;
7303 mbmi->angle_delta[1] = 0;
7304 mbmi->intra_filter = INTRA_FILTER_LINEAR;
7305#endif // CONFIG_EXT_INTRA
7306 }
7307#endif // CONFIG_EXT_INTER
Jingning Han28e03932016-01-20 17:40:47 -08007308#if CONFIG_REF_MV
7309 mbmi->ref_mv_idx = 0;
7310 ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
7311#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07007312 this_rd = handle_inter_mode(cpi, x, bsize,
7313 &rate2, &distortion2, &skippable,
7314 &rate_y, &rate_uv,
7315 &disable_skip, frame_mv,
7316 mi_row, mi_col,
Yue Chend1cad9c2016-01-27 14:18:53 -08007317#if CONFIG_OBMC
7318 dst_buf1, dst_stride1,
7319 dst_buf2, dst_stride2,
7320#endif // CONFIG_OBMC
Yue Chen1ac85872016-01-07 15:13:52 -08007321#if CONFIG_EXT_INTER
7322 single_newmvs,
Geza Lore7ded0382016-02-22 10:55:32 +00007323 single_newmvs_rate,
7324 &compmode_interintra_cost,
Yue Chen1ac85872016-01-07 15:13:52 -08007325#else
7326 single_newmv,
7327#endif // CONFIG_EXT_INTER
7328 single_inter_filter,
Geza Lore7ded0382016-02-22 10:55:32 +00007329 single_skippable,
7330 &total_sse, best_rd,
Jingning Han3ee6db62015-08-05 19:00:31 -07007331 &mask_filter, filter_cache);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07007332
Jingning Han67cf8902016-01-15 09:05:51 -08007333#if CONFIG_REF_MV
Jingning Han4fb8b212016-01-19 16:36:25 -08007334 // TODO(jingning): This needs some refactoring to improve code quality
7335 // and reduce redundant steps.
Jingning Han28e03932016-01-20 17:40:47 -08007336 if (mbmi->mode == NEARMV &&
7337 mbmi_ext->ref_mv_count[ref_frame_type] > 2) {
Jingning Han67cf8902016-01-15 09:05:51 -08007338 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
7339 int_mv cur_mv = mbmi_ext->ref_mv_stack[ref_frame][2].this_mv;
7340 MB_MODE_INFO backup_mbmi = *mbmi;
7341
Jingning Han4fb8b212016-01-19 16:36:25 -08007342 int64_t tmp_ref_rd = this_rd;
7343 int ref_idx;
Jingning Han28e03932016-01-20 17:40:47 -08007344 int ref_set = VPXMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 2);
7345
Jingning Han49589872016-01-21 18:07:31 -08007346 uint8_t drl0_ctx =
Jingning Hana39e83d2016-02-11 16:38:13 -08007347 vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 1);
Jingning Han49589872016-01-21 18:07:31 -08007348 rate2 += cpi->drl_mode_cost0[drl0_ctx][0];
Jingning Han67cf8902016-01-15 09:05:51 -08007349
Jingning Han590265e2016-01-15 11:33:40 -08007350 if (this_rd < INT64_MAX) {
7351 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
7352 RDCOST(x->rdmult, x->rddiv, 0, total_sse))
7353 tmp_ref_rd = RDCOST(x->rdmult, x->rddiv,
7354 rate2 + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0),
7355 distortion2);
7356 else
7357 tmp_ref_rd = RDCOST(x->rdmult, x->rddiv,
7358 rate2 + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1) -
7359 rate_y - rate_uv,
7360 total_sse);
7361 }
Jingning Han7174d632016-03-03 09:20:10 -08007362#if CONFIG_VAR_TX
7363 for (i = 0; i < MAX_MB_PLANE; ++i)
7364 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
7365 sizeof(uint8_t) * ctx->num_4x4_blk);
7366#endif
Jingning Han590265e2016-01-15 11:33:40 -08007367
Jingning Han4fb8b212016-01-19 16:36:25 -08007368 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
7369 int64_t tmp_alt_rd = INT64_MAX;
7370 int tmp_rate = 0, tmp_rate_y = 0, tmp_rate_uv = 0;
7371 int tmp_skip = 1;
7372 int64_t tmp_dist = 0, tmp_sse = 0;
Jingning Han590265e2016-01-15 11:33:40 -08007373
Jingning Han4fb8b212016-01-19 16:36:25 -08007374 cur_mv = mbmi_ext->ref_mv_stack[ref_frame][2 + ref_idx].this_mv;
7375 lower_mv_precision(&cur_mv.as_mv, cm->allow_high_precision_mv);
7376 clamp_mv2(&cur_mv.as_mv, xd);
7377
7378 if (!mv_check_bounds(x, &cur_mv.as_mv)) {
7379 int64_t dummy_filter_cache[SWITCHABLE_FILTER_CONTEXTS];
7380 INTERP_FILTER dummy_single_inter_filter[MB_MODE_COUNT]
7381 [MAX_REF_FRAMES];
7382 int dummy_single_skippable[MB_MODE_COUNT][MAX_REF_FRAMES];
7383 int dummy_disable_skip = 0;
7384 int64_t dummy_mask_filter = 0;
7385#if CONFIG_EXT_INTER
7386 int_mv dummy_single_newmvs[2][MAX_REF_FRAMES] =
7387 { { { 0 } }, { { 0 } } };
Geza Lore7ded0382016-02-22 10:55:32 +00007388 int dummy_single_newmvs_rate[2][MAX_REF_FRAMES] =
7389 { { 0 }, { 0 } };
7390 int dummy_compmode_interintra_cost = 0;
Jingning Han4fb8b212016-01-19 16:36:25 -08007391#else
7392 int_mv dummy_single_newmv[MAX_REF_FRAMES] = { { 0 } };
7393#endif
Jingning Han28e03932016-01-20 17:40:47 -08007394 mbmi->ref_mv_idx = 1 + ref_idx;
7395
Jingning Han4fb8b212016-01-19 16:36:25 -08007396 frame_mv[NEARMV][ref_frame] = cur_mv;
7397 tmp_alt_rd = handle_inter_mode(cpi, x, bsize,
7398 &tmp_rate, &tmp_dist, &tmp_skip,
7399 &tmp_rate_y, &tmp_rate_uv,
7400 &dummy_disable_skip, frame_mv,
7401 mi_row, mi_col,
Yue Chend1cad9c2016-01-27 14:18:53 -08007402#if CONFIG_OBMC
7403 dst_buf1, dst_stride1,
7404 dst_buf2, dst_stride2,
7405#endif // CONFIG_OBMC
Jingning Han4fb8b212016-01-19 16:36:25 -08007406#if CONFIG_EXT_INTER
7407 dummy_single_newmvs,
Geza Lore7ded0382016-02-22 10:55:32 +00007408 dummy_single_newmvs_rate,
7409 &dummy_compmode_interintra_cost,
Jingning Han4fb8b212016-01-19 16:36:25 -08007410#else
7411 dummy_single_newmv,
7412#endif
7413 dummy_single_inter_filter,
7414 dummy_single_skippable,
7415 &tmp_sse, best_rd,
7416 &dummy_mask_filter,
7417 dummy_filter_cache);
7418 }
7419
Jingning Han49589872016-01-21 18:07:31 -08007420 tmp_rate += cpi->drl_mode_cost0[drl0_ctx][1];
7421
7422 if (mbmi_ext->ref_mv_count[ref_frame_type] > 3) {
7423 uint8_t drl1_ctx =
Jingning Hana39e83d2016-02-11 16:38:13 -08007424 vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 2);
Jingning Han49589872016-01-21 18:07:31 -08007425 tmp_rate += cpi->drl_mode_cost1[drl1_ctx][ref_idx];
7426 }
Jingning Han4fb8b212016-01-19 16:36:25 -08007427
7428 if (tmp_alt_rd < INT64_MAX) {
Yue Chena6142622016-02-18 12:35:14 -08007429#if CONFIG_OBMC
7430 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv, tmp_rate, tmp_dist);
7431#else
Jingning Han4fb8b212016-01-19 16:36:25 -08007432 if (RDCOST(x->rdmult, x->rddiv,
7433 tmp_rate_y + tmp_rate_uv, tmp_dist) <
7434 RDCOST(x->rdmult, x->rddiv, 0, tmp_sse))
7435 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv,
7436 tmp_rate + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0),
7437 tmp_dist);
7438 else
7439 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv,
7440 tmp_rate + vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1) -
7441 tmp_rate_y - tmp_rate_uv,
7442 tmp_sse);
Yue Chena6142622016-02-18 12:35:14 -08007443#endif // CONFIG_OBMC
Jingning Han4fb8b212016-01-19 16:36:25 -08007444 }
7445
7446 if (tmp_ref_rd > tmp_alt_rd) {
7447 rate2 = tmp_rate;
7448 distortion2 = tmp_dist;
7449 skippable = tmp_skip;
7450 rate_y = tmp_rate_y;
7451 rate_uv = tmp_rate_uv;
7452 total_sse = tmp_sse;
7453 this_rd = tmp_alt_rd;
Jingning Han4fb8b212016-01-19 16:36:25 -08007454 tmp_ref_rd = tmp_alt_rd;
7455 backup_mbmi = *mbmi;
Jingning Han7174d632016-03-03 09:20:10 -08007456#if CONFIG_VAR_TX
7457 for (i = 0; i < MAX_MB_PLANE; ++i)
7458 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
7459 sizeof(uint8_t) * ctx->num_4x4_blk);
7460#endif
Jingning Han4fb8b212016-01-19 16:36:25 -08007461 } else {
7462 *mbmi = backup_mbmi;
7463 }
Jingning Han67cf8902016-01-15 09:05:51 -08007464 }
7465
7466 frame_mv[NEARMV][ref_frame] = backup_mv;
Jingning Han7174d632016-03-03 09:20:10 -08007467#if CONFIG_VAR_TX
7468 for (i = 0; i < MAX_MB_PLANE; ++i)
7469 memcpy(x->blk_skip[i], x->blk_skip_drl[i],
7470 sizeof(uint8_t) * ctx->num_4x4_blk);
7471#endif
Jingning Han67cf8902016-01-15 09:05:51 -08007472 }
Geza Lore7ded0382016-02-22 10:55:32 +00007473#endif // CONFIG_REF_MV
Jingning Han67cf8902016-01-15 09:05:51 -08007474
Jingning Han3ee6db62015-08-05 19:00:31 -07007475 if (this_rd == INT64_MAX)
7476 continue;
7477
7478 compmode_cost = vp10_cost_bit(comp_mode_p, comp_pred);
7479
7480 if (cm->reference_mode == REFERENCE_MODE_SELECT)
7481 rate2 += compmode_cost;
7482 }
7483
Geza Lore7ded0382016-02-22 10:55:32 +00007484#if CONFIG_EXT_INTER
7485 rate2 += compmode_interintra_cost;
7486#endif // CONFIG_EXT_INTER
7487
Jingning Han3ee6db62015-08-05 19:00:31 -07007488 // Estimate the reference frame signaling cost and add it
7489 // to the rolling cost variable.
7490 if (comp_pred) {
7491 rate2 += ref_costs_comp[ref_frame];
7492 } else {
7493 rate2 += ref_costs_single[ref_frame];
7494 }
7495
Yue Chena6142622016-02-18 12:35:14 -08007496#if CONFIG_OBMC
7497 if (ref_frame == INTRA_FRAME) {
7498#else
Jingning Han3ee6db62015-08-05 19:00:31 -07007499 if (!disable_skip) {
Yue Chena6142622016-02-18 12:35:14 -08007500#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007501 if (skippable) {
7502 // Back out the coefficient coding costs
7503 rate2 -= (rate_y + rate_uv);
Debargha Mukherjee3787b172015-11-19 16:51:16 -08007504 rate_y = 0;
7505 rate_uv = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07007506 // Cost the skip mb case
7507 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04007508 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Jingning Han3ee6db62015-08-05 19:00:31 -07007509 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
7510 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
7511 // Add in the cost of the no skip flag.
7512 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
7513 } else {
7514 // FIXME(rbultje) make this work for splitmv also
7515 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
7516 distortion2 = total_sse;
7517 assert(total_sse >= 0);
7518 rate2 -= (rate_y + rate_uv);
7519 this_skip2 = 1;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08007520 rate_y = 0;
7521 rate_uv = 0;
Jingning Han3ee6db62015-08-05 19:00:31 -07007522 }
7523 } else {
7524 // Add in the cost of the no skip flag.
7525 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
7526 }
7527
7528 // Calculate the final RD estimate for this mode.
7529 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yue Chena6142622016-02-18 12:35:14 -08007530#if CONFIG_OBMC
7531 } else {
7532 this_skip2 = mbmi->skip;
7533 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
7534#endif // CONFIG_OBMC
Jingning Han3ee6db62015-08-05 19:00:31 -07007535 }
7536
Yue Chena6142622016-02-18 12:35:14 -08007537
Jingning Han3ee6db62015-08-05 19:00:31 -07007538 // Apply an adjustment to the rd value based on the similarity of the
7539 // source variance and reconstructed variance.
Yue Chena6142622016-02-18 12:35:14 -08007540 rd_variance_adjustment(cpi, x, bsize, &this_rd, ref_frame,
7541#if CONFIG_OBMC
7542 is_inter_block(mbmi),
7543#endif // CONFIG_OBMC
7544 x->source_variance);
Jingning Han3ee6db62015-08-05 19:00:31 -07007545
7546 if (ref_frame == INTRA_FRAME) {
7547 // Keep record of best intra rd
7548 if (this_rd < best_intra_rd) {
7549 best_intra_rd = this_rd;
7550 best_intra_mode = mbmi->mode;
7551 }
7552 }
7553
7554 if (!disable_skip && ref_frame == INTRA_FRAME) {
7555 for (i = 0; i < REFERENCE_MODES; ++i)
James Zern5e16d392015-08-17 18:19:22 -07007556 best_pred_rd[i] = VPXMIN(best_pred_rd[i], this_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07007557 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
James Zern5e16d392015-08-17 18:19:22 -07007558 best_filter_rd[i] = VPXMIN(best_filter_rd[i], this_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07007559 }
7560
7561 // Did this mode help.. i.e. is it the new best mode
7562 if (this_rd < best_rd || x->skip) {
7563 int max_plane = MAX_MB_PLANE;
7564 if (!mode_excluded) {
7565 // Note index of best mode so far
7566 best_mode_index = mode_index;
7567
7568 if (ref_frame == INTRA_FRAME) {
7569 /* required for left and above block mv */
7570 mbmi->mv[0].as_int = 0;
7571 max_plane = 1;
7572 } else {
7573 best_pred_sse = x->pred_sse[ref_frame];
7574 }
7575
7576 rd_cost->rate = rate2;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08007577#if CONFIG_SUPERTX
7578 *returnrate_nocoef = rate2 - rate_y - rate_uv;
7579 if (!disable_skip) {
7580 *returnrate_nocoef -= vp10_cost_bit(vp10_get_skip_prob(cm, xd),
7581 skippable || this_skip2);
7582 }
7583 *returnrate_nocoef -= vp10_cost_bit(vp10_get_intra_inter_prob(cm, xd),
7584 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chend1cad9c2016-01-27 14:18:53 -08007585#if CONFIG_OBMC
7586 if (is_inter_block(mbmi) && is_obmc_allowed(mbmi))
7587 *returnrate_nocoef -= cpi->obmc_cost[bsize][mbmi->obmc];
7588#endif // CONFIG_OBMC
Debargha Mukherjee3787b172015-11-19 16:51:16 -08007589#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07007590 rd_cost->dist = distortion2;
7591 rd_cost->rdcost = this_rd;
7592 best_rd = this_rd;
7593 best_mbmode = *mbmi;
7594 best_skip2 = this_skip2;
7595 best_mode_skippable = skippable;
7596
7597 if (!x->select_tx_size)
7598 swap_block_ptr(x, ctx, 1, 0, 0, max_plane);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07007599
7600#if CONFIG_VAR_TX
7601 for (i = 0; i < MAX_MB_PLANE; ++i)
7602 memcpy(ctx->blk_skip[i], x->blk_skip[i],
7603 sizeof(uint8_t) * ctx->num_4x4_blk);
7604#else
Jingning Han3ee6db62015-08-05 19:00:31 -07007605 memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
hui su088b05f2015-08-12 10:41:51 -07007606 sizeof(ctx->zcoeff_blk[0]) * ctx->num_4x4_blk);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07007607#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07007608
7609 // TODO(debargha): enhance this test with a better distortion prediction
7610 // based on qp, activity mask and history
7611 if ((mode_search_skip_flags & FLAG_EARLY_TERMINATE) &&
7612 (mode_index > MIN_EARLY_TERM_INDEX)) {
7613 int qstep = xd->plane[0].dequant[1];
7614 // TODO(debargha): Enhance this by specializing for each mode_index
7615 int scale = 4;
7616#if CONFIG_VP9_HIGHBITDEPTH
7617 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
7618 qstep >>= (xd->bd - 8);
7619 }
7620#endif // CONFIG_VP9_HIGHBITDEPTH
7621 if (x->source_variance < UINT_MAX) {
7622 const int var_adjust = (x->source_variance < 16);
7623 scale -= var_adjust;
7624 }
7625 if (ref_frame > INTRA_FRAME &&
7626 distortion2 * scale < qstep * qstep) {
7627 early_term = 1;
7628 }
7629 }
7630 }
7631 }
7632
7633 /* keep record of best compound/single-only prediction */
7634 if (!disable_skip && ref_frame != INTRA_FRAME) {
7635 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
7636
7637 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
7638 single_rate = rate2 - compmode_cost;
7639 hybrid_rate = rate2;
7640 } else {
7641 single_rate = rate2;
7642 hybrid_rate = rate2 + compmode_cost;
7643 }
7644
7645 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
7646 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
7647
7648 if (!comp_pred) {
7649 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
7650 best_pred_rd[SINGLE_REFERENCE] = single_rd;
7651 } else {
7652 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
7653 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
7654 }
7655 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
7656 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
7657
7658 /* keep record of best filter type */
7659 if (!mode_excluded && cm->interp_filter != BILINEAR) {
7660 int64_t ref = filter_cache[cm->interp_filter == SWITCHABLE ?
7661 SWITCHABLE_FILTERS : cm->interp_filter];
7662
7663 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
7664 int64_t adj_rd;
7665 if (ref == INT64_MAX)
7666 adj_rd = 0;
7667 else if (filter_cache[i] == INT64_MAX)
7668 // when early termination is triggered, the encoder does not have
7669 // access to the rate-distortion cost. it only knows that the cost
7670 // should be above the maximum valid value. hence it takes the known
7671 // maximum plus an arbitrary constant as the rate-distortion cost.
7672 adj_rd = mask_filter - ref + 10;
7673 else
7674 adj_rd = filter_cache[i] - ref;
7675
7676 adj_rd += this_rd;
James Zern5e16d392015-08-17 18:19:22 -07007677 best_filter_rd[i] = VPXMIN(best_filter_rd[i], adj_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07007678 }
7679 }
7680 }
7681
7682 if (early_term)
7683 break;
7684
7685 if (x->skip && !comp_pred)
7686 break;
7687 }
7688
7689 // The inter modes' rate costs are not calculated precisely in some cases.
7690 // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
7691 // ZEROMV. Here, checks are added for those cases, and the mode decisions
7692 // are corrected.
Yue Chen1ac85872016-01-07 15:13:52 -08007693 if (best_mbmode.mode == NEWMV
7694#if CONFIG_EXT_INTER
7695 || best_mbmode.mode == NEWFROMNEARMV
Yue Chen968bbc72016-01-19 16:45:45 -08007696 || best_mbmode.mode == NEW_NEWMV
Yue Chen1ac85872016-01-07 15:13:52 -08007697#endif // CONFIG_EXT_INTER
7698 ) {
Jingning Han3ee6db62015-08-05 19:00:31 -07007699 const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0],
7700 best_mbmode.ref_frame[1]};
7701 int comp_pred_mode = refs[1] > INTRA_FRAME;
Jingning Han33cc1bd2016-01-12 15:06:59 -08007702#if CONFIG_REF_MV
Geza Lore7ded0382016-02-22 10:55:32 +00007703 const uint8_t rf_type = vp10_ref_frame_type(best_mbmode.ref_frame);
Jingning Han33cc1bd2016-01-12 15:06:59 -08007704 if (!comp_pred_mode) {
Geza Lore7ded0382016-02-22 10:55:32 +00007705 if (best_mbmode.ref_mv_idx > 0 && refs[1] == NONE) {
7706 int idx = best_mbmode.ref_mv_idx + 1;
7707 int_mv cur_mv = mbmi_ext->ref_mv_stack[refs[0]][idx].this_mv;
Jingning Han67cf8902016-01-15 09:05:51 -08007708 lower_mv_precision(&cur_mv.as_mv, cm->allow_high_precision_mv);
7709 frame_mv[NEARMV][refs[0]] = cur_mv;
7710 }
7711
Jingning Han33cc1bd2016-01-12 15:06:59 -08007712 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
7713 best_mbmode.mode = NEARESTMV;
7714 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
7715 best_mbmode.mode = NEARMV;
7716 else if (best_mbmode.mv[0].as_int == 0)
7717 best_mbmode.mode = ZEROMV;
7718 } else {
Jingning Han3944cfb2016-01-13 09:03:15 -08007719 int i;
7720 const int allow_hp = cm->allow_high_precision_mv;
7721 int_mv nearestmv[2] = { frame_mv[NEARESTMV][refs[0]],
7722 frame_mv[NEARESTMV][refs[1]] };
Jingning Han3ee6db62015-08-05 19:00:31 -07007723
Jingning Han3944cfb2016-01-13 09:03:15 -08007724 int_mv nearmv[2] = { frame_mv[NEARMV][refs[0]],
7725 frame_mv[NEARMV][refs[1]] };
7726
7727 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
Jingning Han33cc1bd2016-01-12 15:06:59 -08007728 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
7729 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
Jingning Han3944cfb2016-01-13 09:03:15 -08007730 }
7731
7732 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
Geza Lore7ded0382016-02-22 10:55:32 +00007733 int ref_mv_idx = best_mbmode.ref_mv_idx + 1;
Jingning Han28e03932016-01-20 17:40:47 -08007734 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][ref_mv_idx].this_mv;
7735 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][ref_mv_idx].comp_mv;
Jingning Han33cc1bd2016-01-12 15:06:59 -08007736 }
Jingning Han3944cfb2016-01-13 09:03:15 -08007737
7738 for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
7739 lower_mv_precision(&nearestmv[i].as_mv, allow_hp);
7740 lower_mv_precision(&nearmv[i].as_mv, allow_hp);
7741 }
7742
7743 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
7744 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
Yue Chen968bbc72016-01-19 16:45:45 -08007745#if CONFIG_EXT_INTER
7746 best_mbmode.mode = NEAREST_NEARESTMV;
7747 else if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
7748 nearmv[1].as_int == best_mbmode.mv[1].as_int)
7749 best_mbmode.mode = NEAREST_NEARMV;
7750 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
7751 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
7752 best_mbmode.mode = NEAR_NEARESTMV;
7753 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
7754 best_mbmode.mode = ZERO_ZEROMV;
7755#else
Jingning Han3944cfb2016-01-13 09:03:15 -08007756 best_mbmode.mode = NEARESTMV;
7757 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
7758 nearmv[1].as_int == best_mbmode.mv[1].as_int)
7759 best_mbmode.mode = NEARMV;
7760 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
7761 best_mbmode.mode = ZEROMV;
Yue Chen968bbc72016-01-19 16:45:45 -08007762#endif // CONFIG_EXT_INTER
Jingning Han33cc1bd2016-01-12 15:06:59 -08007763 }
7764#else
Yue Chen968bbc72016-01-19 16:45:45 -08007765#if CONFIG_EXT_INTER
7766 if (!comp_pred_mode) {
7767#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07007768 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
7769 ((comp_pred_mode && frame_mv[NEARESTMV][refs[1]].as_int ==
7770 best_mbmode.mv[1].as_int) || !comp_pred_mode))
7771 best_mbmode.mode = NEARESTMV;
7772 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
7773 ((comp_pred_mode && frame_mv[NEARMV][refs[1]].as_int ==
7774 best_mbmode.mv[1].as_int) || !comp_pred_mode))
7775 best_mbmode.mode = NEARMV;
7776 else if (best_mbmode.mv[0].as_int == 0 &&
7777 ((comp_pred_mode && best_mbmode.mv[1].as_int == 0) || !comp_pred_mode))
7778 best_mbmode.mode = ZEROMV;
Yue Chen968bbc72016-01-19 16:45:45 -08007779#if CONFIG_EXT_INTER
7780 } else {
7781 const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0],
7782 best_mbmode.ref_frame[1]};
7783
7784 if (frame_mv[NEAREST_NEARESTMV][refs[0]].as_int ==
7785 best_mbmode.mv[0].as_int &&
7786 frame_mv[NEAREST_NEARESTMV][refs[1]].as_int ==
7787 best_mbmode.mv[1].as_int)
7788 best_mbmode.mode = NEAREST_NEARESTMV;
7789 else if (frame_mv[NEAREST_NEARMV][refs[0]].as_int ==
7790 best_mbmode.mv[0].as_int &&
7791 frame_mv[NEAREST_NEARMV][refs[1]].as_int ==
7792 best_mbmode.mv[1].as_int)
7793 best_mbmode.mode = NEAREST_NEARMV;
7794 else if (frame_mv[NEAR_NEARESTMV][refs[0]].as_int ==
7795 best_mbmode.mv[0].as_int &&
7796 frame_mv[NEAR_NEARESTMV][refs[1]].as_int ==
7797 best_mbmode.mv[1].as_int)
7798 best_mbmode.mode = NEAR_NEARESTMV;
7799 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
7800 best_mbmode.mode = ZERO_ZEROMV;
7801 }
7802#endif // CONFIG_EXT_INTER
Jingning Han33cc1bd2016-01-12 15:06:59 -08007803#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07007804 }
7805
Jingning Hanaa5d53e2015-12-07 15:54:59 -08007806#if CONFIG_REF_MV
7807 if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
7808 best_mbmode.mv[0].as_int == 0 &&
Yue Chen968bbc72016-01-19 16:45:45 -08007809#if CONFIG_EXT_INTER
Geza Lore7ded0382016-02-22 10:55:32 +00007810 (best_mbmode.ref_frame[1] <= INTRA_FRAME)
Yue Chen968bbc72016-01-19 16:45:45 -08007811#else
Geza Lore7ded0382016-02-22 10:55:32 +00007812 (best_mbmode.ref_frame[1] == NONE || best_mbmode.mv[1].as_int == 0)
Yue Chen968bbc72016-01-19 16:45:45 -08007813#endif // CONFIG_EXT_INTER
Geza Lore7ded0382016-02-22 10:55:32 +00007814 ) {
Jingning Hanaa5d53e2015-12-07 15:54:59 -08007815 int16_t mode_ctx = mbmi_ext->mode_context[best_mbmode.ref_frame[0]];
Yue Chen968bbc72016-01-19 16:45:45 -08007816#if !CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08007817 if (best_mbmode.ref_frame[1] > NONE)
7818 mode_ctx &= (mbmi_ext->mode_context[best_mbmode.ref_frame[1]] | 0x00ff);
Yue Chen968bbc72016-01-19 16:45:45 -08007819#endif // !CONFIG_EXT_INTER
Jingning Hanaa5d53e2015-12-07 15:54:59 -08007820
7821 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET))
7822 best_mbmode.mode = ZEROMV;
7823 }
7824#endif
7825
Jingning Han3ee6db62015-08-05 19:00:31 -07007826 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
7827 rd_cost->rate = INT_MAX;
7828 rd_cost->rdcost = INT64_MAX;
7829 return;
7830 }
7831
7832 // If we used an estimate for the uv intra rd in the loop above...
7833 if (sf->use_uv_intra_rd_estimate) {
7834 // Do Intra UV best rd mode selection if best mode choice above was intra.
7835 if (best_mbmode.ref_frame[0] == INTRA_FRAME) {
7836 TX_SIZE uv_tx_size;
7837 *mbmi = best_mbmode;
7838 uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
7839 rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra[uv_tx_size],
7840 &rate_uv_tokenonly[uv_tx_size],
7841 &dist_uv[uv_tx_size],
7842 &skip_uv[uv_tx_size],
7843 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize,
7844 uv_tx_size);
7845 }
7846 }
7847
7848 assert((cm->interp_filter == SWITCHABLE) ||
7849 (cm->interp_filter == best_mbmode.interp_filter) ||
7850 !is_inter_block(&best_mbmode));
7851
7852 if (!cpi->rc.is_src_frame_alt_ref)
7853 vp10_update_rd_thresh_fact(tile_data->thresh_freq_fact,
7854 sf->adaptive_rd_thresh, bsize, best_mode_index);
7855
7856 // macroblock modes
7857 *mbmi = best_mbmode;
7858 x->skip |= best_skip2;
7859
Jingning Handf59bb82016-02-18 11:57:44 -08007860#if CONFIG_REF_MV
7861 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
7862 if (mbmi->mode != NEWMV)
7863 mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
7864 else
7865 mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
7866 }
7867#endif
7868
Jingning Han3ee6db62015-08-05 19:00:31 -07007869 for (i = 0; i < REFERENCE_MODES; ++i) {
7870 if (best_pred_rd[i] == INT64_MAX)
7871 best_pred_diff[i] = INT_MIN;
7872 else
7873 best_pred_diff[i] = best_rd - best_pred_rd[i];
7874 }
7875
7876 if (!x->skip) {
7877 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
7878 if (best_filter_rd[i] == INT64_MAX)
7879 best_filter_diff[i] = 0;
7880 else
7881 best_filter_diff[i] = best_rd - best_filter_rd[i];
7882 }
7883 if (cm->interp_filter == SWITCHABLE)
7884 assert(best_filter_diff[SWITCHABLE_FILTERS] == 0);
7885 } else {
7886 vp10_zero(best_filter_diff);
7887 }
7888
7889 // TODO(yunqingwang): Moving this line in front of the above best_filter_diff
7890 // updating code causes PSNR loss. Need to figure out the confliction.
7891 x->skip |= best_mode_skippable;
7892
7893 if (!x->skip && !x->select_tx_size) {
7894 int has_high_freq_coeff = 0;
7895 int plane;
7896 int max_plane = is_inter_block(&xd->mi[0]->mbmi)
7897 ? MAX_MB_PLANE : 1;
7898 for (plane = 0; plane < max_plane; ++plane) {
7899 x->plane[plane].eobs = ctx->eobs_pbuf[plane][1];
7900 has_high_freq_coeff |= vp10_has_high_freq_in_plane(x, bsize, plane);
7901 }
7902
7903 for (plane = max_plane; plane < MAX_MB_PLANE; ++plane) {
7904 x->plane[plane].eobs = ctx->eobs_pbuf[plane][2];
7905 has_high_freq_coeff |= vp10_has_high_freq_in_plane(x, bsize, plane);
7906 }
7907
7908 best_mode_skippable |= !has_high_freq_coeff;
7909 }
7910
7911 assert(best_mode_index >= 0);
7912
7913 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
7914 best_filter_diff, best_mode_skippable);
7915}
7916
Yaowu Xu26a9afc2015-08-13 09:42:27 -07007917void vp10_rd_pick_inter_mode_sb_seg_skip(VP10_COMP *cpi,
Jingning Han3ee6db62015-08-05 19:00:31 -07007918 TileDataEnc *tile_data,
7919 MACROBLOCK *x,
7920 RD_COST *rd_cost,
7921 BLOCK_SIZE bsize,
7922 PICK_MODE_CONTEXT *ctx,
7923 int64_t best_rd_so_far) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07007924 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07007925 MACROBLOCKD *const xd = &x->e_mbd;
7926 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7927 unsigned char segment_id = mbmi->segment_id;
7928 const int comp_pred = 0;
7929 int i;
7930 int64_t best_pred_diff[REFERENCE_MODES];
7931 int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
7932 unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
7933 vpx_prob comp_mode_p;
7934 INTERP_FILTER best_filter = SWITCHABLE;
7935 int64_t this_rd = INT64_MAX;
7936 int rate2 = 0;
7937 const int64_t distortion2 = 0;
7938
Jingning Han3ee6db62015-08-05 19:00:31 -07007939 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
7940 &comp_mode_p);
7941
7942 for (i = 0; i < MAX_REF_FRAMES; ++i)
7943 x->pred_sse[i] = INT_MAX;
7944 for (i = LAST_FRAME; i < MAX_REF_FRAMES; ++i)
7945 x->pred_mv_sad[i] = INT_MAX;
7946
7947 rd_cost->rate = INT_MAX;
7948
7949 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
7950
hui suc93e5cc2015-12-07 18:18:57 -08007951 mbmi->palette_mode_info.palette_size[0] = 0;
7952 mbmi->palette_mode_info.palette_size[1] = 0;
hui sube3559b2015-10-07 09:29:02 -07007953#if CONFIG_EXT_INTRA
7954 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
7955 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
7956#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07007957 mbmi->mode = ZEROMV;
7958 mbmi->uv_mode = DC_PRED;
7959 mbmi->ref_frame[0] = LAST_FRAME;
7960 mbmi->ref_frame[1] = NONE;
7961 mbmi->mv[0].as_int = 0;
7962 x->skip = 1;
7963
7964 if (cm->interp_filter != BILINEAR) {
Debargha Mukherjeebab29122016-02-26 00:18:03 -08007965 best_filter = EIGHTTAP_REGULAR;
Jingning Han3ee6db62015-08-05 19:00:31 -07007966 if (cm->interp_filter == SWITCHABLE &&
Debargha Mukherjee85514c42015-10-30 09:19:36 -07007967#if CONFIG_EXT_INTERP
7968 vp10_is_interp_needed(xd) &&
7969#endif // CONFIG_EXT_INTERP
Jingning Han3ee6db62015-08-05 19:00:31 -07007970 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
7971 int rs;
7972 int best_rs = INT_MAX;
7973 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
7974 mbmi->interp_filter = i;
7975 rs = vp10_get_switchable_rate(cpi, xd);
7976 if (rs < best_rs) {
7977 best_rs = rs;
7978 best_filter = mbmi->interp_filter;
7979 }
7980 }
7981 }
7982 }
7983 // Set the appropriate filter
7984 if (cm->interp_filter == SWITCHABLE) {
7985 mbmi->interp_filter = best_filter;
7986 rate2 += vp10_get_switchable_rate(cpi, xd);
7987 } else {
7988 mbmi->interp_filter = cm->interp_filter;
7989 }
7990
7991 if (cm->reference_mode == REFERENCE_MODE_SELECT)
7992 rate2 += vp10_cost_bit(comp_mode_p, comp_pred);
7993
7994 // Estimate the reference frame signaling cost and add it
7995 // to the rolling cost variable.
7996 rate2 += ref_costs_single[LAST_FRAME];
7997 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
7998
7999 rd_cost->rate = rate2;
8000 rd_cost->dist = distortion2;
8001 rd_cost->rdcost = this_rd;
8002
8003 if (this_rd >= best_rd_so_far) {
8004 rd_cost->rate = INT_MAX;
8005 rd_cost->rdcost = INT64_MAX;
8006 return;
8007 }
8008
8009 assert((cm->interp_filter == SWITCHABLE) ||
8010 (cm->interp_filter == mbmi->interp_filter));
8011
8012 vp10_update_rd_thresh_fact(tile_data->thresh_freq_fact,
8013 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
8014
8015 vp10_zero(best_pred_diff);
8016 vp10_zero(best_filter_diff);
8017
8018 if (!x->select_tx_size)
8019 swap_block_ptr(x, ctx, 1, 0, 0, MAX_MB_PLANE);
8020 store_coding_context(x, ctx, THR_ZEROMV,
8021 best_pred_diff, best_filter_diff, 0);
8022}
8023
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008024void vp10_rd_pick_inter_mode_sub8x8(struct VP10_COMP *cpi,
8025 TileDataEnc *tile_data,
8026 struct macroblock *x,
8027 int mi_row, int mi_col,
8028 struct RD_COST *rd_cost,
8029#if CONFIG_SUPERTX
8030 int *returnrate_nocoef,
8031#endif // CONFIG_SUPERTX
8032 BLOCK_SIZE bsize,
8033 PICK_MODE_CONTEXT *ctx,
8034 int64_t best_rd_so_far) {
Yaowu Xufc7cbd12015-08-13 09:36:53 -07008035 VP10_COMMON *const cm = &cpi->common;
Jingning Han3ee6db62015-08-05 19:00:31 -07008036 RD_OPT *const rd_opt = &cpi->rd;
8037 SPEED_FEATURES *const sf = &cpi->sf;
8038 MACROBLOCKD *const xd = &x->e_mbd;
8039 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
8040 const struct segmentation *const seg = &cm->seg;
8041 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
8042 unsigned char segment_id = mbmi->segment_id;
8043 int comp_pred, i;
8044 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
Zoe Liu3ec16012015-11-12 02:12:17 -08008045 struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE];
8046 static const int flag_list[REFS_PER_FRAME + 1] = {
8047 0,
8048 VP9_LAST_FLAG,
8049#if CONFIG_EXT_REFS
8050 VP9_LAST2_FLAG,
8051 VP9_LAST3_FLAG,
8052 VP9_LAST4_FLAG,
8053#endif // CONFIG_EXT_REFS
8054 VP9_GOLD_FLAG,
8055 VP9_ALT_FLAG
8056 };
Jingning Han3ee6db62015-08-05 19:00:31 -07008057 int64_t best_rd = best_rd_so_far;
8058 int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
8059 int64_t best_pred_diff[REFERENCE_MODES];
8060 int64_t best_pred_rd[REFERENCE_MODES];
8061 int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
8062 int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
8063 MB_MODE_INFO best_mbmode;
8064 int ref_index, best_ref_index = 0;
8065 unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
8066 vpx_prob comp_mode_p;
8067 INTERP_FILTER tmp_best_filter = SWITCHABLE;
8068 int rate_uv_intra, rate_uv_tokenonly;
8069 int64_t dist_uv;
8070 int skip_uv;
8071 PREDICTION_MODE mode_uv = DC_PRED;
8072 const int intra_cost_penalty = vp10_get_intra_cost_penalty(
8073 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
Yue Chen1ac85872016-01-07 15:13:52 -08008074#if CONFIG_EXT_INTER
8075 int_mv seg_mvs[4][2][MAX_REF_FRAMES];
8076#else
Jingning Han3ee6db62015-08-05 19:00:31 -07008077 int_mv seg_mvs[4][MAX_REF_FRAMES];
Yue Chen1ac85872016-01-07 15:13:52 -08008078#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07008079 b_mode_info best_bmodes[4];
8080 int best_skip2 = 0;
8081 int ref_frame_skip_mask[2] = { 0 };
8082 int64_t mask_filter = 0;
8083 int64_t filter_cache[SWITCHABLE_FILTER_CONTEXTS];
8084 int internal_active_edge =
8085 vp10_active_edge_sb(cpi, mi_row, mi_col) && vp10_internal_image_edge(cpi);
8086
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008087#if CONFIG_SUPERTX
8088 best_rd_so_far = INT64_MAX;
8089 best_rd = best_rd_so_far;
8090 best_yrd = best_rd_so_far;
8091#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07008092 memset(x->zcoeff_blk[TX_4X4], 0, 4);
8093 vp10_zero(best_mbmode);
8094
hui sube3559b2015-10-07 09:29:02 -07008095#if CONFIG_EXT_INTRA
8096 mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
8097 mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
8098#endif // CONFIG_EXT_INTRA
Yue Chend1cad9c2016-01-27 14:18:53 -08008099#if CONFIG_OBMC
8100 mbmi->obmc = 0;
8101#endif // CONFIG_OBMC
hui sube3559b2015-10-07 09:29:02 -07008102
Jingning Han3ee6db62015-08-05 19:00:31 -07008103 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
8104 filter_cache[i] = INT64_MAX;
8105
8106 for (i = 0; i < 4; i++) {
8107 int j;
Yue Chen1ac85872016-01-07 15:13:52 -08008108#if CONFIG_EXT_INTER
8109 int k;
8110
8111 for (k = 0; k < 2; k++)
8112 for (j = 0; j < MAX_REF_FRAMES; j++)
8113 seg_mvs[i][k][j].as_int = INVALID_MV;
8114#else
Jingning Han3ee6db62015-08-05 19:00:31 -07008115 for (j = 0; j < MAX_REF_FRAMES; j++)
8116 seg_mvs[i][j].as_int = INVALID_MV;
Yue Chen1ac85872016-01-07 15:13:52 -08008117#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07008118 }
8119
8120 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
8121 &comp_mode_p);
8122
8123 for (i = 0; i < REFERENCE_MODES; ++i)
8124 best_pred_rd[i] = INT64_MAX;
8125 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
8126 best_filter_rd[i] = INT64_MAX;
8127 rate_uv_intra = INT_MAX;
8128
8129 rd_cost->rate = INT_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008130#if CONFIG_SUPERTX
8131 *returnrate_nocoef = INT_MAX;
8132#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07008133
8134 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
Jingning Han387a10e2015-12-09 09:07:39 -08008135 x->mbmi_ext->mode_context[ref_frame] = 0;
Yue Chen968bbc72016-01-19 16:45:45 -08008136#if CONFIG_REF_MV && CONFIG_EXT_INTER
8137 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
8138#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07008139 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
8140 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
8141 frame_mv[NEARESTMV], frame_mv[NEARMV],
8142 yv12_mb);
8143 } else {
8144 ref_frame_skip_mask[0] |= (1 << ref_frame);
8145 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8146 }
8147 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Yue Chen1ac85872016-01-07 15:13:52 -08008148#if CONFIG_EXT_INTER
8149 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
8150#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07008151 frame_mv[ZEROMV][ref_frame].as_int = 0;
8152 }
8153
hui suc93e5cc2015-12-07 18:18:57 -08008154 mbmi->palette_mode_info.palette_size[0] = 0;
8155 mbmi->palette_mode_info.palette_size[1] = 0;
8156
Jingning Han3ee6db62015-08-05 19:00:31 -07008157 for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
8158 int mode_excluded = 0;
8159 int64_t this_rd = INT64_MAX;
8160 int disable_skip = 0;
8161 int compmode_cost = 0;
8162 int rate2 = 0, rate_y = 0, rate_uv = 0;
8163 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
8164 int skippable = 0;
8165 int i;
8166 int this_skip2 = 0;
8167 int64_t total_sse = INT_MAX;
8168 int early_term = 0;
8169
8170 ref_frame = vp10_ref_order[ref_index].ref_frame[0];
8171 second_ref_frame = vp10_ref_order[ref_index].ref_frame[1];
8172
8173 // Look at the reference frame of the best mode so far and set the
8174 // skip mask to look at a subset of the remaining modes.
8175 if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
8176 if (ref_index == 3) {
8177 switch (best_mbmode.ref_frame[0]) {
8178 case INTRA_FRAME:
8179 break;
8180 case LAST_FRAME:
Zoe Liu3ec16012015-11-12 02:12:17 -08008181 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
8182#if CONFIG_EXT_REFS
8183 (1 << LAST2_FRAME) |
8184 (1 << LAST3_FRAME) |
8185 (1 << LAST4_FRAME) |
8186#endif // CONFIG_EXT_REFS
8187 (1 << ALTREF_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07008188 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8189 break;
Zoe Liu3ec16012015-11-12 02:12:17 -08008190#if CONFIG_EXT_REFS
8191 case LAST2_FRAME:
8192 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
8193 (1 << LAST3_FRAME) |
8194 (1 << LAST4_FRAME) |
8195 (1 << GOLDEN_FRAME) |
8196 (1 << ALTREF_FRAME);
8197 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8198 break;
8199 case LAST3_FRAME:
8200 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
8201 (1 << LAST2_FRAME) |
8202 (1 << LAST4_FRAME) |
8203 (1 << GOLDEN_FRAME) |
8204 (1 << ALTREF_FRAME);
8205 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8206 break;
8207 case LAST4_FRAME:
8208 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
8209 (1 << LAST2_FRAME) |
8210 (1 << LAST3_FRAME) |
8211 (1 << GOLDEN_FRAME) |
8212 (1 << ALTREF_FRAME);
8213 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8214 break;
8215#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07008216 case GOLDEN_FRAME:
Zoe Liu3ec16012015-11-12 02:12:17 -08008217 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
8218#if CONFIG_EXT_REFS
8219 (1 << LAST2_FRAME) |
8220 (1 << LAST3_FRAME) |
8221 (1 << LAST4_FRAME) |
8222#endif // CONFIG_EXT_REFS
8223 (1 << ALTREF_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07008224 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8225 break;
8226 case ALTREF_FRAME:
Zoe Liu3ec16012015-11-12 02:12:17 -08008227 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
8228#if CONFIG_EXT_REFS
8229 (1 << LAST2_FRAME) |
8230 (1 << LAST3_FRAME) |
8231 (1 << LAST4_FRAME) |
8232#endif // CONFIG_EXT_REFS
8233 (1 << LAST_FRAME);
Jingning Han3ee6db62015-08-05 19:00:31 -07008234 break;
8235 case NONE:
8236 case MAX_REF_FRAMES:
8237 assert(0 && "Invalid Reference frame");
8238 break;
8239 }
8240 }
8241 }
8242
8243 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
James Zern5e16d392015-08-17 18:19:22 -07008244 (ref_frame_skip_mask[1] & (1 << VPXMAX(0, second_ref_frame))))
Jingning Han3ee6db62015-08-05 19:00:31 -07008245 continue;
8246
8247 // Test best rd so far against threshold for trying this mode.
8248 if (!internal_active_edge &&
8249 rd_less_than_thresh(best_rd,
8250 rd_opt->threshes[segment_id][bsize][ref_index],
8251 tile_data->thresh_freq_fact[bsize][ref_index]))
8252 continue;
8253
8254 comp_pred = second_ref_frame > INTRA_FRAME;
8255 if (comp_pred) {
8256 if (!cpi->allow_comp_inter_inter)
8257 continue;
8258 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
8259 continue;
8260 // Do not allow compound prediction if the segment level reference frame
8261 // feature is in use as in this case there can only be one reference.
8262 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
8263 continue;
8264
8265 if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
8266 best_mbmode.ref_frame[0] == INTRA_FRAME)
8267 continue;
8268 }
8269
8270 // TODO(jingning, jkoleszar): scaling reference frame not supported for
8271 // sub8x8 blocks.
8272 if (ref_frame > INTRA_FRAME &&
8273 vp10_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
8274 continue;
8275
8276 if (second_ref_frame > INTRA_FRAME &&
8277 vp10_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
8278 continue;
8279
8280 if (comp_pred)
8281 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
8282 else if (ref_frame != INTRA_FRAME)
8283 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
8284
8285 // If the segment reference frame feature is enabled....
8286 // then do nothing if the current ref frame is not allowed..
8287 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
8288 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
8289 continue;
8290 // Disable this drop out case if the ref frame
8291 // segment level feature is enabled for this segment. This is to
8292 // prevent the possibility that we end up unable to pick any mode.
8293 } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
8294 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
8295 // unless ARNR filtering is enabled in which case we want
8296 // an unfiltered alternative. We allow near/nearest as well
8297 // because they may result in zero-zero MVs but be cheaper.
8298 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
8299 continue;
8300 }
8301
8302 mbmi->tx_size = TX_4X4;
8303 mbmi->uv_mode = DC_PRED;
8304 mbmi->ref_frame[0] = ref_frame;
8305 mbmi->ref_frame[1] = second_ref_frame;
8306 // Evaluate all sub-pel filters irrespective of whether we can use
8307 // them for this frame.
Debargha Mukherjeebab29122016-02-26 00:18:03 -08008308 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
Jingning Han3ee6db62015-08-05 19:00:31 -07008309 : cm->interp_filter;
8310 x->skip = 0;
8311 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
8312
8313 // Select prediction reference frames.
8314 for (i = 0; i < MAX_MB_PLANE; i++) {
8315 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
8316 if (comp_pred)
8317 xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
8318 }
8319
Jingning Han704985e2015-10-08 12:05:03 -07008320#if CONFIG_VAR_TX
Jingning Han0f34e352015-11-15 20:52:51 -08008321 mbmi->inter_tx_size[0] = mbmi->tx_size;
Jingning Han704985e2015-10-08 12:05:03 -07008322#endif
8323
Jingning Han3ee6db62015-08-05 19:00:31 -07008324 if (ref_frame == INTRA_FRAME) {
8325 int rate;
8326 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y,
8327 &distortion_y, best_rd) >= best_rd)
8328 continue;
8329 rate2 += rate;
8330 rate2 += intra_cost_penalty;
8331 distortion2 += distortion_y;
8332
8333 if (rate_uv_intra == INT_MAX) {
8334 choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4,
8335 &rate_uv_intra,
8336 &rate_uv_tokenonly,
8337 &dist_uv, &skip_uv,
8338 &mode_uv);
8339 }
8340 rate2 += rate_uv_intra;
8341 rate_uv = rate_uv_tokenonly;
8342 distortion2 += dist_uv;
8343 distortion_uv = dist_uv;
8344 mbmi->uv_mode = mode_uv;
8345 } else {
8346 int rate;
8347 int64_t distortion;
8348 int64_t this_rd_thresh;
8349 int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
8350 int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
8351 int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
8352 int tmp_best_skippable = 0;
8353 int switchable_filter_index;
8354 int_mv *second_ref = comp_pred ?
8355 &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL;
8356 b_mode_info tmp_best_bmodes[16];
8357 MB_MODE_INFO tmp_best_mbmode;
8358 BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
8359 int pred_exists = 0;
8360 int uv_skippable;
Yue Chen1ac85872016-01-07 15:13:52 -08008361#if CONFIG_EXT_INTER
8362 int_mv compound_seg_newmvs[4][2];
8363 int i;
8364
8365 for (i = 0; i < 4; i++) {
8366 compound_seg_newmvs[i][0].as_int = INVALID_MV;
8367 compound_seg_newmvs[i][1].as_int = INVALID_MV;
8368 }
8369#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07008370
8371 this_rd_thresh = (ref_frame == LAST_FRAME) ?
8372 rd_opt->threshes[segment_id][bsize][THR_LAST] :
8373 rd_opt->threshes[segment_id][bsize][THR_ALTR];
Zoe Liu3ec16012015-11-12 02:12:17 -08008374#if CONFIG_EXT_REFS
8375 this_rd_thresh = (ref_frame == LAST2_FRAME) ?
8376 rd_opt->threshes[segment_id][bsize][THR_LAST2] : this_rd_thresh;
8377 this_rd_thresh = (ref_frame == LAST3_FRAME) ?
8378 rd_opt->threshes[segment_id][bsize][THR_LAST3] : this_rd_thresh;
8379 this_rd_thresh = (ref_frame == LAST4_FRAME) ?
8380 rd_opt->threshes[segment_id][bsize][THR_LAST4] : this_rd_thresh;
8381#endif // CONFIG_EXT_REFS
Jingning Han3ee6db62015-08-05 19:00:31 -07008382 this_rd_thresh = (ref_frame == GOLDEN_FRAME) ?
Zoe Liu3ec16012015-11-12 02:12:17 -08008383 rd_opt->threshes[segment_id][bsize][THR_GOLD] : this_rd_thresh;
Jingning Han3ee6db62015-08-05 19:00:31 -07008384 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
8385 filter_cache[i] = INT64_MAX;
8386
Debargha Mukherjeed46c1f22016-02-08 15:59:17 -08008387 // TODO(any): Add search of the tx_type to improve rd performance at the
8388 // expense of speed.
8389 mbmi->tx_type = DCT_DCT;
8390
Jingning Han3ee6db62015-08-05 19:00:31 -07008391 if (cm->interp_filter != BILINEAR) {
Debargha Mukherjeebab29122016-02-26 00:18:03 -08008392 tmp_best_filter = EIGHTTAP_REGULAR;
Jingning Han3ee6db62015-08-05 19:00:31 -07008393 if (x->source_variance < sf->disable_filter_search_var_thresh) {
Debargha Mukherjeebab29122016-02-26 00:18:03 -08008394 tmp_best_filter = EIGHTTAP_REGULAR;
Jingning Han3ee6db62015-08-05 19:00:31 -07008395 } else if (sf->adaptive_pred_interp_filter == 1 &&
8396 ctx->pred_interp_filter < SWITCHABLE) {
8397 tmp_best_filter = ctx->pred_interp_filter;
8398 } else if (sf->adaptive_pred_interp_filter == 2) {
8399 tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE ?
8400 ctx->pred_interp_filter : 0;
8401 } else {
8402 for (switchable_filter_index = 0;
8403 switchable_filter_index < SWITCHABLE_FILTERS;
8404 ++switchable_filter_index) {
8405 int newbest, rs;
8406 int64_t rs_rd;
8407 MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
8408 mbmi->interp_filter = switchable_filter_index;
8409 tmp_rd = rd_pick_best_sub8x8_mode(cpi, x,
8410 &mbmi_ext->ref_mvs[ref_frame][0],
8411 second_ref, best_yrd, &rate,
8412 &rate_y, &distortion,
8413 &skippable, &total_sse,
8414 (int) this_rd_thresh, seg_mvs,
Yue Chen1ac85872016-01-07 15:13:52 -08008415#if CONFIG_EXT_INTER
8416 compound_seg_newmvs,
8417#endif // CONFIG_EXT_INTER
Jingning Han3ee6db62015-08-05 19:00:31 -07008418 bsi, switchable_filter_index,
8419 mi_row, mi_col);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07008420#if CONFIG_EXT_INTERP
8421 if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Debargha Mukherjeebab29122016-02-26 00:18:03 -08008422 mbmi->interp_filter != EIGHTTAP_REGULAR) // invalid config
Debargha Mukherjee85514c42015-10-30 09:19:36 -07008423 continue;
8424#endif // CONFIG_EXT_INTERP
Jingning Han3ee6db62015-08-05 19:00:31 -07008425 if (tmp_rd == INT64_MAX)
8426 continue;
8427 rs = vp10_get_switchable_rate(cpi, xd);
8428 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
8429 filter_cache[switchable_filter_index] = tmp_rd;
8430 filter_cache[SWITCHABLE_FILTERS] =
James Zern5e16d392015-08-17 18:19:22 -07008431 VPXMIN(filter_cache[SWITCHABLE_FILTERS], tmp_rd + rs_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07008432 if (cm->interp_filter == SWITCHABLE)
8433 tmp_rd += rs_rd;
8434
James Zern5e16d392015-08-17 18:19:22 -07008435 mask_filter = VPXMAX(mask_filter, tmp_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07008436
8437 newbest = (tmp_rd < tmp_best_rd);
8438 if (newbest) {
8439 tmp_best_filter = mbmi->interp_filter;
8440 tmp_best_rd = tmp_rd;
8441 }
8442 if ((newbest && cm->interp_filter == SWITCHABLE) ||
8443 (mbmi->interp_filter == cm->interp_filter &&
8444 cm->interp_filter != SWITCHABLE)) {
8445 tmp_best_rdu = tmp_rd;
8446 tmp_best_rate = rate;
8447 tmp_best_ratey = rate_y;
8448 tmp_best_distortion = distortion;
8449 tmp_best_sse = total_sse;
8450 tmp_best_skippable = skippable;
8451 tmp_best_mbmode = *mbmi;
8452 for (i = 0; i < 4; i++) {
8453 tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
8454 x->zcoeff_blk[TX_4X4][i] = !x->plane[0].eobs[i];
8455 }
8456 pred_exists = 1;
8457 if (switchable_filter_index == 0 &&
8458 sf->use_rd_breakout &&
8459 best_rd < INT64_MAX) {
8460 if (tmp_best_rdu / 2 > best_rd) {
8461 // skip searching the other filters if the first is
8462 // already substantially larger than the best so far
8463 tmp_best_filter = mbmi->interp_filter;
8464 tmp_best_rdu = INT64_MAX;
8465 break;
8466 }
8467 }
8468 }
8469 } // switchable_filter_index loop
8470 }
8471 }
8472
8473 if (tmp_best_rdu == INT64_MAX && pred_exists)
8474 continue;
8475
8476 mbmi->interp_filter = (cm->interp_filter == SWITCHABLE ?
8477 tmp_best_filter : cm->interp_filter);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07008478
Jingning Han3ee6db62015-08-05 19:00:31 -07008479 if (!pred_exists) {
8480 // Handles the special case when a filter that is not in the
Debargha Mukherjee85514c42015-10-30 09:19:36 -07008481 // switchable list (bilinear) is indicated at the frame level
Jingning Han3ee6db62015-08-05 19:00:31 -07008482 tmp_rd = rd_pick_best_sub8x8_mode(cpi, x,
8483 &x->mbmi_ext->ref_mvs[ref_frame][0],
8484 second_ref, best_yrd, &rate, &rate_y,
8485 &distortion, &skippable, &total_sse,
Yue Chen1ac85872016-01-07 15:13:52 -08008486 (int) this_rd_thresh, seg_mvs,
8487#if CONFIG_EXT_INTER
8488 compound_seg_newmvs,
8489#endif // CONFIG_EXT_INTER
8490 bsi, 0,
Jingning Han3ee6db62015-08-05 19:00:31 -07008491 mi_row, mi_col);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07008492#if CONFIG_EXT_INTERP
8493 if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Debargha Mukherjeebab29122016-02-26 00:18:03 -08008494 mbmi->interp_filter != EIGHTTAP_REGULAR) {
8495 mbmi->interp_filter = EIGHTTAP_REGULAR;
Yue Chen1ac85872016-01-07 15:13:52 -08008496 tmp_rd = rd_pick_best_sub8x8_mode(cpi, x,
8497 &x->mbmi_ext->ref_mvs[ref_frame][0],
8498 second_ref, best_yrd, &rate, &rate_y,
8499 &distortion, &skippable, &total_sse,
8500 (int) this_rd_thresh, seg_mvs,
8501#if CONFIG_EXT_INTER
8502 compound_seg_newmvs,
8503#endif // CONFIG_EXT_INTER
8504 bsi, 0,
8505 mi_row, mi_col);
Debargha Mukherjee85514c42015-10-30 09:19:36 -07008506 }
8507#endif // CONFIG_EXT_INTERP
Jingning Han3ee6db62015-08-05 19:00:31 -07008508 if (tmp_rd == INT64_MAX)
8509 continue;
8510 } else {
8511 total_sse = tmp_best_sse;
8512 rate = tmp_best_rate;
8513 rate_y = tmp_best_ratey;
8514 distortion = tmp_best_distortion;
8515 skippable = tmp_best_skippable;
8516 *mbmi = tmp_best_mbmode;
8517 for (i = 0; i < 4; i++)
8518 xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
8519 }
Debargha Mukherjeee2c1ea92016-02-08 09:34:43 -08008520 // Add in the cost of the transform type
8521 if (!xd->lossless[mbmi->segment_id]) {
8522 int rate_tx_type = 0;
8523#if CONFIG_EXT_TX
8524 if (get_ext_tx_types(mbmi->tx_size, bsize, 1) > 1) {
8525 const int eset = get_ext_tx_set(mbmi->tx_size, bsize, 1);
8526 rate_tx_type =
8527 cpi->inter_tx_type_costs[eset][mbmi->tx_size][mbmi->tx_type];
8528 }
8529#else
8530 if (mbmi->tx_size < TX_32X32) {
8531 rate_tx_type = cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
8532 }
8533#endif
8534 rate += rate_tx_type;
8535 rate_y += rate_tx_type;
8536 }
Jingning Han3ee6db62015-08-05 19:00:31 -07008537
8538 rate2 += rate;
8539 distortion2 += distortion;
8540
8541 if (cm->interp_filter == SWITCHABLE)
8542 rate2 += vp10_get_switchable_rate(cpi, xd);
8543
8544 if (!mode_excluded)
8545 mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
8546 : cm->reference_mode == COMPOUND_REFERENCE;
8547
8548 compmode_cost = vp10_cost_bit(comp_mode_p, comp_pred);
8549
8550 tmp_best_rdu = best_rd -
James Zern5e16d392015-08-17 18:19:22 -07008551 VPXMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
8552 RDCOST(x->rdmult, x->rddiv, 0, total_sse));
Jingning Han3ee6db62015-08-05 19:00:31 -07008553
8554 if (tmp_best_rdu > 0) {
8555 // If even the 'Y' rd value of split is higher than best so far
8556 // then dont bother looking at UV
8557 vp10_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col,
8558 BLOCK_8X8);
8559 memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
Jingning Hana8dad552015-10-08 16:46:10 -07008560#if CONFIG_VAR_TX
8561 if (!inter_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
8562 &uv_sse, BLOCK_8X8, tmp_best_rdu))
8563 continue;
8564#else
Jingning Han3ee6db62015-08-05 19:00:31 -07008565 if (!super_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
8566 &uv_sse, BLOCK_8X8, tmp_best_rdu))
8567 continue;
Jingning Hana8dad552015-10-08 16:46:10 -07008568#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07008569 rate2 += rate_uv;
8570 distortion2 += distortion_uv;
8571 skippable = skippable && uv_skippable;
8572 total_sse += uv_sse;
8573 }
8574 }
8575
8576 if (cm->reference_mode == REFERENCE_MODE_SELECT)
8577 rate2 += compmode_cost;
8578
8579 // Estimate the reference frame signaling cost and add it
8580 // to the rolling cost variable.
8581 if (second_ref_frame > INTRA_FRAME) {
8582 rate2 += ref_costs_comp[ref_frame];
8583 } else {
8584 rate2 += ref_costs_single[ref_frame];
8585 }
8586
8587 if (!disable_skip) {
8588 // Skip is never coded at the segment level for sub8x8 blocks and instead
8589 // always coded in the bitstream at the mode info level.
8590
Ronald S. Bultje60c58b52015-10-12 17:54:25 -04008591 if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Jingning Han3ee6db62015-08-05 19:00:31 -07008592 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
8593 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
8594 // Add in the cost of the no skip flag.
8595 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
8596 } else {
8597 // FIXME(rbultje) make this work for splitmv also
8598 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
8599 distortion2 = total_sse;
8600 assert(total_sse >= 0);
8601 rate2 -= (rate_y + rate_uv);
8602 rate_y = 0;
8603 rate_uv = 0;
8604 this_skip2 = 1;
8605 }
8606 } else {
8607 // Add in the cost of the no skip flag.
8608 rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 0);
8609 }
8610
8611 // Calculate the final RD estimate for this mode.
8612 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
8613 }
8614
8615 if (!disable_skip && ref_frame == INTRA_FRAME) {
8616 for (i = 0; i < REFERENCE_MODES; ++i)
James Zern5e16d392015-08-17 18:19:22 -07008617 best_pred_rd[i] = VPXMIN(best_pred_rd[i], this_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07008618 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
James Zern5e16d392015-08-17 18:19:22 -07008619 best_filter_rd[i] = VPXMIN(best_filter_rd[i], this_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07008620 }
8621
8622 // Did this mode help.. i.e. is it the new best mode
8623 if (this_rd < best_rd || x->skip) {
8624 if (!mode_excluded) {
8625 int max_plane = MAX_MB_PLANE;
8626 // Note index of best mode so far
8627 best_ref_index = ref_index;
8628
8629 if (ref_frame == INTRA_FRAME) {
8630 /* required for left and above block mv */
8631 mbmi->mv[0].as_int = 0;
8632 max_plane = 1;
8633 }
8634
8635 rd_cost->rate = rate2;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008636#if CONFIG_SUPERTX
8637 *returnrate_nocoef = rate2 - rate_y - rate_uv;
8638 if (!disable_skip)
8639 *returnrate_nocoef -= vp10_cost_bit(vp10_get_skip_prob(cm, xd),
8640 this_skip2);
8641 *returnrate_nocoef -= vp10_cost_bit(vp10_get_intra_inter_prob(cm, xd),
8642 mbmi->ref_frame[0] != INTRA_FRAME);
8643 assert(*returnrate_nocoef > 0);
8644#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07008645 rd_cost->dist = distortion2;
8646 rd_cost->rdcost = this_rd;
8647 best_rd = this_rd;
8648 best_yrd = best_rd -
8649 RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
8650 best_mbmode = *mbmi;
8651 best_skip2 = this_skip2;
8652 if (!x->select_tx_size)
8653 swap_block_ptr(x, ctx, 1, 0, 0, max_plane);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07008654
8655#if CONFIG_VAR_TX
8656 for (i = 0; i < MAX_MB_PLANE; ++i)
8657 memset(ctx->blk_skip[i], 0, sizeof(uint8_t) * ctx->num_4x4_blk);
8658#else
Jingning Han3ee6db62015-08-05 19:00:31 -07008659 memcpy(ctx->zcoeff_blk, x->zcoeff_blk[TX_4X4],
hui su088b05f2015-08-12 10:41:51 -07008660 sizeof(ctx->zcoeff_blk[0]) * ctx->num_4x4_blk);
Jingning Hanbfeac5e2015-10-15 23:11:30 -07008661#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07008662
8663 for (i = 0; i < 4; i++)
8664 best_bmodes[i] = xd->mi[0]->bmi[i];
8665
8666 // TODO(debargha): enhance this test with a better distortion prediction
8667 // based on qp, activity mask and history
8668 if ((sf->mode_search_skip_flags & FLAG_EARLY_TERMINATE) &&
8669 (ref_index > MIN_EARLY_TERM_INDEX)) {
8670 int qstep = xd->plane[0].dequant[1];
8671 // TODO(debargha): Enhance this by specializing for each mode_index
8672 int scale = 4;
8673#if CONFIG_VP9_HIGHBITDEPTH
8674 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
8675 qstep >>= (xd->bd - 8);
8676 }
8677#endif // CONFIG_VP9_HIGHBITDEPTH
8678 if (x->source_variance < UINT_MAX) {
8679 const int var_adjust = (x->source_variance < 16);
8680 scale -= var_adjust;
8681 }
8682 if (ref_frame > INTRA_FRAME &&
8683 distortion2 * scale < qstep * qstep) {
8684 early_term = 1;
8685 }
8686 }
8687 }
8688 }
8689
8690 /* keep record of best compound/single-only prediction */
8691 if (!disable_skip && ref_frame != INTRA_FRAME) {
8692 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
8693
8694 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
8695 single_rate = rate2 - compmode_cost;
8696 hybrid_rate = rate2;
8697 } else {
8698 single_rate = rate2;
8699 hybrid_rate = rate2 + compmode_cost;
8700 }
8701
8702 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
8703 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
8704
8705 if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE])
8706 best_pred_rd[SINGLE_REFERENCE] = single_rd;
8707 else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE])
8708 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
8709
8710 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
8711 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
8712 }
8713
8714 /* keep record of best filter type */
8715 if (!mode_excluded && !disable_skip && ref_frame != INTRA_FRAME &&
8716 cm->interp_filter != BILINEAR) {
8717 int64_t ref = filter_cache[cm->interp_filter == SWITCHABLE ?
8718 SWITCHABLE_FILTERS : cm->interp_filter];
8719 int64_t adj_rd;
8720 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
8721 if (ref == INT64_MAX)
8722 adj_rd = 0;
8723 else if (filter_cache[i] == INT64_MAX)
8724 // when early termination is triggered, the encoder does not have
8725 // access to the rate-distortion cost. it only knows that the cost
8726 // should be above the maximum valid value. hence it takes the known
8727 // maximum plus an arbitrary constant as the rate-distortion cost.
8728 adj_rd = mask_filter - ref + 10;
8729 else
8730 adj_rd = filter_cache[i] - ref;
8731
8732 adj_rd += this_rd;
James Zern5e16d392015-08-17 18:19:22 -07008733 best_filter_rd[i] = VPXMIN(best_filter_rd[i], adj_rd);
Jingning Han3ee6db62015-08-05 19:00:31 -07008734 }
8735 }
8736
8737 if (early_term)
8738 break;
8739
8740 if (x->skip && !comp_pred)
8741 break;
8742 }
8743
8744 if (best_rd >= best_rd_so_far) {
8745 rd_cost->rate = INT_MAX;
8746 rd_cost->rdcost = INT64_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008747#if CONFIG_SUPERTX
8748 *returnrate_nocoef = INT_MAX;
8749#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07008750 return;
8751 }
8752
8753 // If we used an estimate for the uv intra rd in the loop above...
8754 if (sf->use_uv_intra_rd_estimate) {
8755 // Do Intra UV best rd mode selection if best mode choice above was intra.
8756 if (best_mbmode.ref_frame[0] == INTRA_FRAME) {
8757 *mbmi = best_mbmode;
8758 rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra,
8759 &rate_uv_tokenonly,
8760 &dist_uv,
8761 &skip_uv,
8762 BLOCK_8X8, TX_4X4);
8763 }
8764 }
8765
8766 if (best_rd == INT64_MAX) {
8767 rd_cost->rate = INT_MAX;
8768 rd_cost->dist = INT64_MAX;
8769 rd_cost->rdcost = INT64_MAX;
Debargha Mukherjee3787b172015-11-19 16:51:16 -08008770#if CONFIG_SUPERTX
8771 *returnrate_nocoef = INT_MAX;
8772#endif // CONFIG_SUPERTX
Jingning Han3ee6db62015-08-05 19:00:31 -07008773 return;
8774 }
8775
8776 assert((cm->interp_filter == SWITCHABLE) ||
8777 (cm->interp_filter == best_mbmode.interp_filter) ||
8778 !is_inter_block(&best_mbmode));
8779
8780 vp10_update_rd_thresh_fact(tile_data->thresh_freq_fact,
8781 sf->adaptive_rd_thresh, bsize, best_ref_index);
8782
8783 // macroblock modes
8784 *mbmi = best_mbmode;
8785 x->skip |= best_skip2;
8786 if (!is_inter_block(&best_mbmode)) {
8787 for (i = 0; i < 4; i++)
8788 xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
8789 } else {
8790 for (i = 0; i < 4; ++i)
8791 memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
8792
8793 mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
8794 mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
Jingning Handf59bb82016-02-18 11:57:44 -08008795#if CONFIG_REF_MV
8796 mbmi->pred_mv[0].as_int = xd->mi[0]->bmi[3].pred_mv[0].as_int;
8797 mbmi->pred_mv[1].as_int = xd->mi[0]->bmi[3].pred_mv[1].as_int;
8798#endif
Jingning Han3ee6db62015-08-05 19:00:31 -07008799 }
8800
8801 for (i = 0; i < REFERENCE_MODES; ++i) {
8802 if (best_pred_rd[i] == INT64_MAX)
8803 best_pred_diff[i] = INT_MIN;
8804 else
8805 best_pred_diff[i] = best_rd - best_pred_rd[i];
8806 }
8807
8808 if (!x->skip) {
8809 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
8810 if (best_filter_rd[i] == INT64_MAX)
8811 best_filter_diff[i] = 0;
8812 else
8813 best_filter_diff[i] = best_rd - best_filter_rd[i];
8814 }
8815 if (cm->interp_filter == SWITCHABLE)
8816 assert(best_filter_diff[SWITCHABLE_FILTERS] == 0);
8817 } else {
8818 vp10_zero(best_filter_diff);
8819 }
8820
8821 store_coding_context(x, ctx, best_ref_index,
8822 best_pred_diff, best_filter_diff, 0);
8823}
Yue Chend1cad9c2016-01-27 14:18:53 -08008824
8825#if CONFIG_OBMC
8826void vp10_build_prediction_by_above_preds(VP10_COMP *cpi,
8827 MACROBLOCKD *xd,
8828 int mi_row, int mi_col,
8829 uint8_t *tmp_buf[MAX_MB_PLANE],
8830 int tmp_stride[MAX_MB_PLANE]) {
8831 VP10_COMMON *const cm = &cpi->common;
8832 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
8833 int i, j, mi_step, ref;
8834
8835 if (mi_row == 0)
8836 return;
8837
8838 for (i = 0; i < VPXMIN(xd->n8_w, cm->mi_cols - mi_col); i += mi_step) {
8839 int mi_row_offset = -1;
8840 int mi_col_offset = i;
8841 int mi_x, mi_y, bw, bh;
8842 MODE_INFO *above_mi = xd->mi[mi_col_offset +
8843 mi_row_offset * xd->mi_stride];
8844 MB_MODE_INFO *above_mbmi = &above_mi->mbmi;
8845
8846 mi_step = VPXMIN(xd->n8_w,
8847 num_8x8_blocks_wide_lookup[above_mbmi->sb_type]);
8848
8849 if (!is_inter_block(above_mbmi))
8850 continue;
8851
8852 for (j = 0; j < MAX_MB_PLANE; ++j) {
8853 struct macroblockd_plane *const pd = &xd->plane[j];
8854 setup_pred_plane(&pd->dst,
8855 tmp_buf[j], tmp_stride[j],
8856 0, i, NULL,
8857 pd->subsampling_x, pd->subsampling_y);
8858 }
8859 set_ref_ptrs(cm, xd, above_mbmi->ref_frame[0], above_mbmi->ref_frame[1]);
8860 for (ref = 0; ref < 1 + has_second_ref(above_mbmi); ++ref) {
8861 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi,
8862 above_mbmi->ref_frame[ref]);
8863 assert(cfg != NULL);
8864 vp10_setup_pre_planes(xd, ref, cfg, mi_row, mi_col + i,
8865 &xd->block_refs[ref]->sf);
8866 }
8867
8868 xd->mb_to_left_edge = -(((mi_col + i) * MI_SIZE) * 8);
8869 mi_x = (mi_col + i) << MI_SIZE_LOG2;
8870 mi_y = mi_row << MI_SIZE_LOG2;
8871
8872 for (j = 0; j < MAX_MB_PLANE; ++j) {
8873 const struct macroblockd_plane *pd = &xd->plane[j];
8874 bw = (mi_step * 8) >> pd->subsampling_x;
8875 bh = VPXMAX((num_4x4_blocks_high_lookup[bsize] * 2) >> pd->subsampling_y,
8876 4);
8877
8878 if (above_mbmi->sb_type < BLOCK_8X8) {
8879 const PARTITION_TYPE bp = BLOCK_8X8 - above_mbmi->sb_type;
8880 const int have_vsplit = bp != PARTITION_HORZ;
8881 const int have_hsplit = bp != PARTITION_VERT;
8882 const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
8883 const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);
8884 const int pw = 8 >> (have_vsplit | pd->subsampling_x);
8885 int x, y;
8886
8887 for (y = 0; y < num_4x4_h; ++y)
8888 for (x = 0; x < num_4x4_w; ++x) {
8889 if ((bp == PARTITION_HORZ || bp == PARTITION_SPLIT)
8890 && y == 0 && !pd->subsampling_y)
8891 continue;
8892
8893 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
8894 y * 2 + x, bw, bh,
8895 4 * x, 0, pw, bh, mi_x, mi_y);
8896 }
8897 } else {
8898 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0,
8899 bw, bh, 0, 0, bw, bh, mi_x, mi_y);
8900 }
8901 }
8902 }
8903 xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8);
8904}
8905
8906void vp10_build_prediction_by_left_preds(VP10_COMP *cpi,
8907 MACROBLOCKD *xd,
8908 int mi_row, int mi_col,
8909 uint8_t *tmp_buf[MAX_MB_PLANE],
8910 int tmp_stride[MAX_MB_PLANE]) {
8911 VP10_COMMON *const cm = &cpi->common;
8912 const TileInfo *const tile = &xd->tile;
8913 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
8914 int i, j, mi_step, ref;
8915
8916 if (mi_col == 0 || (mi_col - 1 < tile->mi_col_start) ||
8917 (mi_col - 1) >= tile->mi_col_end)
8918 return;
8919
8920 for (i = 0; i < VPXMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) {
8921 int mi_row_offset = i;
8922 int mi_col_offset = -1;
8923 int mi_x, mi_y, bw, bh;
8924 MODE_INFO *left_mi = xd->mi[mi_col_offset +
8925 mi_row_offset * xd->mi_stride];
8926 MB_MODE_INFO *left_mbmi = &left_mi->mbmi;
8927
8928 mi_step = VPXMIN(xd->n8_h,
8929 num_8x8_blocks_high_lookup[left_mbmi->sb_type]);
8930
8931 if (!is_inter_block(left_mbmi))
8932 continue;
8933
8934 for (j = 0; j < MAX_MB_PLANE; ++j) {
8935 struct macroblockd_plane *const pd = &xd->plane[j];
8936 setup_pred_plane(&pd->dst,
8937 tmp_buf[j], tmp_stride[j],
8938 i, 0, NULL,
8939 pd->subsampling_x, pd->subsampling_y);
8940 }
8941 set_ref_ptrs(cm, xd, left_mbmi->ref_frame[0], left_mbmi->ref_frame[1]);
8942 for (ref = 0; ref < 1 + has_second_ref(left_mbmi); ++ref) {
8943 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi,
8944 left_mbmi->ref_frame[ref]);
8945 assert(cfg != NULL);
8946 vp10_setup_pre_planes(xd, ref, cfg, mi_row + i, mi_col,
8947 &xd->block_refs[ref]->sf);
8948 }
8949
8950 xd->mb_to_top_edge = -(((mi_row + i) * MI_SIZE) * 8);
8951 mi_x = mi_col << MI_SIZE_LOG2;
8952 mi_y = (mi_row + i) << MI_SIZE_LOG2;
8953
8954 for (j = 0; j < MAX_MB_PLANE; ++j) {
8955 const struct macroblockd_plane *pd = &xd->plane[j];
8956 bw = VPXMAX((num_4x4_blocks_wide_lookup[bsize] * 2) >> pd->subsampling_x,
8957 4);
8958 bh = (mi_step << MI_SIZE_LOG2) >> pd->subsampling_y;
8959
8960 if (left_mbmi->sb_type < BLOCK_8X8) {
8961 const PARTITION_TYPE bp = BLOCK_8X8 - left_mbmi->sb_type;
8962 const int have_vsplit = bp != PARTITION_HORZ;
8963 const int have_hsplit = bp != PARTITION_VERT;
8964 const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
8965 const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);
8966 const int ph = 8 >> (have_hsplit | pd->subsampling_y);
8967 int x, y;
8968
8969 for (y = 0; y < num_4x4_h; ++y)
8970 for (x = 0; x < num_4x4_w; ++x) {
8971 if ((bp == PARTITION_VERT || bp == PARTITION_SPLIT)
8972 && x == 0 && !pd->subsampling_x)
8973 continue;
8974
8975 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
8976 y * 2 + x, bw, bh,
8977 0, 4 * y, bw, ph, mi_x, mi_y);
8978 }
8979 } else {
8980 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0,
8981 bw, bh, 0, 0, bw, bh, mi_x, mi_y);
8982 }
8983 }
8984 }
8985 xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8);
8986}
8987#endif // CONFIG_OBMC