blob: 6bb84c05eb22d70b1bbdf88ed4547d69d5a3bd1c [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
12#include <assert.h>
13#include <math.h>
14
Yaowu Xuf883b422016-08-30 14:01:10 -070015#include "./aom_dsp_rtcd.h"
Jingning Han1aab8182016-06-03 11:09:06 -070016#include "./av1_rtcd.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070017
Yaowu Xuf883b422016-08-30 14:01:10 -070018#include "aom_dsp/aom_dsp_common.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070019#include "aom_dsp/blend.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070020#include "aom_mem/aom_mem.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070021#include "aom_ports/mem.h"
22#include "aom_ports/system_state.h"
23
24#include "av1/common/common.h"
25#include "av1/common/common_data.h"
26#include "av1/common/entropy.h"
27#include "av1/common/entropymode.h"
28#include "av1/common/idct.h"
29#include "av1/common/mvref_common.h"
30#include "av1/common/pred_common.h"
31#include "av1/common/quant_common.h"
32#include "av1/common/reconinter.h"
33#include "av1/common/reconintra.h"
34#include "av1/common/scan.h"
35#include "av1/common/seg_common.h"
Yue Chen69f18e12016-09-08 14:48:15 -070036#if CONFIG_WARPED_MOTION
37#include "av1/common/warped_motion.h"
38#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070039
Jingning Han1aab8182016-06-03 11:09:06 -070040#include "av1/encoder/aq_variance.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070041#include "av1/encoder/cost.h"
42#include "av1/encoder/encodemb.h"
43#include "av1/encoder/encodemv.h"
44#include "av1/encoder/encoder.h"
45#include "av1/encoder/hybrid_fwd_txfm.h"
46#include "av1/encoder/mcomp.h"
Urvang Joshib100db72016-10-12 16:28:56 -070047#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070048#include "av1/encoder/palette.h"
Urvang Joshib100db72016-10-12 16:28:56 -070049#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070050#include "av1/encoder/quantize.h"
51#include "av1/encoder/ratectrl.h"
52#include "av1/encoder/rd.h"
53#include "av1/encoder/rdopt.h"
Debargha Mukherjeeceebb702016-10-11 05:26:50 -070054#include "av1/encoder/tokenize.h"
Yushin Cho77bba8d2016-11-04 16:36:56 -070055#if CONFIG_PVQ
56#include "av1/encoder/pvq_encoder.h"
57#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070058#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080059#define DUAL_FILTER_SET_SIZE (SWITCHABLE_FILTERS * SWITCHABLE_FILTERS)
Yaowu Xuc27fc142016-08-22 16:08:15 -070060#if CONFIG_EXT_INTERP
Angie Chiang5678ad92016-11-21 09:38:40 -080061static const int filter_sets[DUAL_FILTER_SET_SIZE][2] = {
Angie Chiangd91ab372016-11-21 18:16:49 -080062 { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 1, 0 }, { 1, 1 },
63 { 1, 2 }, { 1, 3 }, { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 },
64 { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 },
Yaowu Xuc27fc142016-08-22 16:08:15 -070065};
Angie Chiang5678ad92016-11-21 09:38:40 -080066#else // CONFIG_EXT_INTERP
67static const int filter_sets[DUAL_FILTER_SET_SIZE][2] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -070068 { 0, 0 }, { 0, 1 }, { 0, 2 }, { 1, 0 }, { 1, 1 },
69 { 1, 2 }, { 2, 0 }, { 2, 1 }, { 2, 2 },
70};
Angie Chiang5678ad92016-11-21 09:38:40 -080071#endif // CONFIG_EXT_INTERP
72#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070073
74#if CONFIG_EXT_REFS
75
76#define LAST_FRAME_MODE_MASK \
77 ((1 << INTRA_FRAME) | (1 << LAST2_FRAME) | (1 << LAST3_FRAME) | \
78 (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
79#define LAST2_FRAME_MODE_MASK \
80 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST3_FRAME) | \
81 (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
82#define LAST3_FRAME_MODE_MASK \
83 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
84 (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
85#define GOLDEN_FRAME_MODE_MASK \
86 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
87 (1 << LAST3_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
88#define BWDREF_FRAME_MODE_MASK \
89 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
90 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME))
91#define ALTREF_FRAME_MODE_MASK \
92 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
93 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME))
94
95#else
96
97#define LAST_FRAME_MODE_MASK \
98 ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | (1 << INTRA_FRAME))
99#define GOLDEN_FRAME_MODE_MASK \
100 ((1 << LAST_FRAME) | (1 << ALTREF_FRAME) | (1 << INTRA_FRAME))
101#define ALTREF_FRAME_MODE_MASK \
102 ((1 << LAST_FRAME) | (1 << GOLDEN_FRAME) | (1 << INTRA_FRAME))
103
104#endif // CONFIG_EXT_REFS
105
106#if CONFIG_EXT_REFS
107#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | (1 << BWDREF_FRAME) | 0x01)
108#else
109#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | 0x01)
110#endif // CONFIG_EXT_REFS
111
112#define MIN_EARLY_TERM_INDEX 3
113#define NEW_MV_DISCOUNT_FACTOR 8
114
115#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -0700116#define ANGLE_SKIP_THRESH 10
117#define FILTER_FAST_SEARCH 1
118#endif // CONFIG_EXT_INTRA
119
120const double ADST_FLIP_SVM[8] = { -6.6623, -2.8062, -3.2531, 3.1671, // vert
121 -7.7051, -3.2234, -3.6193, 3.4533 }; // horz
122
123typedef struct {
124 PREDICTION_MODE mode;
125 MV_REFERENCE_FRAME ref_frame[2];
126} MODE_DEFINITION;
127
128typedef struct { MV_REFERENCE_FRAME ref_frame[2]; } REF_DEFINITION;
129
130struct rdcost_block_args {
Yaowu Xuf883b422016-08-30 14:01:10 -0700131 const AV1_COMP *cpi;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700132 MACROBLOCK *x;
133 ENTROPY_CONTEXT t_above[2 * MAX_MIB_SIZE];
134 ENTROPY_CONTEXT t_left[2 * MAX_MIB_SIZE];
Angie Chiang7c2b7f22016-11-07 16:00:00 -0800135 RD_STATS rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700136 int64_t this_rd;
137 int64_t best_rd;
138 int exit_early;
139 int use_fast_coef_costing;
Urvang Joshi03f6fdc2016-10-14 15:53:39 -0700140 const SCAN_ORDER *scan_order;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700141};
142
143#define LAST_NEW_MV_INDEX 6
Yaowu Xuf883b422016-08-30 14:01:10 -0700144static const MODE_DEFINITION av1_mode_order[MAX_MODES] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700145 { NEARESTMV, { LAST_FRAME, NONE } },
146#if CONFIG_EXT_REFS
147 { NEARESTMV, { LAST2_FRAME, NONE } },
148 { NEARESTMV, { LAST3_FRAME, NONE } },
149 { NEARESTMV, { BWDREF_FRAME, NONE } },
150#endif // CONFIG_EXT_REFS
151 { NEARESTMV, { ALTREF_FRAME, NONE } },
152 { NEARESTMV, { GOLDEN_FRAME, NONE } },
153
154 { DC_PRED, { INTRA_FRAME, NONE } },
155
156 { NEWMV, { LAST_FRAME, NONE } },
157#if CONFIG_EXT_REFS
158 { NEWMV, { LAST2_FRAME, NONE } },
159 { NEWMV, { LAST3_FRAME, NONE } },
160 { NEWMV, { BWDREF_FRAME, NONE } },
161#endif // CONFIG_EXT_REFS
162 { NEWMV, { ALTREF_FRAME, NONE } },
163 { NEWMV, { GOLDEN_FRAME, NONE } },
164
165 { NEARMV, { LAST_FRAME, NONE } },
166#if CONFIG_EXT_REFS
167 { NEARMV, { LAST2_FRAME, NONE } },
168 { NEARMV, { LAST3_FRAME, NONE } },
169 { NEARMV, { BWDREF_FRAME, NONE } },
170#endif // CONFIG_EXT_REFS
171 { NEARMV, { ALTREF_FRAME, NONE } },
172 { NEARMV, { GOLDEN_FRAME, NONE } },
173
174#if CONFIG_EXT_INTER
175 { NEWFROMNEARMV, { LAST_FRAME, NONE } },
176#if CONFIG_EXT_REFS
177 { NEWFROMNEARMV, { LAST2_FRAME, NONE } },
178 { NEWFROMNEARMV, { LAST3_FRAME, NONE } },
179 { NEWFROMNEARMV, { BWDREF_FRAME, NONE } },
180#endif // CONFIG_EXT_REFS
181 { NEWFROMNEARMV, { ALTREF_FRAME, NONE } },
182 { NEWFROMNEARMV, { GOLDEN_FRAME, NONE } },
183#endif // CONFIG_EXT_INTER
184
185 { ZEROMV, { LAST_FRAME, NONE } },
186#if CONFIG_EXT_REFS
187 { ZEROMV, { LAST2_FRAME, NONE } },
188 { ZEROMV, { LAST3_FRAME, NONE } },
189 { ZEROMV, { BWDREF_FRAME, NONE } },
190#endif // CONFIG_EXT_REFS
191 { ZEROMV, { GOLDEN_FRAME, NONE } },
192 { ZEROMV, { ALTREF_FRAME, NONE } },
193
194// TODO(zoeliu): May need to reconsider the order on the modes to check
195
196#if CONFIG_EXT_INTER
197 { NEAREST_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
198#if CONFIG_EXT_REFS
199 { NEAREST_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
200 { NEAREST_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
201#endif // CONFIG_EXT_REFS
202 { NEAREST_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
203#if CONFIG_EXT_REFS
204 { NEAREST_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
205 { NEAREST_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
206 { NEAREST_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
207 { NEAREST_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
208#endif // CONFIG_EXT_REFS
209
210#else // CONFIG_EXT_INTER
211
212 { NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
213#if CONFIG_EXT_REFS
214 { NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
215 { NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
216#endif // CONFIG_EXT_REFS
217 { NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
218#if CONFIG_EXT_REFS
219 { NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
220 { NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
221 { NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
222 { NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
223#endif // CONFIG_EXT_REFS
224#endif // CONFIG_EXT_INTER
225
226 { TM_PRED, { INTRA_FRAME, NONE } },
227
Urvang Joshi6be4a542016-11-03 15:24:05 -0700228#if CONFIG_ALT_INTRA
229 { SMOOTH_PRED, { INTRA_FRAME, NONE } },
230#endif // CONFIG_ALT_INTRA
231
Yaowu Xuc27fc142016-08-22 16:08:15 -0700232#if CONFIG_EXT_INTER
233 { NEAR_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
234 { NEAREST_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
235 { NEAR_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
236 { NEW_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
237 { NEAREST_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
238 { NEW_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
239 { NEAR_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
240 { NEW_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
241 { ZERO_ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
242
243#if CONFIG_EXT_REFS
244 { NEAR_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
245 { NEAREST_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
246 { NEAR_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
247 { NEW_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
248 { NEAREST_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
249 { NEW_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
250 { NEAR_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
251 { NEW_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
252 { ZERO_ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
253
254 { NEAR_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
255 { NEAREST_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
256 { NEAR_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
257 { NEW_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
258 { NEAREST_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
259 { NEW_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
260 { NEAR_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
261 { NEW_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
262 { ZERO_ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
263#endif // CONFIG_EXT_REFS
264
265 { NEAR_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
266 { NEAREST_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
267 { NEAR_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
268 { NEW_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
269 { NEAREST_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
270 { NEW_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
271 { NEAR_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
272 { NEW_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
273 { ZERO_ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
274
275#if CONFIG_EXT_REFS
276 { NEAR_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
277 { NEAREST_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
278 { NEAR_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
279 { NEW_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
280 { NEAREST_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
281 { NEW_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
282 { NEAR_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
283 { NEW_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
284 { ZERO_ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
285
286 { NEAR_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
287 { NEAREST_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
288 { NEAR_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
289 { NEW_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
290 { NEAREST_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
291 { NEW_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
292 { NEAR_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
293 { NEW_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
294 { ZERO_ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
295
296 { NEAR_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
297 { NEAREST_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
298 { NEAR_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
299 { NEW_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
300 { NEAREST_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
301 { NEW_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
302 { NEAR_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
303 { NEW_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
304 { ZERO_ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
305
306 { NEAR_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
307 { NEAREST_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
308 { NEAR_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
309 { NEW_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
310 { NEAREST_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
311 { NEW_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
312 { NEAR_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
313 { NEW_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
314 { ZERO_ZEROMV, { GOLDEN_FRAME, BWDREF_FRAME } },
315#endif // CONFIG_EXT_REFS
316
317#else // CONFIG_EXT_INTER
318
319 { NEARMV, { LAST_FRAME, ALTREF_FRAME } },
320 { NEWMV, { LAST_FRAME, ALTREF_FRAME } },
321#if CONFIG_EXT_REFS
322 { NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
323 { NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
324 { NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
325 { NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
326#endif // CONFIG_EXT_REFS
327 { NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
328 { NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
329
330#if CONFIG_EXT_REFS
331 { NEARMV, { LAST_FRAME, BWDREF_FRAME } },
332 { NEWMV, { LAST_FRAME, BWDREF_FRAME } },
333 { NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
334 { NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
335 { NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
336 { NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
337 { NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
338 { NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
339#endif // CONFIG_EXT_REFS
340
341 { ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
342#if CONFIG_EXT_REFS
343 { ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
344 { ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
345#endif // CONFIG_EXT_REFS
346 { ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
347
348#if CONFIG_EXT_REFS
349 { ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
350 { ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
351 { ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
352 { ZEROMV, { GOLDEN_FRAME, BWDREF_FRAME } },
353#endif // CONFIG_EXT_REFS
354
355#endif // CONFIG_EXT_INTER
356
357 { H_PRED, { INTRA_FRAME, NONE } },
358 { V_PRED, { INTRA_FRAME, NONE } },
359 { D135_PRED, { INTRA_FRAME, NONE } },
360 { D207_PRED, { INTRA_FRAME, NONE } },
361 { D153_PRED, { INTRA_FRAME, NONE } },
362 { D63_PRED, { INTRA_FRAME, NONE } },
363 { D117_PRED, { INTRA_FRAME, NONE } },
364 { D45_PRED, { INTRA_FRAME, NONE } },
365
366#if CONFIG_EXT_INTER
367 { ZEROMV, { LAST_FRAME, INTRA_FRAME } },
368 { NEARESTMV, { LAST_FRAME, INTRA_FRAME } },
369 { NEARMV, { LAST_FRAME, INTRA_FRAME } },
370 { NEWMV, { LAST_FRAME, INTRA_FRAME } },
371
372#if CONFIG_EXT_REFS
373 { ZEROMV, { LAST2_FRAME, INTRA_FRAME } },
374 { NEARESTMV, { LAST2_FRAME, INTRA_FRAME } },
375 { NEARMV, { LAST2_FRAME, INTRA_FRAME } },
376 { NEWMV, { LAST2_FRAME, INTRA_FRAME } },
377
378 { ZEROMV, { LAST3_FRAME, INTRA_FRAME } },
379 { NEARESTMV, { LAST3_FRAME, INTRA_FRAME } },
380 { NEARMV, { LAST3_FRAME, INTRA_FRAME } },
381 { NEWMV, { LAST3_FRAME, INTRA_FRAME } },
382#endif // CONFIG_EXT_REFS
383
384 { ZEROMV, { GOLDEN_FRAME, INTRA_FRAME } },
385 { NEARESTMV, { GOLDEN_FRAME, INTRA_FRAME } },
386 { NEARMV, { GOLDEN_FRAME, INTRA_FRAME } },
387 { NEWMV, { GOLDEN_FRAME, INTRA_FRAME } },
388
389#if CONFIG_EXT_REFS
390 { ZEROMV, { BWDREF_FRAME, INTRA_FRAME } },
391 { NEARESTMV, { BWDREF_FRAME, INTRA_FRAME } },
392 { NEARMV, { BWDREF_FRAME, INTRA_FRAME } },
393 { NEWMV, { BWDREF_FRAME, INTRA_FRAME } },
394#endif // CONFIG_EXT_REFS
395
396 { ZEROMV, { ALTREF_FRAME, INTRA_FRAME } },
397 { NEARESTMV, { ALTREF_FRAME, INTRA_FRAME } },
398 { NEARMV, { ALTREF_FRAME, INTRA_FRAME } },
399 { NEWMV, { ALTREF_FRAME, INTRA_FRAME } },
400#endif // CONFIG_EXT_INTER
401};
402
Yaowu Xuf883b422016-08-30 14:01:10 -0700403static const REF_DEFINITION av1_ref_order[MAX_REFS] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700404 { { LAST_FRAME, NONE } },
405#if CONFIG_EXT_REFS
406 { { LAST2_FRAME, NONE } }, { { LAST3_FRAME, NONE } },
407 { { BWDREF_FRAME, NONE } },
408#endif // CONFIG_EXT_REFS
409 { { GOLDEN_FRAME, NONE } }, { { ALTREF_FRAME, NONE } },
410
411 { { LAST_FRAME, ALTREF_FRAME } },
412#if CONFIG_EXT_REFS
413 { { LAST2_FRAME, ALTREF_FRAME } }, { { LAST3_FRAME, ALTREF_FRAME } },
414#endif // CONFIG_EXT_REFS
415 { { GOLDEN_FRAME, ALTREF_FRAME } },
416
417#if CONFIG_EXT_REFS
418 { { LAST_FRAME, BWDREF_FRAME } }, { { LAST2_FRAME, BWDREF_FRAME } },
419 { { LAST3_FRAME, BWDREF_FRAME } }, { { GOLDEN_FRAME, BWDREF_FRAME } },
420#endif // CONFIG_EXT_REFS
421
422 { { INTRA_FRAME, NONE } },
423};
424
hui su5db97432016-10-14 16:10:14 -0700425#if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700426static INLINE int write_uniform_cost(int n, int v) {
427 int l = get_unsigned_bits(n), m = (1 << l) - n;
428 if (l == 0) return 0;
429 if (v < m)
Yaowu Xuf883b422016-08-30 14:01:10 -0700430 return (l - 1) * av1_cost_bit(128, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700431 else
Yaowu Xuf883b422016-08-30 14:01:10 -0700432 return l * av1_cost_bit(128, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700433}
hui su5db97432016-10-14 16:10:14 -0700434#endif // CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700435
436// constants for prune 1 and prune 2 decision boundaries
437#define FAST_EXT_TX_CORR_MID 0.0
438#define FAST_EXT_TX_EDST_MID 0.1
439#define FAST_EXT_TX_CORR_MARGIN 0.5
440#define FAST_EXT_TX_EDST_MARGIN 0.3
441
442static const TX_TYPE_1D vtx_tab[TX_TYPES] = {
443 DCT_1D, ADST_1D, DCT_1D, ADST_1D,
444#if CONFIG_EXT_TX
445 FLIPADST_1D, DCT_1D, FLIPADST_1D, ADST_1D, FLIPADST_1D, IDTX_1D,
446 DCT_1D, IDTX_1D, ADST_1D, IDTX_1D, FLIPADST_1D, IDTX_1D,
447#endif // CONFIG_EXT_TX
448};
449
450static const TX_TYPE_1D htx_tab[TX_TYPES] = {
451 DCT_1D, DCT_1D, ADST_1D, ADST_1D,
452#if CONFIG_EXT_TX
453 DCT_1D, FLIPADST_1D, FLIPADST_1D, FLIPADST_1D, ADST_1D, IDTX_1D,
454 IDTX_1D, DCT_1D, IDTX_1D, ADST_1D, IDTX_1D, FLIPADST_1D,
455#endif // CONFIG_EXT_TX
456};
457
Yaowu Xuf883b422016-08-30 14:01:10 -0700458static void get_energy_distribution_fine(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700459 uint8_t *src, int src_stride,
460 uint8_t *dst, int dst_stride,
461 double *hordist, double *verdist) {
Jingning Han73db4ac2016-11-30 11:23:27 -0800462 int bw = block_size_wide[bsize];
463 int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700464 unsigned int esq[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
465 unsigned int var[16];
466 double total = 0;
467
468 const int f_index = bsize - BLOCK_16X16;
469 if (f_index < 0) {
470 int i, j, index;
471 int w_shift = bw == 8 ? 1 : 2;
472 int h_shift = bh == 8 ? 1 : 2;
Yaowu Xuf883b422016-08-30 14:01:10 -0700473#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700474 if (cpi->common.use_highbitdepth) {
475 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
476 uint16_t *dst16 = CONVERT_TO_SHORTPTR(dst);
477 for (i = 0; i < bh; ++i)
478 for (j = 0; j < bw; ++j) {
479 index = (j >> w_shift) + ((i >> h_shift) << 2);
480 esq[index] +=
481 (src16[j + i * src_stride] - dst16[j + i * dst_stride]) *
482 (src16[j + i * src_stride] - dst16[j + i * dst_stride]);
483 }
484 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700485#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700486
487 for (i = 0; i < bh; ++i)
488 for (j = 0; j < bw; ++j) {
489 index = (j >> w_shift) + ((i >> h_shift) << 2);
490 esq[index] += (src[j + i * src_stride] - dst[j + i * dst_stride]) *
491 (src[j + i * src_stride] - dst[j + i * dst_stride]);
492 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700493#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700494 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700495#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700496 } else {
497 var[0] = cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[0]);
498 var[1] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
499 dst_stride, &esq[1]);
500 var[2] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
501 dst_stride, &esq[2]);
502 var[3] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
503 dst + 3 * bw / 4, dst_stride, &esq[3]);
504 src += bh / 4 * src_stride;
505 dst += bh / 4 * dst_stride;
506
507 var[4] = cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[4]);
508 var[5] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
509 dst_stride, &esq[5]);
510 var[6] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
511 dst_stride, &esq[6]);
512 var[7] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
513 dst + 3 * bw / 4, dst_stride, &esq[7]);
514 src += bh / 4 * src_stride;
515 dst += bh / 4 * dst_stride;
516
517 var[8] = cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[8]);
518 var[9] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
519 dst_stride, &esq[9]);
520 var[10] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
521 dst_stride, &esq[10]);
522 var[11] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
523 dst + 3 * bw / 4, dst_stride, &esq[11]);
524 src += bh / 4 * src_stride;
525 dst += bh / 4 * dst_stride;
526
527 var[12] =
528 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[12]);
529 var[13] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
530 dst_stride, &esq[13]);
531 var[14] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
532 dst_stride, &esq[14]);
533 var[15] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
534 dst + 3 * bw / 4, dst_stride, &esq[15]);
535 }
536
537 total = esq[0] + esq[1] + esq[2] + esq[3] + esq[4] + esq[5] + esq[6] +
538 esq[7] + esq[8] + esq[9] + esq[10] + esq[11] + esq[12] + esq[13] +
539 esq[14] + esq[15];
540 if (total > 0) {
541 const double e_recip = 1.0 / total;
542 hordist[0] =
543 ((double)esq[0] + (double)esq[4] + (double)esq[8] + (double)esq[12]) *
544 e_recip;
545 hordist[1] =
546 ((double)esq[1] + (double)esq[5] + (double)esq[9] + (double)esq[13]) *
547 e_recip;
548 hordist[2] =
549 ((double)esq[2] + (double)esq[6] + (double)esq[10] + (double)esq[14]) *
550 e_recip;
551 verdist[0] =
552 ((double)esq[0] + (double)esq[1] + (double)esq[2] + (double)esq[3]) *
553 e_recip;
554 verdist[1] =
555 ((double)esq[4] + (double)esq[5] + (double)esq[6] + (double)esq[7]) *
556 e_recip;
557 verdist[2] =
558 ((double)esq[8] + (double)esq[9] + (double)esq[10] + (double)esq[11]) *
559 e_recip;
560 } else {
561 hordist[0] = verdist[0] = 0.25;
562 hordist[1] = verdist[1] = 0.25;
563 hordist[2] = verdist[2] = 0.25;
564 }
565 (void)var[0];
566 (void)var[1];
567 (void)var[2];
568 (void)var[3];
569 (void)var[4];
570 (void)var[5];
571 (void)var[6];
572 (void)var[7];
573 (void)var[8];
574 (void)var[9];
575 (void)var[10];
576 (void)var[11];
577 (void)var[12];
578 (void)var[13];
579 (void)var[14];
580 (void)var[15];
581}
582
Yaowu Xuf883b422016-08-30 14:01:10 -0700583static int adst_vs_flipadst(const AV1_COMP *cpi, BLOCK_SIZE bsize, uint8_t *src,
584 int src_stride, uint8_t *dst, int dst_stride,
585 double *hdist, double *vdist) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700586 int prune_bitmask = 0;
587 double svm_proj_h = 0, svm_proj_v = 0;
588 get_energy_distribution_fine(cpi, bsize, src, src_stride, dst, dst_stride,
589 hdist, vdist);
590
591 svm_proj_v = vdist[0] * ADST_FLIP_SVM[0] + vdist[1] * ADST_FLIP_SVM[1] +
592 vdist[2] * ADST_FLIP_SVM[2] + ADST_FLIP_SVM[3];
593 svm_proj_h = hdist[0] * ADST_FLIP_SVM[4] + hdist[1] * ADST_FLIP_SVM[5] +
594 hdist[2] * ADST_FLIP_SVM[6] + ADST_FLIP_SVM[7];
595 if (svm_proj_v > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
596 prune_bitmask |= 1 << FLIPADST_1D;
597 else if (svm_proj_v < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
598 prune_bitmask |= 1 << ADST_1D;
599
600 if (svm_proj_h > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
601 prune_bitmask |= 1 << (FLIPADST_1D + 8);
602 else if (svm_proj_h < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
603 prune_bitmask |= 1 << (ADST_1D + 8);
604
605 return prune_bitmask;
606}
607
608#if CONFIG_EXT_TX
609static void get_horver_correlation(int16_t *diff, int stride, int w, int h,
610 double *hcorr, double *vcorr) {
611 // Returns hor/ver correlation coefficient
612 const int num = (h - 1) * (w - 1);
613 double num_r;
614 int i, j;
615 int64_t xy_sum = 0, xz_sum = 0;
616 int64_t x_sum = 0, y_sum = 0, z_sum = 0;
617 int64_t x2_sum = 0, y2_sum = 0, z2_sum = 0;
618 double x_var_n, y_var_n, z_var_n, xy_var_n, xz_var_n;
619 *hcorr = *vcorr = 1;
620
621 assert(num > 0);
622 num_r = 1.0 / num;
623 for (i = 1; i < h; ++i) {
624 for (j = 1; j < w; ++j) {
625 const int16_t x = diff[i * stride + j];
626 const int16_t y = diff[i * stride + j - 1];
627 const int16_t z = diff[(i - 1) * stride + j];
628 xy_sum += x * y;
629 xz_sum += x * z;
630 x_sum += x;
631 y_sum += y;
632 z_sum += z;
633 x2_sum += x * x;
634 y2_sum += y * y;
635 z2_sum += z * z;
636 }
637 }
638 x_var_n = x2_sum - (x_sum * x_sum) * num_r;
639 y_var_n = y2_sum - (y_sum * y_sum) * num_r;
640 z_var_n = z2_sum - (z_sum * z_sum) * num_r;
641 xy_var_n = xy_sum - (x_sum * y_sum) * num_r;
642 xz_var_n = xz_sum - (x_sum * z_sum) * num_r;
643 if (x_var_n > 0 && y_var_n > 0) {
644 *hcorr = xy_var_n / sqrt(x_var_n * y_var_n);
645 *hcorr = *hcorr < 0 ? 0 : *hcorr;
646 }
647 if (x_var_n > 0 && z_var_n > 0) {
648 *vcorr = xz_var_n / sqrt(x_var_n * z_var_n);
649 *vcorr = *vcorr < 0 ? 0 : *vcorr;
650 }
651}
652
653int dct_vs_idtx(int16_t *diff, int stride, int w, int h, double *hcorr,
654 double *vcorr) {
655 int prune_bitmask = 0;
656 get_horver_correlation(diff, stride, w, h, hcorr, vcorr);
657
658 if (*vcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
659 prune_bitmask |= 1 << IDTX_1D;
660 else if (*vcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
661 prune_bitmask |= 1 << DCT_1D;
662
663 if (*hcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
664 prune_bitmask |= 1 << (IDTX_1D + 8);
665 else if (*hcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
666 prune_bitmask |= 1 << (DCT_1D + 8);
667 return prune_bitmask;
668}
669
670// Performance drop: 0.5%, Speed improvement: 24%
Yaowu Xuf883b422016-08-30 14:01:10 -0700671static int prune_two_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700672 MACROBLOCK *x, MACROBLOCKD *xd, int adst_flipadst,
673 int dct_idtx) {
674 struct macroblock_plane *const p = &x->plane[0];
675 struct macroblockd_plane *const pd = &xd->plane[0];
676 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
677 const int bw = 4 << (b_width_log2_lookup[bs]);
678 const int bh = 4 << (b_height_log2_lookup[bs]);
679 double hdist[3] = { 0, 0, 0 }, vdist[3] = { 0, 0, 0 };
680 double hcorr, vcorr;
681 int prune = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700682 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700683
684 if (adst_flipadst)
685 prune |= adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride,
686 pd->dst.buf, pd->dst.stride, hdist, vdist);
687 if (dct_idtx) prune |= dct_vs_idtx(p->src_diff, bw, bw, bh, &hcorr, &vcorr);
688
689 return prune;
690}
691#endif // CONFIG_EXT_TX
692
693// Performance drop: 0.3%, Speed improvement: 5%
Yaowu Xuf883b422016-08-30 14:01:10 -0700694static int prune_one_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700695 MACROBLOCK *x, MACROBLOCKD *xd) {
696 struct macroblock_plane *const p = &x->plane[0];
697 struct macroblockd_plane *const pd = &xd->plane[0];
698 double hdist[3] = { 0, 0, 0 }, vdist[3] = { 0, 0, 0 };
Yaowu Xuf883b422016-08-30 14:01:10 -0700699 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700700 return adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride, pd->dst.buf,
701 pd->dst.stride, hdist, vdist);
702}
703
Yaowu Xuf883b422016-08-30 14:01:10 -0700704static int prune_tx_types(const AV1_COMP *cpi, BLOCK_SIZE bsize, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700705 MACROBLOCKD *xd, int tx_set) {
706#if CONFIG_EXT_TX
707 const int *tx_set_1D = ext_tx_used_inter_1D[tx_set];
708#else
709 const int tx_set_1D[TX_TYPES_1D] = { 0 };
710#endif
711
712 switch (cpi->sf.tx_type_search.prune_mode) {
713 case NO_PRUNE: return 0; break;
714 case PRUNE_ONE:
Sarah Parker68a26b62016-10-28 13:19:33 -0700715 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700716 return 0;
717 return prune_one_for_sby(cpi, bsize, x, xd);
718 break;
719#if CONFIG_EXT_TX
720 case PRUNE_TWO:
Sarah Parker68a26b62016-10-28 13:19:33 -0700721 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D])) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700722 if (!(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D])) return 0;
723 return prune_two_for_sby(cpi, bsize, x, xd, 0, 1);
724 }
Sarah Parker68a26b62016-10-28 13:19:33 -0700725 if ((tx_set >= 0) && !(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700726 return prune_two_for_sby(cpi, bsize, x, xd, 1, 0);
727 return prune_two_for_sby(cpi, bsize, x, xd, 1, 1);
728 break;
729#endif
730 }
731 assert(0);
732 return 0;
733}
734
735static int do_tx_type_search(TX_TYPE tx_type, int prune) {
736// TODO(sarahparker) implement for non ext tx
737#if CONFIG_EXT_TX
738 return !(((prune >> vtx_tab[tx_type]) & 1) |
739 ((prune >> (htx_tab[tx_type] + 8)) & 1));
740#else
741 // temporary to avoid compiler warnings
742 (void)vtx_tab;
743 (void)htx_tab;
744 (void)tx_type;
745 (void)prune;
746 return 1;
747#endif
748}
749
Yaowu Xuf883b422016-08-30 14:01:10 -0700750static void model_rd_from_sse(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700751 const MACROBLOCKD *const xd, BLOCK_SIZE bsize,
752 int plane, int64_t sse, int *rate,
753 int64_t *dist) {
754 const struct macroblockd_plane *const pd = &xd->plane[plane];
755 const int dequant_shift =
Yaowu Xuf883b422016-08-30 14:01:10 -0700756#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700757 (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd - 5 :
Yaowu Xuf883b422016-08-30 14:01:10 -0700758#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700759 3;
760
761 // Fast approximate the modelling function.
762 if (cpi->sf.simple_model_rd_from_var) {
763 const int64_t square_error = sse;
764 int quantizer = (pd->dequant[1] >> dequant_shift);
765
766 if (quantizer < 120)
767 *rate = (int)((square_error * (280 - quantizer)) >>
Yaowu Xuf883b422016-08-30 14:01:10 -0700768 (16 - AV1_PROB_COST_SHIFT));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700769 else
770 *rate = 0;
771 *dist = (square_error * quantizer) >> 8;
772 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700773 av1_model_rd_from_var_lapndz(sse, num_pels_log2_lookup[bsize],
774 pd->dequant[1] >> dequant_shift, rate, dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700775 }
776
777 *dist <<= 4;
778}
779
Yaowu Xuf883b422016-08-30 14:01:10 -0700780static void model_rd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700781 MACROBLOCK *x, MACROBLOCKD *xd, int plane_from,
782 int plane_to, int *out_rate_sum,
783 int64_t *out_dist_sum, int *skip_txfm_sb,
784 int64_t *skip_sse_sb) {
785 // Note our transform coeffs are 8 times an orthogonal transform.
786 // Hence quantizer step is also 8 times. To get effective quantizer
787 // we need to divide by 8 before sending to modeling function.
788 int plane;
789 const int ref = xd->mi[0]->mbmi.ref_frame[0];
790
791 int64_t rate_sum = 0;
792 int64_t dist_sum = 0;
793 int64_t total_sse = 0;
794
795 x->pred_sse[ref] = 0;
796
797 for (plane = plane_from; plane <= plane_to; ++plane) {
798 struct macroblock_plane *const p = &x->plane[plane];
799 struct macroblockd_plane *const pd = &xd->plane[plane];
800 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
801
802 unsigned int sse;
803 int rate;
804 int64_t dist;
805
806 // TODO(geza): Write direct sse functions that do not compute
807 // variance as well.
808 cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride, pd->dst.buf, pd->dst.stride,
809 &sse);
810
811 if (plane == 0) x->pred_sse[ref] = sse;
812
813 total_sse += sse;
814
815 model_rd_from_sse(cpi, xd, bs, plane, sse, &rate, &dist);
816
817 rate_sum += rate;
818 dist_sum += dist;
819 }
820
821 *skip_txfm_sb = total_sse == 0;
822 *skip_sse_sb = total_sse << 4;
823 *out_rate_sum = (int)rate_sum;
824 *out_dist_sum = dist_sum;
825}
826
Yushin Cho77bba8d2016-11-04 16:36:56 -0700827#if CONFIG_PVQ
828// Without PVQ, av1_block_error_c() return two kind of errors,
829// 1) reconstruction (i.e. decoded) error and
830// 2) Squared sum of transformed residue (i.e. 'coeff')
831// However, if PVQ is enabled, coeff does not keep the transformed residue
832// but instead a transformed original is kept.
833// Hence, new parameter ref vector (i.e. transformed predicted signal)
834// is required to derive the residue signal,
835// i.e. coeff - ref = residue (all transformed).
836
837// TODO(yushin) : Since 4x4 case does not need ssz, better to refactor into
838// a separate function that does not do the extra computations for ssz.
839int64_t av1_block_error2_c(const tran_low_t *coeff, const tran_low_t *dqcoeff,
840 const tran_low_t *ref, intptr_t block_size,
841 int64_t *ssz) {
842 int64_t error;
843
844 // Use the existing sse codes for calculating distortion of decoded signal:
845 // i.e. (orig - decoded)^2
846 error = av1_block_error_fp(coeff, dqcoeff, block_size);
847 // prediction residue^2 = (orig - ref)^2
848 *ssz = av1_block_error_fp(coeff, ref, block_size);
849
850 return error;
851}
852#endif
853
Yaowu Xuf883b422016-08-30 14:01:10 -0700854int64_t av1_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff,
855 intptr_t block_size, int64_t *ssz) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700856 int i;
857 int64_t error = 0, sqcoeff = 0;
858
859 for (i = 0; i < block_size; i++) {
860 const int diff = coeff[i] - dqcoeff[i];
861 error += diff * diff;
862 sqcoeff += coeff[i] * coeff[i];
863 }
864
865 *ssz = sqcoeff;
866 return error;
867}
868
Yaowu Xuf883b422016-08-30 14:01:10 -0700869int64_t av1_block_error_fp_c(const int16_t *coeff, const int16_t *dqcoeff,
870 int block_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700871 int i;
872 int64_t error = 0;
873
874 for (i = 0; i < block_size; i++) {
875 const int diff = coeff[i] - dqcoeff[i];
876 error += diff * diff;
877 }
878
879 return error;
880}
881
Yaowu Xuf883b422016-08-30 14:01:10 -0700882#if CONFIG_AOM_HIGHBITDEPTH
883int64_t av1_highbd_block_error_c(const tran_low_t *coeff,
884 const tran_low_t *dqcoeff, intptr_t block_size,
885 int64_t *ssz, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700886 int i;
887 int64_t error = 0, sqcoeff = 0;
888 int shift = 2 * (bd - 8);
889 int rounding = shift > 0 ? 1 << (shift - 1) : 0;
890
891 for (i = 0; i < block_size; i++) {
892 const int64_t diff = coeff[i] - dqcoeff[i];
893 error += diff * diff;
894 sqcoeff += (int64_t)coeff[i] * (int64_t)coeff[i];
895 }
896 assert(error >= 0 && sqcoeff >= 0);
897 error = (error + rounding) >> shift;
898 sqcoeff = (sqcoeff + rounding) >> shift;
899
900 *ssz = sqcoeff;
901 return error;
902}
Yaowu Xuf883b422016-08-30 14:01:10 -0700903#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700904
Yushin Cho77bba8d2016-11-04 16:36:56 -0700905#if !CONFIG_PVQ
Debargha Mukherjeeceebb702016-10-11 05:26:50 -0700906/* The trailing '0' is a terminator which is used inside av1_cost_coeffs() to
Yaowu Xuc27fc142016-08-22 16:08:15 -0700907 * decide whether to include cost of a trailing EOB node or not (i.e. we
908 * can skip this if the last coefficient in this transform block, e.g. the
909 * 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block,
910 * were non-zero). */
Angie Chiang22ba7512016-10-20 17:10:33 -0700911int av1_cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
912 int block, int coeff_ctx, TX_SIZE tx_size,
913 const int16_t *scan, const int16_t *nb,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -0700914 int use_fast_coef_costing) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700915 MACROBLOCKD *const xd = &x->e_mbd;
916 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
917 const struct macroblock_plane *p = &x->plane[plane];
918 const struct macroblockd_plane *pd = &xd->plane[plane];
919 const PLANE_TYPE type = pd->plane_type;
920 const uint16_t *band_count = &band_count_table[tx_size][1];
921 const int eob = p->eobs[block];
922 const tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
923 const int tx_size_ctx = txsize_sqr_map[tx_size];
924 unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
925 x->token_costs[tx_size_ctx][type][is_inter_block(mbmi)];
926 uint8_t token_cache[MAX_TX_SQUARE];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700927 int pt = coeff_ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700928 int c, cost;
Yaowu Xuf883b422016-08-30 14:01:10 -0700929#if CONFIG_AOM_HIGHBITDEPTH
930 const int *cat6_high_cost = av1_get_high_cost_table(xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700931#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700932 const int *cat6_high_cost = av1_get_high_cost_table(8);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700933#endif
934
935#if !CONFIG_VAR_TX && !CONFIG_SUPERTX
936 // Check for consistency of tx_size with mode info
937 assert(type == PLANE_TYPE_Y ? mbmi->tx_size == tx_size
938 : get_uv_tx_size(mbmi, pd) == tx_size);
939#endif // !CONFIG_VAR_TX && !CONFIG_SUPERTX
Angie Chiang22ba7512016-10-20 17:10:33 -0700940 (void)cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700941
942 if (eob == 0) {
943 // single eob token
944 cost = token_costs[0][0][pt][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700945 } else {
946 if (use_fast_coef_costing) {
947 int band_left = *band_count++;
948
949 // dc token
950 int v = qcoeff[0];
951 int16_t prev_t;
Yaowu Xuf883b422016-08-30 14:01:10 -0700952 cost = av1_get_token_cost(v, &prev_t, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700953 cost += (*token_costs)[0][pt][prev_t];
954
Yaowu Xuf883b422016-08-30 14:01:10 -0700955 token_cache[0] = av1_pt_energy_class[prev_t];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700956 ++token_costs;
957
958 // ac tokens
959 for (c = 1; c < eob; c++) {
960 const int rc = scan[c];
961 int16_t t;
962
963 v = qcoeff[rc];
Yaowu Xuf883b422016-08-30 14:01:10 -0700964 cost += av1_get_token_cost(v, &t, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700965 cost += (*token_costs)[!prev_t][!prev_t][t];
966 prev_t = t;
967 if (!--band_left) {
968 band_left = *band_count++;
969 ++token_costs;
970 }
971 }
972
973 // eob token
974 if (band_left) cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
975
976 } else { // !use_fast_coef_costing
977 int band_left = *band_count++;
978
979 // dc token
980 int v = qcoeff[0];
981 int16_t tok;
982 unsigned int(*tok_cost_ptr)[COEFF_CONTEXTS][ENTROPY_TOKENS];
Yaowu Xuf883b422016-08-30 14:01:10 -0700983 cost = av1_get_token_cost(v, &tok, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700984 cost += (*token_costs)[0][pt][tok];
985
Yaowu Xuf883b422016-08-30 14:01:10 -0700986 token_cache[0] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700987 ++token_costs;
988
989 tok_cost_ptr = &((*token_costs)[!tok]);
990
991 // ac tokens
992 for (c = 1; c < eob; c++) {
993 const int rc = scan[c];
994
995 v = qcoeff[rc];
Yaowu Xuf883b422016-08-30 14:01:10 -0700996 cost += av1_get_token_cost(v, &tok, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700997 pt = get_coef_context(nb, token_cache, c);
998 cost += (*tok_cost_ptr)[pt][tok];
Yaowu Xuf883b422016-08-30 14:01:10 -0700999 token_cache[rc] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001000 if (!--band_left) {
1001 band_left = *band_count++;
1002 ++token_costs;
1003 }
1004 tok_cost_ptr = &((*token_costs)[!tok]);
1005 }
1006
1007 // eob token
1008 if (band_left) {
1009 pt = get_coef_context(nb, token_cache, c);
1010 cost += (*token_costs)[0][pt][EOB_TOKEN];
1011 }
1012 }
1013 }
1014
Yaowu Xuc27fc142016-08-22 16:08:15 -07001015 return cost;
1016}
Yushin Cho77bba8d2016-11-04 16:36:56 -07001017#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001018
Yaowu Xuf883b422016-08-30 14:01:10 -07001019static void dist_block(const AV1_COMP *cpi, MACROBLOCK *x, int plane, int block,
1020 int blk_row, int blk_col, TX_SIZE tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001021 int64_t *out_dist, int64_t *out_sse) {
1022 MACROBLOCKD *const xd = &x->e_mbd;
1023 const struct macroblock_plane *const p = &x->plane[plane];
1024 const struct macroblockd_plane *const pd = &xd->plane[plane];
1025 if (cpi->sf.use_transform_domain_distortion) {
1026 // Transform domain distortion computation is more accurate as it does
1027 // not involve an inverse transform, but it is less accurate.
Jingning Hanb9c57272016-10-25 10:15:39 -07001028 const int buffer_length = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001029 int64_t this_sse;
Debargha Mukherjee0e119122016-11-04 12:10:23 -07001030 int shift = (MAX_TX_SCALE - get_tx_scale(tx_size)) * 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001031 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
1032 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001033#if CONFIG_PVQ
Yaowu Xud6ea71c2016-11-07 10:24:14 -08001034 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001035#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001036#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001037 const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
Jingning Hanb9c57272016-10-25 10:15:39 -07001038 *out_dist =
1039 av1_highbd_block_error(coeff, dqcoeff, buffer_length, &this_sse, bd) >>
1040 shift;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001041#elif CONFIG_PVQ
1042 *out_dist = av1_block_error2_c(coeff, dqcoeff, ref_coeff, buffer_length,
1043 &this_sse) >>
1044 shift;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001045#else
1046 *out_dist =
Jingning Hanb9c57272016-10-25 10:15:39 -07001047 av1_block_error(coeff, dqcoeff, buffer_length, &this_sse) >> shift;
Yaowu Xuf883b422016-08-30 14:01:10 -07001048#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001049 *out_sse = this_sse >> shift;
1050 } else {
1051 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Jingning Hanb9c57272016-10-25 10:15:39 -07001052 const int bsw = block_size_wide[tx_bsize];
1053 const int bsh = block_size_high[tx_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001054 const int src_stride = x->plane[plane].src.stride;
1055 const int dst_stride = xd->plane[plane].dst.stride;
Jingning Hanb9c57272016-10-25 10:15:39 -07001056 // Scale the transform block index to pixel unit.
1057 const int src_idx = (blk_row * src_stride + blk_col)
1058 << tx_size_wide_log2[0];
1059 const int dst_idx = (blk_row * dst_stride + blk_col)
1060 << tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001061 const uint8_t *src = &x->plane[plane].src.buf[src_idx];
1062 const uint8_t *dst = &xd->plane[plane].dst.buf[dst_idx];
1063 const tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1064 const uint16_t eob = p->eobs[block];
1065
1066 unsigned int tmp;
1067
1068 assert(cpi != NULL);
Jingning Hanb9c57272016-10-25 10:15:39 -07001069 assert(tx_size_wide_log2[0] == tx_size_high_log2[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001070
1071 cpi->fn_ptr[tx_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
1072 *out_sse = (int64_t)tmp * 16;
1073
1074 if (eob) {
1075 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Yaowu Xuf883b422016-08-30 14:01:10 -07001076#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001077 DECLARE_ALIGNED(16, uint16_t, recon16[MAX_TX_SQUARE]);
1078 uint8_t *recon = (uint8_t *)recon16;
1079#else
1080 DECLARE_ALIGNED(16, uint8_t, recon[MAX_TX_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07001081#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001082
1083 const PLANE_TYPE plane_type = plane == 0 ? PLANE_TYPE_Y : PLANE_TYPE_UV;
1084
1085 INV_TXFM_PARAM inv_txfm_param;
1086
1087 inv_txfm_param.tx_type = get_tx_type(plane_type, xd, block, tx_size);
1088 inv_txfm_param.tx_size = tx_size;
1089 inv_txfm_param.eob = eob;
1090 inv_txfm_param.lossless = xd->lossless[mbmi->segment_id];
1091
Yaowu Xuf883b422016-08-30 14:01:10 -07001092#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001093 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1094 recon = CONVERT_TO_BYTEPTR(recon);
1095 inv_txfm_param.bd = xd->bd;
Yaowu Xuf883b422016-08-30 14:01:10 -07001096 aom_highbd_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001097 NULL, 0, bsw, bsh, xd->bd);
1098 highbd_inv_txfm_add(dqcoeff, recon, MAX_TX_SIZE, &inv_txfm_param);
1099 } else
Yaowu Xuf883b422016-08-30 14:01:10 -07001100#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001101 {
Yushin Cho721868c2016-11-14 16:04:33 +09001102#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -07001103 aom_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001104 bsw, bsh);
Yushin Cho721868c2016-11-14 16:04:33 +09001105#else
1106 int i, j;
1107
1108 for (j = 0; j < bsh; j++)
1109 for (i = 0; i < bsw; i++) recon[j * MAX_TX_SIZE + i] = 0;
1110#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001111 inv_txfm_add(dqcoeff, recon, MAX_TX_SIZE, &inv_txfm_param);
1112 }
1113
1114 cpi->fn_ptr[tx_bsize].vf(src, src_stride, recon, MAX_TX_SIZE, &tmp);
1115 }
1116
1117 *out_dist = (int64_t)tmp * 16;
1118 }
1119}
1120
Yushin Cho77bba8d2016-11-04 16:36:56 -07001121#if !CONFIG_PVQ
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001122static int rate_block(int plane, int block, int coeff_ctx, TX_SIZE tx_size,
Debargha Mukherjee29630542016-09-06 13:15:31 -07001123 struct rdcost_block_args *args) {
Angie Chiang22ba7512016-10-20 17:10:33 -07001124 return av1_cost_coeffs(&args->cpi->common, args->x, plane, block, coeff_ctx,
1125 tx_size, args->scan_order->scan,
1126 args->scan_order->neighbors,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001127 args->use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001128}
Yushin Cho77bba8d2016-11-04 16:36:56 -07001129#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001130
1131static uint64_t sum_squares_2d(const int16_t *diff, int diff_stride,
1132 TX_SIZE tx_size) {
1133 uint64_t sse;
1134 switch (tx_size) {
Jingning Han2194eec2016-12-01 15:20:16 -08001135#if CONFIG_CB4X4
1136 case TX_2X2:
1137 sse = aom_sum_squares_2d_i16_c(diff, diff_stride, tx_size_wide[tx_size]);
1138 break;
1139#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001140 case TX_4X8:
Yaowu Xuf883b422016-08-30 14:01:10 -07001141 sse = aom_sum_squares_2d_i16(diff, diff_stride, 4) +
1142 aom_sum_squares_2d_i16(diff + 4 * diff_stride, diff_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001143 break;
1144 case TX_8X4:
Yaowu Xuf883b422016-08-30 14:01:10 -07001145 sse = aom_sum_squares_2d_i16(diff, diff_stride, 4) +
1146 aom_sum_squares_2d_i16(diff + 4, diff_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001147 break;
1148 case TX_8X16:
Yaowu Xuf883b422016-08-30 14:01:10 -07001149 sse = aom_sum_squares_2d_i16(diff, diff_stride, 8) +
1150 aom_sum_squares_2d_i16(diff + 8 * diff_stride, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001151 break;
1152 case TX_16X8:
Yaowu Xuf883b422016-08-30 14:01:10 -07001153 sse = aom_sum_squares_2d_i16(diff, diff_stride, 8) +
1154 aom_sum_squares_2d_i16(diff + 8, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001155 break;
1156 case TX_16X32:
Yaowu Xuf883b422016-08-30 14:01:10 -07001157 sse = aom_sum_squares_2d_i16(diff, diff_stride, 16) +
1158 aom_sum_squares_2d_i16(diff + 16 * diff_stride, diff_stride, 16);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001159 break;
1160 case TX_32X16:
Yaowu Xuf883b422016-08-30 14:01:10 -07001161 sse = aom_sum_squares_2d_i16(diff, diff_stride, 16) +
1162 aom_sum_squares_2d_i16(diff + 16, diff_stride, 16);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001163 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001164 default:
1165 assert(tx_size < TX_SIZES);
Jingning Hanc598cf82016-10-25 10:37:34 -07001166 sse = aom_sum_squares_2d_i16(diff, diff_stride, tx_size_wide[tx_size]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001167 break;
1168 }
1169 return sse;
1170}
1171
1172static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
1173 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
1174 struct rdcost_block_args *args = arg;
1175 MACROBLOCK *const x = args->x;
1176 MACROBLOCKD *const xd = &x->e_mbd;
1177 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -07001178 const AV1_COMMON *cm = &args->cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001179 int64_t rd1, rd2, rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001180 int coeff_ctx = combine_entropy_contexts(*(args->t_above + blk_col),
1181 *(args->t_left + blk_row));
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001182 RD_STATS this_rd_stats;
1183 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001184
1185 if (args->exit_early) return;
1186
1187 if (!is_inter_block(mbmi)) {
Urvang Joshi454280d2016-10-14 16:51:44 -07001188 struct encode_b_args b_args = {
Angie Chiangff6d8902016-10-21 11:02:09 -07001189 (AV1_COMMON *)cm, x, NULL, &mbmi->skip, args->t_above, args->t_left, 1
Yaowu Xuc27fc142016-08-22 16:08:15 -07001190 };
Yaowu Xuf883b422016-08-30 14:01:10 -07001191 av1_encode_block_intra(plane, block, blk_row, blk_col, plane_bsize, tx_size,
Urvang Joshi454280d2016-10-14 16:51:44 -07001192 &b_args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001193
1194 if (args->cpi->sf.use_transform_domain_distortion) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001195 dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size,
1196 &this_rd_stats.dist, &this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001197 } else {
1198 // Note that the encode block_intra call above already calls
1199 // inv_txfm_add, so we can't just call dist_block here.
1200 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Yaowu Xuf883b422016-08-30 14:01:10 -07001201 const aom_variance_fn_t variance = args->cpi->fn_ptr[tx_bsize].vf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001202
1203 const struct macroblock_plane *const p = &x->plane[plane];
1204 const struct macroblockd_plane *const pd = &xd->plane[plane];
1205
1206 const int src_stride = p->src.stride;
1207 const int dst_stride = pd->dst.stride;
Jingning Hanc598cf82016-10-25 10:37:34 -07001208 const int diff_stride = block_size_wide[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001209
Jingning Han81492262016-12-05 15:48:47 -08001210 const uint8_t *src =
1211 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
1212 const uint8_t *dst =
1213 &pd->dst
1214 .buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
1215 const int16_t *diff = &p->src_diff[(blk_row * diff_stride + blk_col)
1216 << tx_size_wide_log2[0]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001217
1218 unsigned int tmp;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001219 this_rd_stats.sse = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001220
Yaowu Xuf883b422016-08-30 14:01:10 -07001221#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001222 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001223 this_rd_stats.sse =
1224 ROUND_POWER_OF_TWO(this_rd_stats.sse, (xd->bd - 8) * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07001225#endif // CONFIG_AOM_HIGHBITDEPTH
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001226 this_rd_stats.sse = this_rd_stats.sse * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001227
1228 variance(src, src_stride, dst, dst_stride, &tmp);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001229 this_rd_stats.dist = (int64_t)tmp * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001230 }
1231 } else {
1232// full forward transform and quantization
1233#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001234 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1235 coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001236#else
Angie Chiangff6d8902016-10-21 11:02:09 -07001237 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001238 coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001239#endif // CONFIG_NEW_QUANT
Yushin Cho721868c2016-11-14 16:04:33 +09001240#if !CONFIG_PVQ
Yaowu Xufd873802016-12-12 09:37:54 -08001241 if (x->plane[plane].eobs[block] && !xd->lossless[mbmi->segment_id]) {
1242 args->t_above[blk_col] = args->t_left[blk_row] =
1243 (av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx) > 0);
1244 } else {
1245 args->t_above[blk_col] = (x->plane[plane].eobs[block] > 0);
1246 args->t_left[blk_row] = (x->plane[plane].eobs[block] > 0);
1247 }
Yushin Cho721868c2016-11-14 16:04:33 +09001248#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001249 dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size,
1250 &this_rd_stats.dist, &this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001251 }
1252
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001253 rd = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001254 if (args->this_rd + rd > args->best_rd) {
1255 args->exit_early = 1;
1256 return;
1257 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001258#if !CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001259 this_rd_stats.rate = rate_block(plane, block, coeff_ctx, tx_size, args);
Angie Chiang3963d632016-11-10 18:41:40 -08001260#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08001261 av1_update_txb_coeff_cost(&this_rd_stats, plane, tx_size, blk_row, blk_col,
1262 this_rd_stats.rate);
1263#endif
Angie Chiang3963d632016-11-10 18:41:40 -08001264
Yushin Cho77bba8d2016-11-04 16:36:56 -07001265#else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001266 this_rd_stats.rate = x->rate;
Yushin Cho721868c2016-11-14 16:04:33 +09001267 args->t_above[blk_col] = !x->pvq_skip[plane];
1268 args->t_left[blk_row] = !x->pvq_skip[plane];
Yushin Cho77bba8d2016-11-04 16:36:56 -07001269#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001270 rd1 = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate, this_rd_stats.dist);
1271 rd2 = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001272
1273 // TODO(jingning): temporarily enabled only for luma component
Yaowu Xuf883b422016-08-30 14:01:10 -07001274 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001275
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001276#if !CONFIG_PVQ
1277 this_rd_stats.skip &= !x->plane[plane].eobs[block];
1278#else
1279 this_rd_stats.skip &= x->pvq_skip[plane];
1280#endif
1281 av1_merge_rd_stats(&args->rd_stats, &this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001282 args->this_rd += rd;
1283
1284 if (args->this_rd > args->best_rd) {
1285 args->exit_early = 1;
1286 return;
1287 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001288}
1289
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001290static void txfm_rd_in_plane(MACROBLOCK *x, const AV1_COMP *cpi,
1291 RD_STATS *rd_stats, int64_t ref_best_rd, int plane,
1292 BLOCK_SIZE bsize, TX_SIZE tx_size,
1293 int use_fast_coef_casting) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001294 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001295 MACROBLOCKD *const xd = &x->e_mbd;
1296 const struct macroblockd_plane *const pd = &xd->plane[plane];
1297 TX_TYPE tx_type;
1298 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001299 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001300 args.x = x;
1301 args.cpi = cpi;
1302 args.best_rd = ref_best_rd;
1303 args.use_fast_coef_costing = use_fast_coef_casting;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001304 av1_init_rd_stats(&args.rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001305
1306 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1307
Yaowu Xuf883b422016-08-30 14:01:10 -07001308 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001309
1310 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001311 args.scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07001312 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001313
Yaowu Xuf883b422016-08-30 14:01:10 -07001314 av1_foreach_transformed_block_in_plane(xd, bsize, plane, block_rd_txfm,
1315 &args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001316 if (args.exit_early) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001317 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001318 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001319 *rd_stats = args.rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001320 }
1321}
1322
1323#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001324void av1_txfm_rd_in_plane_supertx(MACROBLOCK *x, const AV1_COMP *cpi, int *rate,
1325 int64_t *distortion, int *skippable,
1326 int64_t *sse, int64_t ref_best_rd, int plane,
1327 BLOCK_SIZE bsize, TX_SIZE tx_size,
1328 int use_fast_coef_casting) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001329 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001330 MACROBLOCKD *const xd = &x->e_mbd;
1331 const struct macroblockd_plane *const pd = &xd->plane[plane];
1332 struct rdcost_block_args args;
1333 TX_TYPE tx_type;
1334
Yaowu Xuf883b422016-08-30 14:01:10 -07001335 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001336 args.cpi = cpi;
1337 args.x = x;
1338 args.best_rd = ref_best_rd;
1339 args.use_fast_coef_costing = use_fast_coef_casting;
1340
1341#if CONFIG_EXT_TX
1342 assert(tx_size < TX_SIZES);
1343#endif // CONFIG_EXT_TX
1344
1345 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1346
Yaowu Xuf883b422016-08-30 14:01:10 -07001347 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001348
1349 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001350 args.scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07001351 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001352
1353 block_rd_txfm(plane, 0, 0, 0, get_plane_block_size(bsize, pd), tx_size,
1354 &args);
1355
1356 if (args.exit_early) {
1357 *rate = INT_MAX;
1358 *distortion = INT64_MAX;
1359 *sse = INT64_MAX;
1360 *skippable = 0;
1361 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001362 *distortion = args.rd_stats.dist;
1363 *rate = args.rd_stats.rate;
1364 *sse = args.rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001365 *skippable = !x->plane[plane].eobs[0];
1366 }
1367}
1368#endif // CONFIG_SUPERTX
1369
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001370static int64_t txfm_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
1371 RD_STATS *rd_stats, int64_t ref_best_rd, BLOCK_SIZE bs,
1372 TX_TYPE tx_type, int tx_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07001373 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001374 MACROBLOCKD *const xd = &x->e_mbd;
1375 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1376 int64_t rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001377 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001378 int s0, s1;
1379 const int is_inter = is_inter_block(mbmi);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001380
Yaowu Xuc27fc142016-08-22 16:08:15 -07001381 const int tx_size_cat =
1382 is_inter ? inter_tx_size_cat_lookup[bs] : intra_tx_size_cat_lookup[bs];
1383 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
Jingning Hanb0a71302016-10-25 16:28:49 -07001384 const int depth = tx_size_to_depth(coded_tx_size);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001385 const int tx_select =
1386 cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8;
1387 const int tx_size_ctx = tx_select ? get_tx_size_context(xd) : 0;
1388 const int r_tx_size =
1389 tx_select ? cpi->tx_size_cost[tx_size_cat][tx_size_ctx][depth] : 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001390
1391 assert(skip_prob > 0);
1392#if CONFIG_EXT_TX && CONFIG_RECT_TX
1393 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed_bsize(bs)));
1394#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1395
Yaowu Xuf883b422016-08-30 14:01:10 -07001396 s0 = av1_cost_bit(skip_prob, 0);
1397 s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001398
1399 mbmi->tx_type = tx_type;
1400 mbmi->tx_size = tx_size;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001401 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001402 cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001403 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001404#if CONFIG_EXT_TX
1405 if (get_ext_tx_types(tx_size, bs, is_inter) > 1 &&
1406 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
1407 const int ext_tx_set = get_ext_tx_set(tx_size, bs, is_inter);
1408 if (is_inter) {
1409 if (ext_tx_set > 0)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001410 rd_stats->rate +=
clang-format67948d32016-09-07 22:40:40 -07001411 cpi->inter_tx_type_costs[ext_tx_set][txsize_sqr_map[mbmi->tx_size]]
1412 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001413 } else {
1414 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001415 rd_stats->rate += cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size]
1416 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001417 }
1418 }
1419#else
1420 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1421 !FIXED_TX_TYPE) {
1422 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001423 rd_stats->rate += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001424 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001425 rd_stats->rate +=
1426 cpi->intra_tx_type_costs[mbmi->tx_size]
1427 [intra_mode_to_tx_type_context[mbmi->mode]]
1428 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001429 }
1430 }
1431#endif // CONFIG_EXT_TX
1432
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001433 if (rd_stats->skip) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001434 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001435 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001436 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001437 rd = RDCOST(x->rdmult, x->rddiv, s1 + r_tx_size * tx_select,
1438 rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001439 }
1440 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001441 rd = RDCOST(x->rdmult, x->rddiv,
1442 rd_stats->rate + s0 + r_tx_size * tx_select, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001443 }
1444
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001445 if (tx_select) rd_stats->rate += r_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001446
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001447 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1448 !(rd_stats->skip))
1449 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001450
1451 return rd;
1452}
1453
Urvang Joshi52648442016-10-13 17:27:51 -07001454static int64_t choose_tx_size_fix_type(const AV1_COMP *const cpi, BLOCK_SIZE bs,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001455 MACROBLOCK *x, RD_STATS *rd_stats,
1456 int64_t ref_best_rd, TX_TYPE tx_type,
Yushin Cho55711e62016-11-10 18:49:24 -08001457#if CONFIG_PVQ
1458 od_rollback_buffer buf,
1459#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001460 int prune) {
Urvang Joshi52648442016-10-13 17:27:51 -07001461 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001462 MACROBLOCKD *const xd = &x->e_mbd;
1463 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001464 int64_t rd = INT64_MAX;
1465 int n;
1466 int start_tx, end_tx;
1467 int64_t best_rd = INT64_MAX, last_rd = INT64_MAX;
1468 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
1469 TX_SIZE best_tx_size = max_tx_size;
1470 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
1471 const int is_inter = is_inter_block(mbmi);
1472#if CONFIG_EXT_TX
1473#if CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001474 int evaluate_rect_tx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001475#endif // CONFIG_RECT_TX
1476 int ext_tx_set;
1477#endif // CONFIG_EXT_TX
1478
1479 if (tx_select) {
1480#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001481 evaluate_rect_tx = is_rect_tx_allowed(xd, mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001482#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1483 start_tx = max_tx_size;
Debargha Mukherjee153e1f82016-11-17 09:59:14 -08001484 end_tx = (max_tx_size >= TX_32X32) ? TX_8X8 : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001485 } else {
1486 const TX_SIZE chosen_tx_size =
1487 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
1488#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001489 evaluate_rect_tx = is_rect_tx(chosen_tx_size);
1490 assert(IMPLIES(evaluate_rect_tx, is_rect_tx_allowed(xd, mbmi)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001491#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1492 start_tx = chosen_tx_size;
1493 end_tx = chosen_tx_size;
1494 }
1495
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001496 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001497
1498 mbmi->tx_type = tx_type;
1499
1500#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001501 if (evaluate_rect_tx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001502 const TX_SIZE rect_tx_size = max_txsize_rect_lookup[bs];
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001503 RD_STATS this_rd_stats;
Urvang Joshi368fbc92016-10-17 16:31:34 -07001504 ext_tx_set = get_ext_tx_set(rect_tx_size, bs, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001505 if (ext_tx_used_inter[ext_tx_set][tx_type]) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001506 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001507 rect_tx_size);
1508 best_tx_size = rect_tx_size;
1509 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001510 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001511 }
1512 }
1513#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1514
1515 last_rd = INT64_MAX;
1516 for (n = start_tx; n >= end_tx; --n) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001517 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001518#if CONFIG_EXT_TX && CONFIG_RECT_TX
1519 if (is_rect_tx(n)) break;
1520#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1521 if (FIXED_TX_TYPE && tx_type != get_default_tx_type(0, xd, 0, n)) continue;
1522 if (!is_inter && x->use_default_intra_tx_type &&
1523 tx_type != get_default_tx_type(0, xd, 0, n))
1524 continue;
1525 if (is_inter && x->use_default_inter_tx_type &&
1526 tx_type != get_default_tx_type(0, xd, 0, n))
1527 continue;
Debargha Mukherjee153e1f82016-11-17 09:59:14 -08001528 if (max_tx_size >= TX_32X32 && n == TX_4X4) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001529#if CONFIG_EXT_TX
1530 ext_tx_set = get_ext_tx_set(n, bs, is_inter);
1531 if (is_inter) {
1532 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
1533 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1534 if (!do_tx_type_search(tx_type, prune)) continue;
1535 }
1536 } else {
1537 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1538 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
1539 }
1540 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
1541 }
1542#else // CONFIG_EXT_TX
1543 if (n >= TX_32X32 && tx_type != DCT_DCT) continue;
1544 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
1545 !do_tx_type_search(tx_type, prune))
1546 continue;
1547#endif // CONFIG_EXT_TX
1548
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001549 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type, n);
Yushin Cho55711e62016-11-10 18:49:24 -08001550#if CONFIG_PVQ
1551 od_encode_rollback(&x->daala_enc, &buf);
1552#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001553 // Early termination in transform size search.
1554 if (cpi->sf.tx_size_search_breakout &&
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001555 (rd == INT64_MAX ||
1556 (this_rd_stats.skip == 1 && tx_type != DCT_DCT && n < start_tx) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07001557 (n < (int)max_tx_size && rd > last_rd)))
1558 break;
1559
1560 last_rd = rd;
1561 if (rd < best_rd) {
1562 best_tx_size = n;
1563 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001564 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001565 }
1566 }
1567 mbmi->tx_size = best_tx_size;
1568
1569 return best_rd;
1570}
1571
1572#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07001573static int64_t estimate_yrd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bs,
1574 MACROBLOCK *x, int *r, int64_t *d, int *s,
1575 int64_t *sse, int64_t ref_best_rd) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001576 RD_STATS rd_stats;
1577 int64_t rd = txfm_yrd(cpi, x, &rd_stats, ref_best_rd, bs, DCT_DCT,
1578 max_txsize_lookup[bs]);
1579 *r = rd_stats.rate;
1580 *d = rd_stats.dist;
1581 *s = rd_stats.skip;
1582 *sse = rd_stats.sse;
1583 return rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001584}
1585#endif // CONFIG_EXT_INTER
1586
Urvang Joshi52648442016-10-13 17:27:51 -07001587static void choose_largest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001588 RD_STATS *rd_stats, int64_t ref_best_rd,
Urvang Joshi52648442016-10-13 17:27:51 -07001589 BLOCK_SIZE bs) {
1590 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001591 MACROBLOCKD *const xd = &x->e_mbd;
1592 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1593 TX_TYPE tx_type, best_tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001594 int64_t this_rd, best_rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001595 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
1596 int s0 = av1_cost_bit(skip_prob, 0);
1597 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001598 const int is_inter = is_inter_block(mbmi);
1599 int prune = 0;
1600#if CONFIG_EXT_TX
1601 int ext_tx_set;
1602#endif // CONFIG_EXT_TX
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001603 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001604
1605 mbmi->tx_size = tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
Jingning Hane67b38a2016-11-04 10:30:00 -07001606#if CONFIG_VAR_TX
1607 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
1608#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001609#if CONFIG_EXT_TX
1610 ext_tx_set = get_ext_tx_set(mbmi->tx_size, bs, is_inter);
1611#endif // CONFIG_EXT_TX
1612
1613 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
1614#if CONFIG_EXT_TX
1615 prune = prune_tx_types(cpi, bs, x, xd, ext_tx_set);
1616#else
1617 prune = prune_tx_types(cpi, bs, x, xd, 0);
1618#endif
1619#if CONFIG_EXT_TX
1620 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1 &&
1621 !xd->lossless[mbmi->segment_id]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07001622#if CONFIG_PVQ
1623 od_rollback_buffer pre_buf, post_buf;
1624
1625 od_encode_checkpoint(&x->daala_enc, &pre_buf);
1626 od_encode_checkpoint(&x->daala_enc, &post_buf);
1627#endif
1628
1629 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001630 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001631 if (is_inter) {
1632 if (x->use_default_inter_tx_type &&
1633 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1634 continue;
1635 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
1636 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1637 if (!do_tx_type_search(tx_type, prune)) continue;
1638 }
1639 } else {
1640 if (x->use_default_intra_tx_type &&
1641 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1642 continue;
1643 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1644 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
1645 }
1646 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
1647 }
1648
1649 mbmi->tx_type = tx_type;
1650
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001651 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001652 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001653#if CONFIG_PVQ
1654 od_encode_rollback(&x->daala_enc, &pre_buf);
1655#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001656 if (this_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001657 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1) {
1658 if (is_inter) {
1659 if (ext_tx_set > 0)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001660 this_rd_stats.rate +=
1661 cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size]
1662 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001663 } else {
1664 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001665 this_rd_stats.rate +=
1666 cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->mode]
1667 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001668 }
1669 }
1670
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001671 if (this_rd_stats.skip)
1672 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001673 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001674 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
1675 this_rd_stats.dist);
1676 if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] &&
1677 !this_rd_stats.skip)
1678 this_rd =
1679 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001680
1681 if (this_rd < best_rd) {
1682 best_rd = this_rd;
1683 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001684 *rd_stats = this_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001685#if CONFIG_PVQ
1686 od_encode_checkpoint(&x->daala_enc, &post_buf);
1687#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001688 }
1689 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001690#if CONFIG_PVQ
1691 od_encode_rollback(&x->daala_enc, &post_buf);
1692#endif
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001693 } else {
1694 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001695 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
1696 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001697 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001698#else // CONFIG_EXT_TX
1699 if (mbmi->tx_size < TX_32X32 && !xd->lossless[mbmi->segment_id]) {
1700 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001701 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001702 if (!is_inter && x->use_default_intra_tx_type &&
1703 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1704 continue;
1705 if (is_inter && x->use_default_inter_tx_type &&
1706 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1707 continue;
1708 mbmi->tx_type = tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001709 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001710 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001711 if (this_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001712 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001713 this_rd_stats.rate +=
1714 cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001715 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
1716 !do_tx_type_search(tx_type, prune))
1717 continue;
1718 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001719 this_rd_stats.rate +=
1720 cpi->intra_tx_type_costs[mbmi->tx_size]
1721 [intra_mode_to_tx_type_context[mbmi->mode]]
1722 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001723 }
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001724 if (this_rd_stats.skip)
1725 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001726 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001727 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
1728 this_rd_stats.dist);
1729 if (is_inter && !xd->lossless[mbmi->segment_id] && !this_rd_stats.skip)
1730 this_rd =
1731 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001732
1733 if (this_rd < best_rd) {
1734 best_rd = this_rd;
1735 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001736 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001737 }
1738 }
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001739 } else {
1740 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001741 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
1742 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001743 }
1744#endif // CONFIG_EXT_TX
1745 mbmi->tx_type = best_tx_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001746}
1747
Urvang Joshi52648442016-10-13 17:27:51 -07001748static void choose_smallest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001749 RD_STATS *rd_stats, int64_t ref_best_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001750 BLOCK_SIZE bs) {
1751 MACROBLOCKD *const xd = &x->e_mbd;
1752 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1753
1754 mbmi->tx_size = TX_4X4;
1755 mbmi->tx_type = DCT_DCT;
Jingning Hane67b38a2016-11-04 10:30:00 -07001756#if CONFIG_VAR_TX
1757 mbmi->min_tx_size = get_min_tx_size(TX_4X4);
1758#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001759
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001760 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
1761 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001762}
1763
Urvang Joshi52648442016-10-13 17:27:51 -07001764static void choose_tx_size_type_from_rd(const AV1_COMP *const cpi,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001765 MACROBLOCK *x, RD_STATS *rd_stats,
1766 int64_t ref_best_rd, BLOCK_SIZE bs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001767 MACROBLOCKD *const xd = &x->e_mbd;
1768 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001769 int64_t rd = INT64_MAX;
1770 int64_t best_rd = INT64_MAX;
1771 TX_SIZE best_tx = max_txsize_lookup[bs];
1772 const int is_inter = is_inter_block(mbmi);
1773 TX_TYPE tx_type, best_tx_type = DCT_DCT;
1774 int prune = 0;
1775
Yushin Cho77bba8d2016-11-04 16:36:56 -07001776#if CONFIG_PVQ
1777 od_rollback_buffer buf;
1778#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001779 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
1780 // passing -1 in for tx_type indicates that all 1D
1781 // transforms should be considered for pruning
1782 prune = prune_tx_types(cpi, bs, x, xd, -1);
1783
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001784 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001785
Yushin Cho77bba8d2016-11-04 16:36:56 -07001786#if CONFIG_PVQ
1787 od_encode_checkpoint(&x->daala_enc, &buf);
1788#endif
1789
Yaowu Xuc27fc142016-08-22 16:08:15 -07001790 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001791 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001792#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07001793 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001794#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001795 rd = choose_tx_size_fix_type(cpi, bs, x, &this_rd_stats, ref_best_rd,
Yushin Cho55711e62016-11-10 18:49:24 -08001796 tx_type,
1797#if CONFIG_PVQ
1798 buf,
1799#endif
1800 prune);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001801 if (rd < best_rd) {
1802 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001803 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001804 best_tx_type = tx_type;
1805 best_tx = mbmi->tx_size;
1806 }
1807 }
1808
1809 mbmi->tx_size = best_tx;
1810 mbmi->tx_type = best_tx_type;
1811
Jingning Hane67b38a2016-11-04 10:30:00 -07001812#if CONFIG_VAR_TX
1813 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
1814#endif
1815
Yaowu Xuc27fc142016-08-22 16:08:15 -07001816#if !CONFIG_EXT_TX
1817 if (mbmi->tx_size >= TX_32X32) assert(mbmi->tx_type == DCT_DCT);
1818#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07001819#if CONFIG_PVQ
Yushin Cho403618e2016-11-09 10:45:32 -08001820 if (best_rd != INT64_MAX) {
1821 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, best_tx,
Yushin Cho77bba8d2016-11-04 16:36:56 -07001822 cpi->sf.use_fast_coef_costing);
Yushin Cho05f540a2016-11-08 22:12:51 -08001823 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001824#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001825}
1826
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001827static void super_block_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
1828 RD_STATS *rd_stats, BLOCK_SIZE bs,
1829 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001830 MACROBLOCKD *xd = &x->e_mbd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001831 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001832
1833 assert(bs == xd->mi[0]->mbmi.sb_type);
1834
1835 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001836 choose_smallest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001837 } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001838 choose_largest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001839 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001840 choose_tx_size_type_from_rd(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001841 }
1842}
1843
1844static int conditional_skipintra(PREDICTION_MODE mode,
1845 PREDICTION_MODE best_intra_mode) {
1846 if (mode == D117_PRED && best_intra_mode != V_PRED &&
1847 best_intra_mode != D135_PRED)
1848 return 1;
1849 if (mode == D63_PRED && best_intra_mode != V_PRED &&
1850 best_intra_mode != D45_PRED)
1851 return 1;
1852 if (mode == D207_PRED && best_intra_mode != H_PRED &&
1853 best_intra_mode != D45_PRED)
1854 return 1;
1855 if (mode == D153_PRED && best_intra_mode != H_PRED &&
1856 best_intra_mode != D135_PRED)
1857 return 1;
1858 return 0;
1859}
1860
Urvang Joshib100db72016-10-12 16:28:56 -07001861#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001862static int rd_pick_palette_intra_sby(
Urvang Joshi52648442016-10-13 17:27:51 -07001863 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int palette_ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001864 int dc_mode_cost, PALETTE_MODE_INFO *palette_mode_info,
1865 uint8_t *best_palette_color_map, TX_SIZE *best_tx, TX_TYPE *best_tx_type,
1866 PREDICTION_MODE *mode_selected, int64_t *best_rd) {
1867 int rate_overhead = 0;
1868 MACROBLOCKD *const xd = &x->e_mbd;
1869 MODE_INFO *const mic = xd->mi[0];
Jingning Hanae5cfde2016-11-30 12:01:44 -08001870 const int rows = block_size_high[bsize];
1871 const int cols = block_size_wide[bsize];
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001872 int this_rate, colors, n;
1873 RD_STATS tokenonly_rd_stats;
1874 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001875 const int src_stride = x->plane[0].src.stride;
1876 const uint8_t *const src = x->plane[0].src.buf;
1877
1878 assert(cpi->common.allow_screen_content_tools);
1879
Yaowu Xuf883b422016-08-30 14:01:10 -07001880#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001881 if (cpi->common.use_highbitdepth)
Yaowu Xuf883b422016-08-30 14:01:10 -07001882 colors = av1_count_colors_highbd(src, src_stride, rows, cols,
1883 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001884 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001885#endif // CONFIG_AOM_HIGHBITDEPTH
1886 colors = av1_count_colors(src, src_stride, rows, cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001887 palette_mode_info->palette_size[0] = 0;
hui su5db97432016-10-14 16:10:14 -07001888#if CONFIG_FILTER_INTRA
1889 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0;
1890#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07001891
1892 if (colors > 1 && colors <= 64) {
1893 int r, c, i, j, k;
1894 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07001895 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001896 float *const data = x->palette_buffer->kmeans_data_buf;
1897 float centroids[PALETTE_MAX_SIZE];
1898 uint8_t *const color_map = xd->plane[0].color_index_map;
1899 float lb, ub, val;
1900 MB_MODE_INFO *const mbmi = &mic->mbmi;
1901 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuf883b422016-08-30 14:01:10 -07001902#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001903 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
1904 if (cpi->common.use_highbitdepth)
1905 lb = ub = src16[0];
1906 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001907#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001908 lb = ub = src[0];
1909
Yaowu Xuf883b422016-08-30 14:01:10 -07001910#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001911 if (cpi->common.use_highbitdepth) {
1912 for (r = 0; r < rows; ++r) {
1913 for (c = 0; c < cols; ++c) {
1914 val = src16[r * src_stride + c];
1915 data[r * cols + c] = val;
1916 if (val < lb)
1917 lb = val;
1918 else if (val > ub)
1919 ub = val;
1920 }
1921 }
1922 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001923#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001924 for (r = 0; r < rows; ++r) {
1925 for (c = 0; c < cols; ++c) {
1926 val = src[r * src_stride + c];
1927 data[r * cols + c] = val;
1928 if (val < lb)
1929 lb = val;
1930 else if (val > ub)
1931 ub = val;
1932 }
1933 }
Yaowu Xuf883b422016-08-30 14:01:10 -07001934#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001935 }
Yaowu Xuf883b422016-08-30 14:01:10 -07001936#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001937
1938 mbmi->mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07001939#if CONFIG_FILTER_INTRA
1940 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
1941#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07001942
1943 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return 0;
1944
1945 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
1946 --n) {
1947 for (i = 0; i < n; ++i)
1948 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
Yaowu Xuf883b422016-08-30 14:01:10 -07001949 av1_k_means(data, centroids, color_map, rows * cols, n, 1, max_itr);
1950 k = av1_remove_duplicates(centroids, n);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001951
Yaowu Xuf883b422016-08-30 14:01:10 -07001952#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001953 if (cpi->common.use_highbitdepth)
1954 for (i = 0; i < k; ++i)
1955 pmi->palette_colors[i] =
1956 clip_pixel_highbd((int)centroids[i], cpi->common.bit_depth);
1957 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001958#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001959 for (i = 0; i < k; ++i)
1960 pmi->palette_colors[i] = clip_pixel((int)centroids[i]);
1961 pmi->palette_size[0] = k;
1962
Yaowu Xuf883b422016-08-30 14:01:10 -07001963 av1_calc_indices(data, centroids, color_map, rows * cols, k, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001964
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001965 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
1966 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001967
1968 this_rate =
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001969 tokenonly_rd_stats.rate + dc_mode_cost +
Yaowu Xuf883b422016-08-30 14:01:10 -07001970 cpi->common.bit_depth * k * av1_cost_bit(128, 0) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07001971 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - 2] +
1972 write_uniform_cost(k, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07001973 av1_cost_bit(
1974 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07001975 1);
1976 for (i = 0; i < rows; ++i) {
1977 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07001978 int color_idx;
1979 const int color_ctx = av1_get_palette_color_context(
1980 color_map, cols, i, j, k, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001981 assert(color_idx >= 0 && color_idx < k);
1982 this_rate += cpi->palette_y_color_cost[k - 2][color_ctx][color_idx];
1983 }
1984 }
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001985 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001986
1987 if (this_rd < *best_rd) {
1988 *best_rd = this_rd;
1989 *palette_mode_info = *pmi;
1990 memcpy(best_palette_color_map, color_map,
1991 rows * cols * sizeof(color_map[0]));
1992 *mode_selected = DC_PRED;
1993 *best_tx = mbmi->tx_size;
1994 *best_tx_type = mbmi->tx_type;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001995 rate_overhead = this_rate - tokenonly_rd_stats.rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001996 }
1997 }
1998 }
1999 return rate_overhead;
2000}
Urvang Joshib100db72016-10-12 16:28:56 -07002001#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002002
Urvang Joshi52648442016-10-13 17:27:51 -07002003static int64_t rd_pick_intra4x4block(
2004 const AV1_COMP *const cpi, MACROBLOCK *x, int row, int col,
2005 PREDICTION_MODE *best_mode, const int *bmode_costs, ENTROPY_CONTEXT *a,
2006 ENTROPY_CONTEXT *l, int *bestrate, int *bestratey, int64_t *bestdistortion,
2007 BLOCK_SIZE bsize, int *y_skip, int64_t rd_thresh) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07002008#if !CONFIG_PVQ
Angie Chiang22ba7512016-10-20 17:10:33 -07002009 const AV1_COMMON *const cm = &cpi->common;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002010#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002011 PREDICTION_MODE mode;
2012 MACROBLOCKD *const xd = &x->e_mbd;
2013 int64_t best_rd = rd_thresh;
2014 struct macroblock_plane *p = &x->plane[0];
2015 struct macroblockd_plane *pd = &xd->plane[0];
2016 const int src_stride = p->src.stride;
2017 const int dst_stride = pd->dst.stride;
2018 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
2019 uint8_t *dst_init = &pd->dst.buf[row * 4 * src_stride + col * 4];
Jingning Han276c2942016-12-05 12:37:02 -08002020#if CONFIG_CB4X4
2021 // TODO(jingning): This is a temporal change. The whole function should be
2022 // out when cb4x4 is enabled.
2023 ENTROPY_CONTEXT ta[4], tempa[4];
2024 ENTROPY_CONTEXT tl[4], templ[4];
2025#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07002026 ENTROPY_CONTEXT ta[2], tempa[2];
2027 ENTROPY_CONTEXT tl[2], templ[2];
Jingning Han276c2942016-12-05 12:37:02 -08002028#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002029 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2030 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2031 int idx, idy;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002032 int best_can_skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002033 uint8_t best_dst[8 * 8];
Yaowu Xuf883b422016-08-30 14:01:10 -07002034#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002035 uint16_t best_dst16[8 * 8];
2036#endif
2037
Yushin Cho77bba8d2016-11-04 16:36:56 -07002038#if CONFIG_PVQ
2039 od_rollback_buffer pre_buf, post_buf;
2040 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2041 od_encode_checkpoint(&x->daala_enc, &post_buf);
2042#endif
2043
Yaowu Xuc27fc142016-08-22 16:08:15 -07002044 memcpy(ta, a, num_4x4_blocks_wide * sizeof(a[0]));
2045 memcpy(tl, l, num_4x4_blocks_high * sizeof(l[0]));
2046 xd->mi[0]->mbmi.tx_size = TX_4X4;
Urvang Joshib100db72016-10-12 16:28:56 -07002047#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002048 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002049#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002050
Yaowu Xuf883b422016-08-30 14:01:10 -07002051#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002052 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2053 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2054 int64_t this_rd;
2055 int ratey = 0;
2056 int64_t distortion = 0;
2057 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002058 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002059
2060 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode))) continue;
2061
2062 // Only do the oblique modes if the best so far is
2063 // one of the neighboring directional modes
2064 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2065 if (conditional_skipintra(mode, *best_mode)) continue;
2066 }
2067
2068 memcpy(tempa, ta, num_4x4_blocks_wide * sizeof(ta[0]));
2069 memcpy(templ, tl, num_4x4_blocks_high * sizeof(tl[0]));
2070
2071 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
2072 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
2073 const int block = (row + idy) * 2 + (col + idx);
2074 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2075 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
2076 int16_t *const src_diff =
Yaowu Xuf883b422016-08-30 14:01:10 -07002077 av1_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002078 xd->mi[0]->bmi[block].as_mode = mode;
Jingning Hanc4c99da2016-10-24 10:27:28 -07002079 av1_predict_intra_block(xd, pd->width, pd->height, TX_4X4, mode, dst,
2080 dst_stride, dst, dst_stride, col + idx,
2081 row + idy, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07002082 aom_highbd_subtract_block(4, 4, src_diff, 8, src, src_stride, dst,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002083 dst_stride, xd->bd);
2084 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
2085 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002086 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002087 const int coeff_ctx =
2088 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002089#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002090 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2091 TX_4X4, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002092#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002093 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002094 TX_4X4, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002095#endif // CONFIG_NEW_QUANT
Angie Chiang22ba7512016-10-20 17:10:33 -07002096 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002097 scan_order->scan, scan_order->neighbors,
2098 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002099 *(tempa + idx) = !(p->eobs[block] == 0);
2100 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002101 can_skip &= (p->eobs[block] == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002102 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2103 goto next_highbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07002104 av1_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2105 dst_stride, p->eobs[block], xd->bd,
2106 DCT_DCT, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002107 } else {
2108 int64_t dist;
2109 unsigned int tmp;
2110 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002111 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002112 const int coeff_ctx =
2113 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
2114#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002115 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2116 TX_4X4, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002117#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002118 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002119 TX_4X4, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002120#endif // CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002121 av1_optimize_b(cm, x, 0, block, TX_4X4, coeff_ctx);
Angie Chiang22ba7512016-10-20 17:10:33 -07002122 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002123 scan_order->scan, scan_order->neighbors,
2124 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002125 *(tempa + idx) = !(p->eobs[block] == 0);
2126 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002127 can_skip &= (p->eobs[block] == 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07002128 av1_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2129 dst_stride, p->eobs[block], xd->bd,
2130 tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002131 cpi->fn_ptr[BLOCK_4X4].vf(src, src_stride, dst, dst_stride, &tmp);
2132 dist = (int64_t)tmp << 4;
2133 distortion += dist;
2134 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2135 goto next_highbd;
2136 }
2137 }
2138 }
2139
2140 rate += ratey;
2141 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2142
2143 if (this_rd < best_rd) {
2144 *bestrate = rate;
2145 *bestratey = ratey;
2146 *bestdistortion = distortion;
2147 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002148 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002149 *best_mode = mode;
2150 memcpy(a, tempa, num_4x4_blocks_wide * sizeof(tempa[0]));
2151 memcpy(l, templ, num_4x4_blocks_high * sizeof(templ[0]));
2152 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
2153 memcpy(best_dst16 + idy * 8,
2154 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
2155 num_4x4_blocks_wide * 4 * sizeof(uint16_t));
2156 }
2157 }
2158 next_highbd : {}
2159 }
2160
2161 if (best_rd >= rd_thresh) return best_rd;
2162
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002163 if (y_skip) *y_skip &= best_can_skip;
2164
Yaowu Xuc27fc142016-08-22 16:08:15 -07002165 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
2166 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
2167 best_dst16 + idy * 8, num_4x4_blocks_wide * 4 * sizeof(uint16_t));
2168 }
2169
2170 return best_rd;
2171 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002172#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002173
Yushin Cho77bba8d2016-11-04 16:36:56 -07002174#if CONFIG_PVQ
2175 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2176#endif
2177
Yaowu Xuc27fc142016-08-22 16:08:15 -07002178 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2179 int64_t this_rd;
2180 int ratey = 0;
2181 int64_t distortion = 0;
2182 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002183 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002184
2185 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode))) continue;
2186
2187 // Only do the oblique modes if the best so far is
2188 // one of the neighboring directional modes
2189 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2190 if (conditional_skipintra(mode, *best_mode)) continue;
2191 }
2192
2193 memcpy(tempa, ta, num_4x4_blocks_wide * sizeof(ta[0]));
2194 memcpy(templ, tl, num_4x4_blocks_high * sizeof(tl[0]));
2195
2196 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
2197 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
Jingning Hand1097fc2016-12-06 10:55:34 -08002198 int block = (row + idy) * 2 + (col + idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002199 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2200 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Yushin Cho77bba8d2016-11-04 16:36:56 -07002201#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002202 int16_t *const src_diff =
Yaowu Xuf883b422016-08-30 14:01:10 -07002203 av1_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002204#else
2205 int lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
2206 const int diff_stride = 8;
2207 tran_low_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block);
2208 tran_low_t *const dqcoeff = BLOCK_OFFSET(xd->plane[0].dqcoeff, block);
2209 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
2210 int16_t *pred = &pd->pred[4 * (row * diff_stride + col)];
2211 int16_t *src_int16 = &p->src_int16[4 * (row * diff_stride + col)];
2212 int i, j, tx_blk_size;
2213 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
2214 int rate_pvq;
2215 int skip;
2216#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002217 xd->mi[0]->bmi[block].as_mode = mode;
Jingning Hanc4c99da2016-10-24 10:27:28 -07002218 av1_predict_intra_block(xd, pd->width, pd->height, TX_4X4, mode, dst,
Jingning Hand1097fc2016-12-06 10:55:34 -08002219 dst_stride, dst, dst_stride,
2220#if CONFIG_CB4X4
2221 2 * (col + idx), 2 * (row + idy),
2222#else
2223 col + idx, row + idy,
2224#endif
2225 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002226#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -07002227 aom_subtract_block(4, 4, src_diff, 8, src, src_stride, dst, dst_stride);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002228#else
2229 if (lossless) tx_type = DCT_DCT;
2230 // transform block size in pixels
2231 tx_blk_size = 4;
2232
2233 // copy uint8 orig and predicted block to int16 buffer
2234 // in order to use existing VP10 transform functions
2235 for (j = 0; j < tx_blk_size; j++)
2236 for (i = 0; i < tx_blk_size; i++) {
2237 src_int16[diff_stride * j + i] = src[src_stride * j + i];
2238 pred[diff_stride * j + i] = dst[dst_stride * j + i];
2239 }
2240 {
2241 FWD_TXFM_PARAM fwd_txfm_param;
2242 fwd_txfm_param.tx_type = tx_type;
2243 fwd_txfm_param.tx_size = TX_4X4;
2244 fwd_txfm_param.fwd_txfm_opt = FWD_TXFM_OPT_NORMAL;
2245 fwd_txfm_param.rd_transform = 0;
2246 fwd_txfm_param.lossless = lossless;
2247 fwd_txfm(src_int16, coeff, diff_stride, &fwd_txfm_param);
2248 fwd_txfm(pred, ref_coeff, diff_stride, &fwd_txfm_param);
2249 }
2250#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002251
2252 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07002253#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002254 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002255 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002256 const int coeff_ctx =
2257 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
Jingning Hand1097fc2016-12-06 10:55:34 -08002258#if CONFIG_CB4X4
2259 block = 4 * block;
2260#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002261#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002262 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2263 TX_4X4, coeff_ctx, AV1_XFORM_QUANT_B_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002264#else
Jingning Hand1097fc2016-12-06 10:55:34 -08002265 av1_xform_quant(cm, x, 0, block,
2266#if CONFIG_CB4X4
2267 2 * (row + idy), 2 * (col + idx),
2268#else
2269 row + idy, col + idx,
2270#endif
2271 BLOCK_8X8, TX_4X4, coeff_ctx, AV1_XFORM_QUANT_B);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002272#endif // CONFIG_NEW_QUANT
Angie Chiang22ba7512016-10-20 17:10:33 -07002273 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002274 scan_order->scan, scan_order->neighbors,
2275 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002276 *(tempa + idx) = !(p->eobs[block] == 0);
2277 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002278 can_skip &= (p->eobs[block] == 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002279#else
2280 skip = av1_pvq_encode_helper(&x->daala_enc, coeff, ref_coeff, dqcoeff,
2281 &p->eobs[block], pd->dequant, 0, TX_4X4,
2282 tx_type, &rate_pvq, x->pvq_speed, NULL);
2283 ratey += rate_pvq;
2284#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002285 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2286 goto next;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002287#if CONFIG_PVQ
2288 if (!skip) {
2289 for (j = 0; j < tx_blk_size; j++)
2290 for (i = 0; i < tx_blk_size; i++) dst[j * dst_stride + i] = 0;
2291#endif
2292 av1_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2293 dst_stride, p->eobs[block], DCT_DCT, 1);
2294#if CONFIG_PVQ
2295 }
2296#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002297 } else {
2298 int64_t dist;
2299 unsigned int tmp;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002300#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002301 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002302 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002303 const int coeff_ctx =
2304 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
Jingning Hand1097fc2016-12-06 10:55:34 -08002305#if CONFIG_CB4X4
2306 block = 4 * block;
2307#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002308#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002309 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2310 TX_4X4, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002311#else
Jingning Hand1097fc2016-12-06 10:55:34 -08002312 av1_xform_quant(cm, x, 0, block,
2313#if CONFIG_CB4X4
2314 2 * (row + idy), 2 * (col + idx),
2315#else
2316 row + idy, col + idx,
2317#endif
2318 BLOCK_8X8, TX_4X4, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002319#endif // CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002320 av1_optimize_b(cm, x, 0, block, TX_4X4, coeff_ctx);
Angie Chiang22ba7512016-10-20 17:10:33 -07002321 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002322 scan_order->scan, scan_order->neighbors,
2323 cpi->sf.use_fast_coef_costing);
Jingning Han3d45c0e2016-11-08 12:35:04 -08002324 *(tempa + idx) = !(p->eobs[block] == 0);
2325 *(templ + idy) = !(p->eobs[block] == 0);
2326 can_skip &= (p->eobs[block] == 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002327#else
2328 skip = av1_pvq_encode_helper(&x->daala_enc, coeff, ref_coeff, dqcoeff,
2329 &p->eobs[block], pd->dequant, 0, TX_4X4,
2330 tx_type, &rate_pvq, x->pvq_speed, NULL);
2331 ratey += rate_pvq;
2332#endif
2333 // No need for av1_block_error2_c because the ssz is unused
Yaowu Xuf883b422016-08-30 14:01:10 -07002334 av1_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2335 dst_stride, p->eobs[block], tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002336 cpi->fn_ptr[BLOCK_4X4].vf(src, src_stride, dst, dst_stride, &tmp);
2337 dist = (int64_t)tmp << 4;
2338 distortion += dist;
2339 // To use the pixel domain distortion, the step below needs to be
2340 // put behind the inv txfm. Compared to calculating the distortion
2341 // in the frequency domain, the overhead of encoding effort is low.
2342 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2343 goto next;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002344#if CONFIG_PVQ
2345 if (!skip) {
2346 for (j = 0; j < tx_blk_size; j++)
2347 for (i = 0; i < tx_blk_size; i++) dst[j * dst_stride + i] = 0;
2348#endif
2349#if CONFIG_PVQ
2350 }
2351#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002352 }
2353 }
2354 }
2355
2356 rate += ratey;
2357 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2358
2359 if (this_rd < best_rd) {
2360 *bestrate = rate;
2361 *bestratey = ratey;
2362 *bestdistortion = distortion;
2363 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002364 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002365 *best_mode = mode;
2366 memcpy(a, tempa, num_4x4_blocks_wide * sizeof(tempa[0]));
2367 memcpy(l, templ, num_4x4_blocks_high * sizeof(templ[0]));
Yushin Cho77bba8d2016-11-04 16:36:56 -07002368#if CONFIG_PVQ
2369 od_encode_checkpoint(&x->daala_enc, &post_buf);
2370#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002371 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
2372 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
2373 num_4x4_blocks_wide * 4);
2374 }
2375 next : {}
Yushin Cho77bba8d2016-11-04 16:36:56 -07002376#if CONFIG_PVQ
2377 od_encode_rollback(&x->daala_enc, &pre_buf);
2378#endif
2379 } // mode decision loop
Yaowu Xuc27fc142016-08-22 16:08:15 -07002380
2381 if (best_rd >= rd_thresh) return best_rd;
2382
Yushin Cho77bba8d2016-11-04 16:36:56 -07002383#if CONFIG_PVQ
2384 od_encode_rollback(&x->daala_enc, &post_buf);
2385#endif
2386
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002387 if (y_skip) *y_skip &= best_can_skip;
2388
Yaowu Xuc27fc142016-08-22 16:08:15 -07002389 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
2390 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
2391 num_4x4_blocks_wide * 4);
2392
2393 return best_rd;
2394}
2395
Urvang Joshi52648442016-10-13 17:27:51 -07002396static int64_t rd_pick_intra_sub_8x8_y_mode(const AV1_COMP *const cpi,
2397 MACROBLOCK *mb, int *rate,
2398 int *rate_y, int64_t *distortion,
2399 int *y_skip, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002400 int i, j;
2401 const MACROBLOCKD *const xd = &mb->e_mbd;
2402 MODE_INFO *const mic = xd->mi[0];
2403 const MODE_INFO *above_mi = xd->above_mi;
2404 const MODE_INFO *left_mi = xd->left_mi;
2405 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
2406 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2407 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2408 int idx, idy;
2409 int cost = 0;
2410 int64_t total_distortion = 0;
2411 int tot_rate_y = 0;
2412 int64_t total_rd = 0;
2413 const int *bmode_costs = cpi->mbmode_cost[0];
2414
2415#if CONFIG_EXT_INTRA
hui sueda3d762016-12-06 16:58:23 -08002416#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07002417 mic->mbmi.intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08002418#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07002419#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002420#if CONFIG_FILTER_INTRA
2421 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2422#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002423
2424 // TODO(any): Add search of the tx_type to improve rd performance at the
2425 // expense of speed.
2426 mic->mbmi.tx_type = DCT_DCT;
2427 mic->mbmi.tx_size = TX_4X4;
2428
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002429 if (y_skip) *y_skip = 1;
2430
Yaowu Xuc27fc142016-08-22 16:08:15 -07002431 // Pick modes for each sub-block (of size 4x4, 4x8, or 8x4) in an 8x8 block.
2432 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
2433 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
2434 PREDICTION_MODE best_mode = DC_PRED;
2435 int r = INT_MAX, ry = INT_MAX;
2436 int64_t d = INT64_MAX, this_rd = INT64_MAX;
2437 i = idy * 2 + idx;
2438 if (cpi->common.frame_type == KEY_FRAME) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002439 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, i);
2440 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, i);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002441
2442 bmode_costs = cpi->y_mode_costs[A][L];
2443 }
2444
2445 this_rd = rd_pick_intra4x4block(
2446 cpi, mb, idy, idx, &best_mode, bmode_costs,
2447 xd->plane[0].above_context + idx, xd->plane[0].left_context + idy, &r,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002448 &ry, &d, bsize, y_skip, best_rd - total_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002449 if (this_rd >= best_rd - total_rd) return INT64_MAX;
2450
2451 total_rd += this_rd;
2452 cost += r;
2453 total_distortion += d;
2454 tot_rate_y += ry;
2455
2456 mic->bmi[i].as_mode = best_mode;
2457 for (j = 1; j < num_4x4_blocks_high; ++j)
2458 mic->bmi[i + j * 2].as_mode = best_mode;
2459 for (j = 1; j < num_4x4_blocks_wide; ++j)
2460 mic->bmi[i + j].as_mode = best_mode;
2461
2462 if (total_rd >= best_rd) return INT64_MAX;
2463 }
2464 }
2465 mic->mbmi.mode = mic->bmi[3].as_mode;
2466
2467 // Add in the cost of the transform type
2468 if (!xd->lossless[mic->mbmi.segment_id]) {
2469 int rate_tx_type = 0;
2470#if CONFIG_EXT_TX
2471 if (get_ext_tx_types(TX_4X4, bsize, 0) > 1) {
2472 const int eset = get_ext_tx_set(TX_4X4, bsize, 0);
clang-format67948d32016-09-07 22:40:40 -07002473 rate_tx_type = cpi->intra_tx_type_costs[eset][TX_4X4][mic->mbmi.mode]
2474 [mic->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002475 }
2476#else
clang-format67948d32016-09-07 22:40:40 -07002477 rate_tx_type =
2478 cpi->intra_tx_type_costs[TX_4X4]
2479 [intra_mode_to_tx_type_context[mic->mbmi.mode]]
2480 [mic->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002481#endif
2482 assert(mic->mbmi.tx_size == TX_4X4);
2483 cost += rate_tx_type;
2484 tot_rate_y += rate_tx_type;
2485 }
2486
2487 *rate = cost;
2488 *rate_y = tot_rate_y;
2489 *distortion = total_distortion;
2490
2491 return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
2492}
2493
hui su5db97432016-10-14 16:10:14 -07002494#if CONFIG_FILTER_INTRA
2495// Return 1 if an filter intra mode is selected; return 0 otherwise.
2496static int rd_pick_filter_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2497 int *rate, int *rate_tokenonly,
2498 int64_t *distortion, int *skippable,
2499 BLOCK_SIZE bsize, int mode_cost,
2500 int64_t *best_rd, uint16_t skip_mask) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002501 MACROBLOCKD *const xd = &x->e_mbd;
2502 MODE_INFO *const mic = xd->mi[0];
2503 MB_MODE_INFO *mbmi = &mic->mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002504 int this_rate;
2505 RD_STATS tokenonly_rd_stats;
hui su5db97432016-10-14 16:10:14 -07002506 int filter_intra_selected_flag = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002507 int64_t this_rd;
hui su5db97432016-10-14 16:10:14 -07002508 FILTER_INTRA_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002509 TX_SIZE best_tx_size = TX_4X4;
hui su5db97432016-10-14 16:10:14 -07002510 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002511 TX_TYPE best_tx_type;
2512
hui su5db97432016-10-14 16:10:14 -07002513 av1_zero(filter_intra_mode_info);
2514 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002515 mbmi->mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07002516#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002517 mbmi->palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002518#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002519
2520 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
2521 if (skip_mask & (1 << mode)) continue;
hui su5db97432016-10-14 16:10:14 -07002522 mbmi->filter_intra_mode_info.filter_intra_mode[0] = mode;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002523 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
2524 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002525
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002526 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07002527 av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07002528 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002529 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002530
2531 if (this_rd < *best_rd) {
2532 *best_rd = this_rd;
2533 best_tx_size = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07002534 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002535 best_tx_type = mic->mbmi.tx_type;
2536 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002537 *rate_tokenonly = tokenonly_rd_stats.rate;
2538 *distortion = tokenonly_rd_stats.dist;
2539 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07002540 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002541 }
2542 }
2543
hui su5db97432016-10-14 16:10:14 -07002544 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002545 mbmi->mode = DC_PRED;
2546 mbmi->tx_size = best_tx_size;
hui su5db97432016-10-14 16:10:14 -07002547 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] =
2548 filter_intra_mode_info.use_filter_intra_mode[0];
2549 mbmi->filter_intra_mode_info.filter_intra_mode[0] =
2550 filter_intra_mode_info.filter_intra_mode[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002551 mbmi->tx_type = best_tx_type;
2552 return 1;
2553 } else {
2554 return 0;
2555 }
2556}
hui su5db97432016-10-14 16:10:14 -07002557#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002558
hui su5db97432016-10-14 16:10:14 -07002559#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08002560// Run RD calculation with given luma intra prediction angle., and return
2561// the RD cost. Update the best mode info. if the RD cost is the best so far.
2562static int64_t calc_rd_given_intra_angle(
2563 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int mode_cost,
2564 int64_t best_rd_in, int8_t angle_delta, int max_angle_delta, int *rate,
2565 RD_STATS *rd_stats, int *best_angle_delta, TX_SIZE *best_tx_size,
2566 TX_TYPE *best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08002567#if CONFIG_INTRA_INTERP
2568 INTRA_FILTER *best_filter,
2569#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08002570 int64_t *best_rd) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002571 int this_rate;
2572 RD_STATS tokenonly_rd_stats;
2573 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002574 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002575
hui su45dc5972016-12-08 17:42:50 -08002576 mbmi->angle_delta[0] = angle_delta;
2577 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in);
2578 if (tokenonly_rd_stats.rate == INT_MAX) return INT64_MAX;
2579
2580 this_rate = tokenonly_rd_stats.rate + mode_cost +
2581 write_uniform_cost(2 * max_angle_delta + 1,
2582 mbmi->angle_delta[0] + max_angle_delta);
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002583 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002584
2585 if (this_rd < *best_rd) {
2586 *best_rd = this_rd;
2587 *best_angle_delta = mbmi->angle_delta[0];
2588 *best_tx_size = mbmi->tx_size;
hui sueda3d762016-12-06 16:58:23 -08002589#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07002590 *best_filter = mbmi->intra_filter;
hui sueda3d762016-12-06 16:58:23 -08002591#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07002592 *best_tx_type = mbmi->tx_type;
2593 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08002594 rd_stats->rate = tokenonly_rd_stats.rate;
2595 rd_stats->dist = tokenonly_rd_stats.dist;
2596 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002597 }
hui su45dc5972016-12-08 17:42:50 -08002598 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002599}
2600
hui su45dc5972016-12-08 17:42:50 -08002601// With given luma directional intra prediction mode, pick the best angle delta
2602// Return the RD cost corresponding to the best angle delta.
Urvang Joshi52648442016-10-13 17:27:51 -07002603static int64_t rd_pick_intra_angle_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
hui su45dc5972016-12-08 17:42:50 -08002604 int *rate, RD_STATS *rd_stats,
2605 BLOCK_SIZE bsize, int mode_cost,
Urvang Joshi52648442016-10-13 17:27:51 -07002606 int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002607 MACROBLOCKD *const xd = &x->e_mbd;
2608 MODE_INFO *const mic = xd->mi[0];
2609 MB_MODE_INFO *mbmi = &mic->mbmi;
hui su45dc5972016-12-08 17:42:50 -08002610 int i, angle_delta, best_angle_delta = 0;
2611 const int max_angle_delta = av1_get_max_angle_delta(bsize, 0);
2612 int first_try = 1;
hui sueda3d762016-12-06 16:58:23 -08002613#if CONFIG_INTRA_INTERP
2614 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07002615 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002616 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08002617#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08002618 int64_t this_rd, best_rd_in, rd_cost[16];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002619 TX_SIZE best_tx_size = mic->mbmi.tx_size;
2620 TX_TYPE best_tx_type = mbmi->tx_type;
2621
hui su45dc5972016-12-08 17:42:50 -08002622 for (i = 0; i < 2 * (max_angle_delta + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002623
hui su45dc5972016-12-08 17:42:50 -08002624 for (angle_delta = 0; angle_delta <= max_angle_delta; angle_delta += 2) {
hui sueda3d762016-12-06 16:58:23 -08002625#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08002626 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2627 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
2628 mic->mbmi.intra_filter = filter;
hui sueda3d762016-12-06 16:58:23 -08002629#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08002630 for (i = 0; i < 2; ++i) {
2631 best_rd_in = (best_rd == INT64_MAX)
2632 ? INT64_MAX
2633 : (best_rd + (best_rd >> (first_try ? 3 : 5)));
2634 this_rd = calc_rd_given_intra_angle(
2635 cpi, x, bsize,
hui sueda3d762016-12-06 16:58:23 -08002636#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08002637 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
hui sueda3d762016-12-06 16:58:23 -08002638#else
hui su45dc5972016-12-08 17:42:50 -08002639 mode_cost,
hui sueda3d762016-12-06 16:58:23 -08002640#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08002641 best_rd_in, (1 - 2 * i) * angle_delta, max_angle_delta, rate,
2642 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08002643#if CONFIG_INTRA_INTERP
2644 &best_filter,
2645#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07002646 &best_rd);
hui su45dc5972016-12-08 17:42:50 -08002647 rd_cost[2 * angle_delta + i] = this_rd;
2648 if (first_try && this_rd == INT64_MAX) return best_rd;
2649 first_try = 0;
2650 if (angle_delta == 0) {
2651 rd_cost[1] = this_rd;
2652 break;
2653 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002654 }
hui su45dc5972016-12-08 17:42:50 -08002655#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07002656 }
hui su45dc5972016-12-08 17:42:50 -08002657#endif // CONFIG_INTRA_INTERP
2658 }
2659
2660 assert(best_rd != INT64_MAX);
2661 for (angle_delta = 1; angle_delta <= max_angle_delta; angle_delta += 2) {
2662 int64_t rd_thresh;
2663#if CONFIG_INTRA_INTERP
2664 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2665 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
2666 mic->mbmi.intra_filter = filter;
2667#endif // CONFIG_INTRA_INTERP
2668 for (i = 0; i < 2; ++i) {
2669 int skip_search = 0;
2670 rd_thresh = best_rd + (best_rd >> 5);
2671 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
2672 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
2673 skip_search = 1;
2674 if (!skip_search) {
2675 this_rd = calc_rd_given_intra_angle(
2676 cpi, x, bsize,
2677#if CONFIG_INTRA_INTERP
2678 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
2679#else
2680 mode_cost,
2681#endif // CONFIG_INTRA_INTERP
2682 best_rd, (1 - 2 * i) * angle_delta, max_angle_delta, rate,
2683 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
2684#if CONFIG_INTRA_INTERP
2685 &best_filter,
2686#endif // CONFIG_INTRA_INTERP
2687 &best_rd);
2688 }
2689 }
2690#if CONFIG_INTRA_INTERP
2691 }
2692#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07002693 }
2694
hui sueda3d762016-12-06 16:58:23 -08002695#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08002696 if (FILTER_FAST_SEARCH && rd_stats->rate < INT_MAX) {
2697 p_angle = mode_to_angle_map[mbmi->mode] +
2698 best_angle_delta * av1_get_angle_step(bsize, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07002699 if (av1_is_intra_filter_switchable(p_angle)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002700 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
2701 mic->mbmi.intra_filter = filter;
hui su45dc5972016-12-08 17:42:50 -08002702 this_rd = calc_rd_given_intra_angle(
2703 cpi, x, bsize,
2704 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
2705 best_rd, best_angle_delta, max_angle_delta, rate, rd_stats,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002706 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002707 &best_rd);
2708 }
2709 }
2710 }
hui sueda3d762016-12-06 16:58:23 -08002711#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07002712
2713 mbmi->tx_size = best_tx_size;
2714 mbmi->angle_delta[0] = best_angle_delta;
hui sueda3d762016-12-06 16:58:23 -08002715#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07002716 mic->mbmi.intra_filter = best_filter;
hui sueda3d762016-12-06 16:58:23 -08002717#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07002718 mbmi->tx_type = best_tx_type;
2719 return best_rd;
2720}
2721
2722// Indices are sign, integer, and fractional part of the gradient value
2723static const uint8_t gradient_to_angle_bin[2][7][16] = {
2724 {
2725 { 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0 },
2726 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
2727 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
2728 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
2729 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
2730 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2731 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2732 },
2733 {
2734 { 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4 },
2735 { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3 },
2736 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2737 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2738 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2739 { 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2740 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2741 },
2742};
2743
2744static const uint8_t mode_to_angle_bin[INTRA_MODES] = {
2745 0, 2, 6, 0, 4, 3, 5, 7, 1, 0,
2746};
2747
2748static void angle_estimation(const uint8_t *src, int src_stride, int rows,
2749 int cols, uint8_t *directional_mode_skip_mask) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002750 int i, r, c, index, dx, dy, temp, sn, remd, quot;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002751 uint64_t hist[DIRECTIONAL_MODES];
2752 uint64_t hist_sum = 0;
2753
2754 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
2755 src += src_stride;
2756 for (r = 1; r < rows; ++r) {
2757 for (c = 1; c < cols; ++c) {
2758 dx = src[c] - src[c - 1];
2759 dy = src[c] - src[c - src_stride];
2760 temp = dx * dx + dy * dy;
2761 if (dy == 0) {
2762 index = 2;
2763 } else {
2764 sn = (dx > 0) ^ (dy > 0);
2765 dx = abs(dx);
2766 dy = abs(dy);
2767 remd = dx % dy;
2768 quot = dx / dy;
2769 remd = remd * 16 / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07002770 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002771 }
2772 hist[index] += temp;
2773 }
2774 src += src_stride;
2775 }
2776
2777 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
2778 for (i = 0; i < INTRA_MODES; ++i) {
2779 if (i != DC_PRED && i != TM_PRED) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002780 const uint8_t angle_bin = mode_to_angle_bin[i];
2781 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002782 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07002783 if (angle_bin > 0) {
2784 score += hist[angle_bin - 1];
2785 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002786 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07002787 if (angle_bin < DIRECTIONAL_MODES - 1) {
2788 score += hist[angle_bin + 1];
2789 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002790 }
2791 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
2792 directional_mode_skip_mask[i] = 1;
2793 }
2794 }
2795}
2796
Yaowu Xuf883b422016-08-30 14:01:10 -07002797#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002798static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
2799 int rows, int cols,
2800 uint8_t *directional_mode_skip_mask) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002801 int i, r, c, index, dx, dy, temp, sn, remd, quot;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002802 uint64_t hist[DIRECTIONAL_MODES];
2803 uint64_t hist_sum = 0;
2804 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
2805
2806 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
2807 src += src_stride;
2808 for (r = 1; r < rows; ++r) {
2809 for (c = 1; c < cols; ++c) {
2810 dx = src[c] - src[c - 1];
2811 dy = src[c] - src[c - src_stride];
2812 temp = dx * dx + dy * dy;
2813 if (dy == 0) {
2814 index = 2;
2815 } else {
2816 sn = (dx > 0) ^ (dy > 0);
2817 dx = abs(dx);
2818 dy = abs(dy);
2819 remd = dx % dy;
2820 quot = dx / dy;
2821 remd = remd * 16 / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07002822 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002823 }
2824 hist[index] += temp;
2825 }
2826 src += src_stride;
2827 }
2828
2829 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
2830 for (i = 0; i < INTRA_MODES; ++i) {
2831 if (i != DC_PRED && i != TM_PRED) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002832 const uint8_t angle_bin = mode_to_angle_bin[i];
2833 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002834 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07002835 if (angle_bin > 0) {
2836 score += hist[angle_bin - 1];
2837 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002838 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07002839 if (angle_bin < DIRECTIONAL_MODES - 1) {
2840 score += hist[angle_bin + 1];
2841 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002842 }
2843 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
2844 directional_mode_skip_mask[i] = 1;
2845 }
2846 }
2847}
Yaowu Xuf883b422016-08-30 14:01:10 -07002848#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002849#endif // CONFIG_EXT_INTRA
2850
2851// This function is used only for intra_only frames
Urvang Joshi52648442016-10-13 17:27:51 -07002852static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
2853 int *rate, int *rate_tokenonly,
2854 int64_t *distortion, int *skippable,
2855 BLOCK_SIZE bsize, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002856 uint8_t mode_idx;
2857 PREDICTION_MODE mode_selected = DC_PRED;
2858 MACROBLOCKD *const xd = &x->e_mbd;
2859 MODE_INFO *const mic = xd->mi[0];
2860 int this_rate, this_rate_tokenonly, s;
2861 int64_t this_distortion, this_rd;
2862 TX_SIZE best_tx = TX_4X4;
Urvang Joshib100db72016-10-12 16:28:56 -07002863#if CONFIG_EXT_INTRA || CONFIG_PALETTE
Jingning Hanae5cfde2016-11-30 12:01:44 -08002864 const int rows = block_size_high[bsize];
2865 const int cols = block_size_wide[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07002866#endif // CONFIG_EXT_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002867#if CONFIG_EXT_INTRA
hui sueda3d762016-12-06 16:58:23 -08002868#if CONFIG_INTRA_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07002869 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002870 INTRA_FILTER best_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08002871#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08002872 int is_directional_mode, best_angle_delta = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002873 uint8_t directional_mode_skip_mask[INTRA_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002874 const int src_stride = x->plane[0].src.stride;
2875 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002876#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002877#if CONFIG_FILTER_INTRA
2878 int beat_best_rd = 0;
2879 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
2880 uint16_t filter_intra_mode_skip_mask = (1 << FILTER_INTRA_MODES) - 1;
2881#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002882 TX_TYPE best_tx_type = DCT_DCT;
Urvang Joshi52648442016-10-13 17:27:51 -07002883 const int *bmode_costs;
Urvang Joshib100db72016-10-12 16:28:56 -07002884#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002885 PALETTE_MODE_INFO palette_mode_info;
2886 PALETTE_MODE_INFO *const pmi = &mic->mbmi.palette_mode_info;
2887 uint8_t *best_palette_color_map =
2888 cpi->common.allow_screen_content_tools
2889 ? x->palette_buffer->best_palette_color_map
2890 : NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002891 int palette_ctx = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002892#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002893 const MODE_INFO *above_mi = xd->above_mi;
2894 const MODE_INFO *left_mi = xd->left_mi;
Yaowu Xuf883b422016-08-30 14:01:10 -07002895 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, 0);
2896 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002897 const PREDICTION_MODE FINAL_MODE_SEARCH = TM_PRED + 1;
2898 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
Yushin Cho77bba8d2016-11-04 16:36:56 -07002899#if CONFIG_PVQ
2900 od_rollback_buffer pre_buf, post_buf;
2901
2902 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2903 od_encode_checkpoint(&x->daala_enc, &post_buf);
2904#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002905 bmode_costs = cpi->y_mode_costs[A][L];
2906
2907#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002908 mic->mbmi.angle_delta[0] = 0;
2909 memset(directional_mode_skip_mask, 0,
2910 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
Yaowu Xuf883b422016-08-30 14:01:10 -07002911#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002912 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
2913 highbd_angle_estimation(src, src_stride, rows, cols,
2914 directional_mode_skip_mask);
2915 else
2916#endif
2917 angle_estimation(src, src_stride, rows, cols, directional_mode_skip_mask);
2918#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002919#if CONFIG_FILTER_INTRA
2920 filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2921 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2922#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07002923#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002924 palette_mode_info.palette_size[0] = 0;
2925 pmi->palette_size[0] = 0;
2926 if (above_mi)
2927 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
2928 if (left_mi)
2929 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Urvang Joshib100db72016-10-12 16:28:56 -07002930#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002931
2932 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
2933 x->use_default_intra_tx_type = 1;
2934 else
2935 x->use_default_intra_tx_type = 0;
2936
2937 /* Y Search for intra prediction mode */
2938 for (mode_idx = DC_PRED; mode_idx <= FINAL_MODE_SEARCH; ++mode_idx) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002939 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002940 if (mode_idx == FINAL_MODE_SEARCH) {
2941 if (x->use_default_intra_tx_type == 0) break;
2942 mic->mbmi.mode = mode_selected;
2943 x->use_default_intra_tx_type = 0;
2944 } else {
2945 mic->mbmi.mode = mode_idx;
2946 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07002947#if CONFIG_PVQ
2948 od_encode_rollback(&x->daala_enc, &pre_buf);
2949#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002950#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08002951 is_directional_mode = av1_is_directional_mode(mic->mbmi.mode, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002952 if (is_directional_mode && directional_mode_skip_mask[mic->mbmi.mode])
2953 continue;
2954 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -08002955 this_rd_stats.rate = INT_MAX;
2956 this_rd =
2957 rd_pick_intra_angle_sby(cpi, x, &this_rate, &this_rd_stats, bsize,
2958 bmode_costs[mic->mbmi.mode], best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002959 } else {
2960 mic->mbmi.angle_delta[0] = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002961 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002962 }
2963#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002964 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -08002965#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002966 this_rate_tokenonly = this_rd_stats.rate;
2967 this_distortion = this_rd_stats.dist;
2968 s = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002969
2970 if (this_rate_tokenonly == INT_MAX) continue;
2971
2972 this_rate = this_rate_tokenonly + bmode_costs[mic->mbmi.mode];
2973
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002974 if (!xd->lossless[xd->mi[0]->mbmi.segment_id] &&
2975 mic->mbmi.sb_type >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002976 // super_block_yrd above includes the cost of the tx_size in the
2977 // tokenonly rate, but for intra blocks, tx_size is always coded
2978 // (prediction granularity), so we account for it in the full rate,
2979 // not the tokenonly rate.
2980 this_rate_tokenonly -=
clang-format67948d32016-09-07 22:40:40 -07002981 cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
Jingning Hanb0a71302016-10-25 16:28:49 -07002982 [tx_size_to_depth(mic->mbmi.tx_size)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002983 }
Urvang Joshib100db72016-10-12 16:28:56 -07002984#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002985 if (cpi->common.allow_screen_content_tools && mic->mbmi.mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07002986 this_rate += av1_cost_bit(
2987 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07002988#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07002989#if CONFIG_FILTER_INTRA
2990 if (mic->mbmi.mode == DC_PRED)
2991 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 0);
2992#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002993#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002994 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -08002995 const int max_angle_delta = av1_get_max_angle_delta(bsize, 0);
hui sueda3d762016-12-06 16:58:23 -08002996#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08002997 const int p_angle =
2998 mode_to_angle_map[mic->mbmi.mode] +
2999 mic->mbmi.angle_delta[0] * av1_get_angle_step(bsize, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07003000 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07003001 this_rate +=
3002 cpi->intra_filter_cost[intra_filter_ctx][mic->mbmi.intra_filter];
hui sueda3d762016-12-06 16:58:23 -08003003#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003004 this_rate += write_uniform_cost(
3005 2 * max_angle_delta + 1, max_angle_delta + mic->mbmi.angle_delta[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003006 }
3007#endif // CONFIG_EXT_INTRA
3008 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui su5db97432016-10-14 16:10:14 -07003009#if CONFIG_FILTER_INTRA
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07003010 if (best_rd == INT64_MAX || this_rd - best_rd < (best_rd >> 4)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003011 filter_intra_mode_skip_mask ^= (1 << mic->mbmi.mode);
3012 }
hui su5db97432016-10-14 16:10:14 -07003013#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003014
3015 if (this_rd < best_rd) {
3016 mode_selected = mic->mbmi.mode;
3017 best_rd = this_rd;
3018 best_tx = mic->mbmi.tx_size;
3019#if CONFIG_EXT_INTRA
3020 best_angle_delta = mic->mbmi.angle_delta[0];
hui sueda3d762016-12-06 16:58:23 -08003021#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003022 best_filter = mic->mbmi.intra_filter;
hui sueda3d762016-12-06 16:58:23 -08003023#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003024#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003025#if CONFIG_FILTER_INTRA
3026 beat_best_rd = 1;
3027#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003028 best_tx_type = mic->mbmi.tx_type;
3029 *rate = this_rate;
3030 *rate_tokenonly = this_rate_tokenonly;
3031 *distortion = this_distortion;
3032 *skippable = s;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003033#if CONFIG_PVQ
3034 od_encode_checkpoint(&x->daala_enc, &post_buf);
3035#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003036 }
3037 }
3038
Yushin Cho77bba8d2016-11-04 16:36:56 -07003039#if CONFIG_PVQ
3040 od_encode_rollback(&x->daala_enc, &post_buf);
3041#endif
3042
Urvang Joshib100db72016-10-12 16:28:56 -07003043#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003044 if (cpi->common.allow_screen_content_tools)
3045 rd_pick_palette_intra_sby(cpi, x, bsize, palette_ctx, bmode_costs[DC_PRED],
3046 &palette_mode_info, best_palette_color_map,
3047 &best_tx, &best_tx_type, &mode_selected,
3048 &best_rd);
Urvang Joshib100db72016-10-12 16:28:56 -07003049#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003050
hui su5db97432016-10-14 16:10:14 -07003051#if CONFIG_FILTER_INTRA
3052 if (beat_best_rd) {
3053 if (rd_pick_filter_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
3054 skippable, bsize, bmode_costs[DC_PRED],
3055 &best_rd, filter_intra_mode_skip_mask)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003056 mode_selected = mic->mbmi.mode;
3057 best_tx = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07003058 filter_intra_mode_info = mic->mbmi.filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003059 best_tx_type = mic->mbmi.tx_type;
3060 }
3061 }
3062
hui su5db97432016-10-14 16:10:14 -07003063 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] =
3064 filter_intra_mode_info.use_filter_intra_mode[0];
3065 if (filter_intra_mode_info.use_filter_intra_mode[0]) {
3066 mic->mbmi.filter_intra_mode_info.filter_intra_mode[0] =
3067 filter_intra_mode_info.filter_intra_mode[0];
Urvang Joshib100db72016-10-12 16:28:56 -07003068#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003069 palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003070#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003071 }
hui su5db97432016-10-14 16:10:14 -07003072#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003073
3074 mic->mbmi.mode = mode_selected;
3075 mic->mbmi.tx_size = best_tx;
3076#if CONFIG_EXT_INTRA
3077 mic->mbmi.angle_delta[0] = best_angle_delta;
hui sueda3d762016-12-06 16:58:23 -08003078#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003079 mic->mbmi.intra_filter = best_filter;
hui sueda3d762016-12-06 16:58:23 -08003080#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003081#endif // CONFIG_EXT_INTRA
3082 mic->mbmi.tx_type = best_tx_type;
Urvang Joshib100db72016-10-12 16:28:56 -07003083#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003084 pmi->palette_size[0] = palette_mode_info.palette_size[0];
3085 if (palette_mode_info.palette_size[0] > 0) {
3086 memcpy(pmi->palette_colors, palette_mode_info.palette_colors,
3087 PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
3088 memcpy(xd->plane[0].color_index_map, best_palette_color_map,
3089 rows * cols * sizeof(best_palette_color_map[0]));
3090 }
Urvang Joshib100db72016-10-12 16:28:56 -07003091#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003092
3093 return best_rd;
3094}
3095
Yue Chena1e48dc2016-08-29 17:29:33 -07003096// Return value 0: early termination triggered, no valid rd cost available;
3097// 1: rd cost values are valid.
Angie Chiang284d7772016-11-08 11:06:45 -08003098static int super_block_uvrd(const AV1_COMP *const cpi, MACROBLOCK *x,
3099 RD_STATS *rd_stats, BLOCK_SIZE bsize,
3100 int64_t ref_best_rd) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003101 MACROBLOCKD *const xd = &x->e_mbd;
3102 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3103 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
3104 int plane;
Yue Chena1e48dc2016-08-29 17:29:33 -07003105 int is_cost_valid = 1;
Angie Chiang284d7772016-11-08 11:06:45 -08003106 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003107
3108 if (ref_best_rd < 0) is_cost_valid = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003109#if !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07003110 if (is_inter_block(mbmi) && is_cost_valid) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003111 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
3112 av1_subtract_plane(x, bsize, plane);
3113 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003114#endif
Yue Chena1e48dc2016-08-29 17:29:33 -07003115
Yushin Cho09de28b2016-06-21 14:51:23 -07003116 if (is_cost_valid) {
3117 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003118 RD_STATS pn_rd_stats;
3119 txfm_rd_in_plane(x, cpi, &pn_rd_stats, ref_best_rd, plane, bsize,
3120 uv_tx_size, cpi->sf.use_fast_coef_costing);
3121 if (pn_rd_stats.rate == INT_MAX) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003122 is_cost_valid = 0;
3123 break;
3124 }
Angie Chiang284d7772016-11-08 11:06:45 -08003125 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
3126 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003127 ref_best_rd &&
Angie Chiang284d7772016-11-08 11:06:45 -08003128 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse) > ref_best_rd) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003129 is_cost_valid = 0;
3130 break;
3131 }
Yue Chena1e48dc2016-08-29 17:29:33 -07003132 }
3133 }
3134
3135 if (!is_cost_valid) {
3136 // reset cost value
Angie Chiang284d7772016-11-08 11:06:45 -08003137 av1_invalid_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003138 }
3139
3140 return is_cost_valid;
3141}
3142
Yaowu Xuc27fc142016-08-22 16:08:15 -07003143#if CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07003144void av1_tx_block_rd_b(const AV1_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
3145 int blk_row, int blk_col, int plane, int block,
Angie Chiangb5dda482016-11-02 16:19:58 -07003146 int plane_bsize, int coeff_ctx, RD_STATS *rd_stats) {
Angie Chiang22ba7512016-10-20 17:10:33 -07003147 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003148 MACROBLOCKD *xd = &x->e_mbd;
3149 const struct macroblock_plane *const p = &x->plane[plane];
3150 struct macroblockd_plane *const pd = &xd->plane[plane];
3151 int64_t tmp;
3152 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
3153 PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
3154 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07003155 const SCAN_ORDER *const scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07003156 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003157 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
Jingning Han9fdc4222016-10-27 21:32:19 -07003158 int bh = block_size_high[txm_bsize];
3159 int bw = block_size_wide[txm_bsize];
3160 int txb_h = tx_size_high_unit[tx_size];
3161 int txb_w = tx_size_wide_unit[tx_size];
3162
Yaowu Xuc27fc142016-08-22 16:08:15 -07003163 int src_stride = p->src.stride;
3164 uint8_t *src = &p->src.buf[4 * blk_row * src_stride + 4 * blk_col];
3165 uint8_t *dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
Yaowu Xuf883b422016-08-30 14:01:10 -07003166#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003167 DECLARE_ALIGNED(16, uint16_t, rec_buffer16[MAX_TX_SQUARE]);
3168 uint8_t *rec_buffer;
3169#else
3170 DECLARE_ALIGNED(16, uint8_t, rec_buffer[MAX_TX_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07003171#endif // CONFIG_AOM_HIGHBITDEPTH
Jingning Han9fdc4222016-10-27 21:32:19 -07003172 int max_blocks_high = block_size_high[plane_bsize];
3173 int max_blocks_wide = block_size_wide[plane_bsize];
3174 const int diff_stride = max_blocks_wide;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003175 const int16_t *diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
Angie Chiangd81fdb42016-11-03 12:20:58 -07003176 int txb_coeff_cost;
Jingning Hand3fada82016-11-22 10:46:55 -08003177
3178 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003179
3180 if (xd->mb_to_bottom_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003181 max_blocks_high += xd->mb_to_bottom_edge >> (3 + pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003182 if (xd->mb_to_right_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003183 max_blocks_wide += xd->mb_to_right_edge >> (3 + pd->subsampling_x);
3184
3185 max_blocks_high >>= tx_size_wide_log2[0];
3186 max_blocks_wide >>= tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003187
3188#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08003189 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
3190 coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003191#else
Angie Chiangff6d8902016-10-21 11:02:09 -07003192 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08003193 coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003194#endif // CONFIG_NEW_QUANT
3195
Yushin Cho721868c2016-11-14 16:04:33 +09003196 // TODO(yushin) : If PVQ is enabled, this should not be called.
Angie Chiangff6d8902016-10-21 11:02:09 -07003197 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003198
3199// TODO(any): Use dist_block to compute distortion
Yaowu Xuf883b422016-08-30 14:01:10 -07003200#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003201 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3202 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer16);
Yaowu Xuf883b422016-08-30 14:01:10 -07003203 aom_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003204 0, NULL, 0, bw, bh, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003205 } else {
3206 rec_buffer = (uint8_t *)rec_buffer16;
Yaowu Xuf883b422016-08-30 14:01:10 -07003207 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0,
Jingning Han9fdc4222016-10-27 21:32:19 -07003208 NULL, 0, bw, bh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003209 }
3210#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003211 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003212 0, bw, bh);
Yaowu Xuf883b422016-08-30 14:01:10 -07003213#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003214
Jingning Han9fdc4222016-10-27 21:32:19 -07003215 if (blk_row + txb_h > max_blocks_high || blk_col + txb_w > max_blocks_wide) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003216 int idx, idy;
Jingning Han9fdc4222016-10-27 21:32:19 -07003217 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3218 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003219 tmp = 0;
3220 for (idy = 0; idy < blocks_height; idy += 2) {
3221 for (idx = 0; idx < blocks_width; idx += 2) {
3222 const int16_t *d = diff + 4 * idy * diff_stride + 4 * idx;
Yaowu Xuf883b422016-08-30 14:01:10 -07003223 tmp += aom_sum_squares_2d_i16(d, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003224 }
3225 }
3226 } else {
Jingning Han9fdc4222016-10-27 21:32:19 -07003227 tmp = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003228 }
3229
Yaowu Xuf883b422016-08-30 14:01:10 -07003230#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003231 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
3232 tmp = ROUND_POWER_OF_TWO(tmp, (xd->bd - 8) * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07003233#endif // CONFIG_AOM_HIGHBITDEPTH
Angie Chiangb5dda482016-11-02 16:19:58 -07003234 rd_stats->sse += tmp * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003235
3236 if (p->eobs[block] > 0) {
3237 INV_TXFM_PARAM inv_txfm_param;
3238 inv_txfm_param.tx_type = tx_type;
3239 inv_txfm_param.tx_size = tx_size;
3240 inv_txfm_param.eob = p->eobs[block];
3241 inv_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
Yushin Cho721868c2016-11-14 16:04:33 +09003242// TODO(yushin) : If PVQ is enabled, rec_buffer needs be set as zeros.
Yaowu Xuf883b422016-08-30 14:01:10 -07003243#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003244 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3245 inv_txfm_param.bd = xd->bd;
3246 highbd_inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
3247 } else {
3248 inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
3249 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003250#else // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003251 inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
Yaowu Xuf883b422016-08-30 14:01:10 -07003252#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003253
Jingning Han4b47c932016-11-03 09:20:08 -07003254 if (txb_w + blk_col > max_blocks_wide ||
3255 txb_h + blk_row > max_blocks_high) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003256 int idx, idy;
3257 unsigned int this_dist;
Jingning Han9fdc4222016-10-27 21:32:19 -07003258 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3259 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003260 tmp = 0;
3261 for (idy = 0; idy < blocks_height; idy += 2) {
3262 for (idx = 0; idx < blocks_width; idx += 2) {
3263 uint8_t *const s = src + 4 * idy * src_stride + 4 * idx;
3264 uint8_t *const r = rec_buffer + 4 * idy * MAX_TX_SIZE + 4 * idx;
3265 cpi->fn_ptr[BLOCK_8X8].vf(s, src_stride, r, MAX_TX_SIZE, &this_dist);
3266 tmp += this_dist;
3267 }
3268 }
3269 } else {
3270 uint32_t this_dist;
3271 cpi->fn_ptr[txm_bsize].vf(src, src_stride, rec_buffer, MAX_TX_SIZE,
3272 &this_dist);
3273 tmp = this_dist;
3274 }
3275 }
Angie Chiangb5dda482016-11-02 16:19:58 -07003276 rd_stats->dist += tmp * 16;
Angie Chiangd81fdb42016-11-03 12:20:58 -07003277 txb_coeff_cost = av1_cost_coeffs(cm, x, plane, block, coeff_ctx, tx_size,
3278 scan_order->scan, scan_order->neighbors, 0);
3279 rd_stats->rate += txb_coeff_cost;
Angie Chiangb5dda482016-11-02 16:19:58 -07003280 rd_stats->skip &= (p->eobs[block] == 0);
Jingning Han63cbf342016-11-09 15:37:48 -08003281
Angie Chiangd81fdb42016-11-03 12:20:58 -07003282#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08003283 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
3284 txb_coeff_cost);
Angie Chiangd81fdb42016-11-03 12:20:58 -07003285#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003286}
3287
Yaowu Xuf883b422016-08-30 14:01:10 -07003288static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Jingning Han63cbf342016-11-09 15:37:48 -08003289 int blk_col, int plane, int block, int block32,
3290 TX_SIZE tx_size, int depth, BLOCK_SIZE plane_bsize,
Jingning Han94d5bfc2016-10-21 10:14:36 -07003291 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
3292 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
Angie Chiangb5dda482016-11-02 16:19:58 -07003293 RD_STATS *rd_stats, int64_t ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08003294 int *is_cost_valid, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003295 MACROBLOCKD *const xd = &x->e_mbd;
3296 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3297 struct macroblock_plane *const p = &x->plane[plane];
3298 struct macroblockd_plane *const pd = &xd->plane[plane];
3299 const int tx_row = blk_row >> (1 - pd->subsampling_y);
3300 const int tx_col = blk_col >> (1 - pd->subsampling_x);
clang-format67948d32016-09-07 22:40:40 -07003301 TX_SIZE(*const inter_tx_size)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003302 [MAX_MIB_SIZE] =
3303 (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
Jingning Hanf65b8702016-10-31 12:13:20 -07003304 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
3305 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Jingning Han58224042016-10-27 16:35:32 -07003306 const int bw = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003307 int64_t this_rd = INT64_MAX;
3308 ENTROPY_CONTEXT *pta = ta + blk_col;
3309 ENTROPY_CONTEXT *ptl = tl + blk_row;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003310 int coeff_ctx, i;
Jingning Hanc8b89362016-11-01 10:28:53 -07003311 int ctx =
3312 txfm_partition_context(tx_above + (blk_col >> 1),
3313 tx_left + (blk_row >> 1), mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003314 int64_t sum_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003315 int tmp_eob = 0;
3316 int zero_blk_rate;
Angie Chiangd7246172016-11-03 11:49:15 -07003317 RD_STATS sum_rd_stats;
Jingning Han1c019f92016-11-21 12:53:32 -08003318 const int tx_size_ctx = txsize_sqr_map[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003319
Jingning Han63cbf342016-11-09 15:37:48 -08003320 av1_init_rd_stats(&sum_rd_stats);
Jingning Hanfe45b212016-11-22 10:30:23 -08003321
Jingning Hand3fada82016-11-22 10:46:55 -08003322 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003323
3324 if (ref_best_rd < 0) {
3325 *is_cost_valid = 0;
3326 return;
3327 }
3328
Jingning Hance059e82016-10-31 16:27:28 -07003329 coeff_ctx = get_entropy_context(tx_size, pta, ptl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003330
Angie Chiangc0feea82016-11-03 15:36:18 -07003331 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003332
3333 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
3334
Jingning Han1c019f92016-11-21 12:53:32 -08003335 zero_blk_rate = x->token_costs[tx_size_ctx][pd->plane_type][1][0][0]
3336 [coeff_ctx][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003337
3338 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
3339 inter_tx_size[0][0] = tx_size;
Jingning Han63cbf342016-11-09 15:37:48 -08003340
3341 if (tx_size == TX_32X32 && mbmi->tx_type != DCT_DCT &&
3342 rd_stats_stack[block32].rate != INT_MAX) {
3343 *rd_stats = rd_stats_stack[block32];
3344 p->eobs[block] = !rd_stats->skip;
3345 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
3346 } else {
3347 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
3348 plane_bsize, coeff_ctx, rd_stats);
3349 if (tx_size == TX_32X32) {
3350 rd_stats_stack[block32] = *rd_stats;
3351 }
3352 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003353
Angie Chiangb5dda482016-11-02 16:19:58 -07003354 if ((RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >=
3355 RDCOST(x->rdmult, x->rddiv, zero_blk_rate, rd_stats->sse) ||
3356 rd_stats->skip == 1) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003357 !xd->lossless[mbmi->segment_id]) {
Angie Chiangb5dda482016-11-02 16:19:58 -07003358 rd_stats->rate = zero_blk_rate;
3359 rd_stats->dist = rd_stats->sse;
3360 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003361 x->blk_skip[plane][blk_row * bw + blk_col] = 1;
3362 p->eobs[block] = 0;
3363 } else {
3364 x->blk_skip[plane][blk_row * bw + blk_col] = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07003365 rd_stats->skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003366 }
3367
Jingning Han571189c2016-10-24 10:38:43 -07003368 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH)
Angie Chiangb5dda482016-11-02 16:19:58 -07003369 rd_stats->rate +=
3370 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
3371 this_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003372 tmp_eob = p->eobs[block];
3373 }
3374
Jingning Han571189c2016-10-24 10:38:43 -07003375 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH) {
Jingning Han18482fe2016-11-02 17:01:58 -07003376 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
3377 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07003378 int sub_step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Angie Chiangb5dda482016-11-02 16:19:58 -07003379 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003380 int this_cost_valid = 1;
3381 int64_t tmp_rd = 0;
3382
Angie Chiangd7246172016-11-03 11:49:15 -07003383 sum_rd_stats.rate =
3384 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Jingning Hand3fada82016-11-22 10:46:55 -08003385
3386 assert(tx_size < TX_SIZES_ALL);
3387
Yaowu Xuc27fc142016-08-22 16:08:15 -07003388 for (i = 0; i < 4 && this_cost_valid; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07003389 int offsetr = blk_row + (i >> 1) * bsl;
3390 int offsetc = blk_col + (i & 0x01) * bsl;
3391
3392 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
3393
Jingning Han63cbf342016-11-09 15:37:48 -08003394 select_tx_block(cpi, x, offsetr, offsetc, plane, block, block32, sub_txs,
Jingning Han98d6a1f2016-11-03 12:47:47 -07003395 depth + 1, plane_bsize, ta, tl, tx_above, tx_left,
Jingning Han63cbf342016-11-09 15:37:48 -08003396 &this_rd_stats, ref_best_rd - tmp_rd, &this_cost_valid,
3397 rd_stats_stack);
Jingning Han98d6a1f2016-11-03 12:47:47 -07003398
Angie Chiangc0feea82016-11-03 15:36:18 -07003399 av1_merge_rd_stats(&sum_rd_stats, &this_rd_stats);
Jingning Han98d6a1f2016-11-03 12:47:47 -07003400
Angie Chiangd7246172016-11-03 11:49:15 -07003401 tmp_rd =
3402 RDCOST(x->rdmult, x->rddiv, sum_rd_stats.rate, sum_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003403 if (this_rd < tmp_rd) break;
Jingning Han98d6a1f2016-11-03 12:47:47 -07003404 block += sub_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003405 }
3406 if (this_cost_valid) sum_rd = tmp_rd;
3407 }
3408
3409 if (this_rd < sum_rd) {
3410 int idx, idy;
Jingning Han58224042016-10-27 16:35:32 -07003411 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) pta[i] = !(tmp_eob == 0);
3412 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) ptl[i] = !(tmp_eob == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003413 txfm_partition_update(tx_above + (blk_col >> 1), tx_left + (blk_row >> 1),
3414 tx_size);
3415 inter_tx_size[0][0] = tx_size;
Jingning Han58224042016-10-27 16:35:32 -07003416 for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
3417 for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003418 inter_tx_size[idy][idx] = tx_size;
3419 mbmi->tx_size = tx_size;
3420 if (this_rd == INT64_MAX) *is_cost_valid = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07003421 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003422 } else {
Angie Chiangd7246172016-11-03 11:49:15 -07003423 *rd_stats = sum_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003424 if (sum_rd == INT64_MAX) *is_cost_valid = 0;
3425 }
3426}
3427
Angie Chiangb5dda482016-11-02 16:19:58 -07003428static void inter_block_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
3429 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08003430 int64_t ref_best_rd, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003431 MACROBLOCKD *const xd = &x->e_mbd;
3432 int is_cost_valid = 1;
3433 int64_t this_rd = 0;
3434
3435 if (ref_best_rd < 0) is_cost_valid = 0;
3436
Angie Chiangc0feea82016-11-03 15:36:18 -07003437 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003438
3439 if (is_cost_valid) {
3440 const struct macroblockd_plane *const pd = &xd->plane[0];
3441 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
3442 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
3443 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han70e5f3f2016-11-09 17:03:07 -08003444 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07003445 const int bh = tx_size_high_unit[max_tx_size];
3446 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003447 int idx, idy;
3448 int block = 0;
Jingning Han63cbf342016-11-09 15:37:48 -08003449 int block32 = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07003450 int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003451 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
3452 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
3453 TXFM_CONTEXT tx_above[MAX_MIB_SIZE];
3454 TXFM_CONTEXT tx_left[MAX_MIB_SIZE];
3455
Angie Chiangb5dda482016-11-02 16:19:58 -07003456 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07003457 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003458
Yaowu Xuf883b422016-08-30 14:01:10 -07003459 av1_get_entropy_contexts(bsize, TX_4X4, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003460 memcpy(tx_above, xd->above_txfm_context,
3461 sizeof(TXFM_CONTEXT) * (mi_width >> 1));
3462 memcpy(tx_left, xd->left_txfm_context,
3463 sizeof(TXFM_CONTEXT) * (mi_height >> 1));
3464
3465 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07003466 for (idx = 0; idx < mi_width; idx += bw) {
Jingning Han63cbf342016-11-09 15:37:48 -08003467 select_tx_block(cpi, x, idy, idx, 0, block, block32, max_tx_size,
Jingning Han18482fe2016-11-02 17:01:58 -07003468 mi_height != mi_width, plane_bsize, ctxa, ctxl,
Angie Chiangb5dda482016-11-02 16:19:58 -07003469 tx_above, tx_left, &pn_rd_stats, ref_best_rd - this_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08003470 &is_cost_valid, rd_stats_stack);
Angie Chiangc0feea82016-11-03 15:36:18 -07003471 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Angie Chiangb5dda482016-11-02 16:19:58 -07003472 this_rd += AOMMIN(
3473 RDCOST(x->rdmult, x->rddiv, pn_rd_stats.rate, pn_rd_stats.dist),
3474 RDCOST(x->rdmult, x->rddiv, 0, pn_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003475 block += step;
Jingning Han63cbf342016-11-09 15:37:48 -08003476 ++block32;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003477 }
3478 }
3479 }
3480
Angie Chiangb5dda482016-11-02 16:19:58 -07003481 this_rd = AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
3482 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003483 if (this_rd > ref_best_rd) is_cost_valid = 0;
3484
3485 if (!is_cost_valid) {
3486 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07003487 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003488 }
3489}
3490
Yaowu Xuf883b422016-08-30 14:01:10 -07003491static int64_t select_tx_size_fix_type(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiangb5dda482016-11-02 16:19:58 -07003492 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08003493 int64_t ref_best_rd, TX_TYPE tx_type,
3494 RD_STATS *rd_stats_stack) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003495 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003496 MACROBLOCKD *const xd = &x->e_mbd;
3497 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003498 const int is_inter = is_inter_block(mbmi);
Yaowu Xuf883b422016-08-30 14:01:10 -07003499 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
3500 int s0 = av1_cost_bit(skip_prob, 0);
3501 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003502 int64_t rd;
Jingning Hane67b38a2016-11-04 10:30:00 -07003503 int row, col;
3504 const int max_blocks_high = max_block_high(xd, bsize, 0);
3505 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003506
3507 mbmi->tx_type = tx_type;
Jingning Hane67b38a2016-11-04 10:30:00 -07003508 mbmi->min_tx_size = TX_SIZES_ALL;
Jingning Han63cbf342016-11-09 15:37:48 -08003509 inter_block_yrd(cpi, x, rd_stats, bsize, ref_best_rd, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003510
Angie Chiangb5dda482016-11-02 16:19:58 -07003511 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003512
Jingning Hane67b38a2016-11-04 10:30:00 -07003513 for (row = 0; row < max_blocks_high / 2; ++row)
3514 for (col = 0; col < max_blocks_wide / 2; ++col)
3515 mbmi->min_tx_size = AOMMIN(
3516 mbmi->min_tx_size, get_min_tx_size(mbmi->inter_tx_size[row][col]));
3517
Yaowu Xuc27fc142016-08-22 16:08:15 -07003518#if CONFIG_EXT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07003519 if (get_ext_tx_types(mbmi->min_tx_size, bsize, is_inter) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003520 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Jingning Hane67b38a2016-11-04 10:30:00 -07003521 int ext_tx_set = get_ext_tx_set(mbmi->min_tx_size, bsize, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003522 if (is_inter) {
3523 if (ext_tx_set > 0)
Angie Chiangb5dda482016-11-02 16:19:58 -07003524 rd_stats->rate +=
Jingning Hane67b38a2016-11-04 10:30:00 -07003525 cpi->inter_tx_type_costs[ext_tx_set]
3526 [txsize_sqr_map[mbmi->min_tx_size]]
Peter de Rivazb85a5a72016-10-18 11:47:56 +01003527 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003528 } else {
3529 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Jingning Hane67b38a2016-11-04 10:30:00 -07003530 rd_stats->rate +=
3531 cpi->intra_tx_type_costs[ext_tx_set][mbmi->min_tx_size][mbmi->mode]
3532 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003533 }
3534 }
3535#else // CONFIG_EXT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07003536 if (mbmi->min_tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id])
3537 rd_stats->rate +=
3538 cpi->inter_tx_type_costs[mbmi->min_tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003539#endif // CONFIG_EXT_TX
3540
Angie Chiangb5dda482016-11-02 16:19:58 -07003541 if (rd_stats->skip)
3542 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003543 else
Angie Chiangb5dda482016-11-02 16:19:58 -07003544 rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate + s0, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003545
Angie Chiangb5dda482016-11-02 16:19:58 -07003546 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
3547 !(rd_stats->skip))
3548 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003549
3550 return rd;
3551}
3552
Angie Chiangb5dda482016-11-02 16:19:58 -07003553static void select_tx_type_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
3554 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003555 int64_t ref_best_rd) {
3556 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
3557 MACROBLOCKD *const xd = &x->e_mbd;
3558 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3559 int64_t rd = INT64_MAX;
3560 int64_t best_rd = INT64_MAX;
3561 TX_TYPE tx_type, best_tx_type = DCT_DCT;
3562 const int is_inter = is_inter_block(mbmi);
3563 TX_SIZE best_tx_size[MAX_MIB_SIZE][MAX_MIB_SIZE];
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07003564 TX_SIZE best_tx = max_txsize_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07003565 TX_SIZE best_min_tx_size = TX_SIZES_ALL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003566 uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
3567 const int n4 = 1 << (num_pels_log2_lookup[bsize] - 4);
3568 int idx, idy;
3569 int prune = 0;
Jingning Han89d648b2016-11-22 11:22:08 -08003570 const int count32 = 1 << (2 * (cpi->common.mib_size_log2 -
3571 mi_width_log2_lookup[BLOCK_32X32]));
3572#if CONFIG_EXT_PARTITION
3573 RD_STATS rd_stats_stack[16];
3574#else
Jingning Han63cbf342016-11-09 15:37:48 -08003575 RD_STATS rd_stats_stack[4];
Jingning Han89d648b2016-11-22 11:22:08 -08003576#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003577#if CONFIG_EXT_TX
3578 int ext_tx_set = get_ext_tx_set(max_tx_size, bsize, is_inter);
3579#endif // CONFIG_EXT_TX
3580
3581 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
3582#if CONFIG_EXT_TX
3583 prune = prune_tx_types(cpi, bsize, x, xd, ext_tx_set);
3584#else
3585 prune = prune_tx_types(cpi, bsize, x, xd, 0);
3586#endif
3587
Angie Chiangc0feea82016-11-03 15:36:18 -07003588 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003589
Jingning Han89d648b2016-11-22 11:22:08 -08003590 for (idx = 0; idx < count32; ++idx)
3591 av1_invalid_rd_stats(&rd_stats_stack[idx]);
Jingning Han63cbf342016-11-09 15:37:48 -08003592
Yaowu Xuc27fc142016-08-22 16:08:15 -07003593 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiangb5dda482016-11-02 16:19:58 -07003594 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07003595 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003596#if CONFIG_EXT_TX
3597 if (is_inter) {
3598 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
3599 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
3600 if (!do_tx_type_search(tx_type, prune)) continue;
3601 }
3602 } else {
3603 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
3604 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
3605 }
3606 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
3607 }
3608#else // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003609 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
3610 !do_tx_type_search(tx_type, prune))
3611 continue;
3612#endif // CONFIG_EXT_TX
3613 if (is_inter && x->use_default_inter_tx_type &&
3614 tx_type != get_default_tx_type(0, xd, 0, max_tx_size))
3615 continue;
3616
Jingning Hane67b38a2016-11-04 10:30:00 -07003617 if (xd->lossless[mbmi->segment_id])
3618 if (tx_type != DCT_DCT) continue;
3619
Angie Chiangb5dda482016-11-02 16:19:58 -07003620 rd = select_tx_size_fix_type(cpi, x, &this_rd_stats, bsize, ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08003621 tx_type, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003622
3623 if (rd < best_rd) {
3624 best_rd = rd;
Angie Chiangb5dda482016-11-02 16:19:58 -07003625 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003626 best_tx_type = mbmi->tx_type;
3627 best_tx = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -07003628 best_min_tx_size = mbmi->min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003629 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
3630 for (idy = 0; idy < xd->n8_h; ++idy)
3631 for (idx = 0; idx < xd->n8_w; ++idx)
3632 best_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
3633 }
3634 }
3635
3636 mbmi->tx_type = best_tx_type;
3637 for (idy = 0; idy < xd->n8_h; ++idy)
3638 for (idx = 0; idx < xd->n8_w; ++idx)
3639 mbmi->inter_tx_size[idy][idx] = best_tx_size[idy][idx];
3640 mbmi->tx_size = best_tx;
Jingning Hane67b38a2016-11-04 10:30:00 -07003641 mbmi->min_tx_size = best_min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003642 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
3643}
3644
Yaowu Xuf883b422016-08-30 14:01:10 -07003645static void tx_block_rd(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003646 int blk_col, int plane, int block, TX_SIZE tx_size,
3647 BLOCK_SIZE plane_bsize, ENTROPY_CONTEXT *above_ctx,
Angie Chiangb5dda482016-11-02 16:19:58 -07003648 ENTROPY_CONTEXT *left_ctx, RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003649 MACROBLOCKD *const xd = &x->e_mbd;
3650 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3651 struct macroblock_plane *const p = &x->plane[plane];
3652 struct macroblockd_plane *const pd = &xd->plane[plane];
3653 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
3654 const int tx_row = blk_row >> (1 - pd->subsampling_y);
3655 const int tx_col = blk_col >> (1 - pd->subsampling_x);
3656 TX_SIZE plane_tx_size;
Jingning Han18482fe2016-11-02 17:01:58 -07003657 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
3658 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003659
Jingning Hand3fada82016-11-22 10:46:55 -08003660 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003661
Yaowu Xuc27fc142016-08-22 16:08:15 -07003662 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
3663
Debargha Mukherjee2f123402016-08-30 17:43:38 -07003664 plane_tx_size =
3665 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
3666 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003667
3668 if (tx_size == plane_tx_size) {
3669 int coeff_ctx, i;
3670 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
3671 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
Jingning Han18482fe2016-11-02 17:01:58 -07003672 coeff_ctx = get_entropy_context(tx_size, ta, tl);
Yaowu Xuf883b422016-08-30 14:01:10 -07003673 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiangb5dda482016-11-02 16:19:58 -07003674 plane_bsize, coeff_ctx, rd_stats);
Jingning Han607fa6a2016-10-26 10:46:28 -07003675
Jingning Han58224042016-10-27 16:35:32 -07003676 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003677 ta[i] = !(p->eobs[block] == 0);
Jingning Han58224042016-10-27 16:35:32 -07003678 for (i = 0; i < tx_size_high_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003679 tl[i] = !(p->eobs[block] == 0);
3680 } else {
Jingning Han18482fe2016-11-02 17:01:58 -07003681 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
3682 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07003683 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003684 int i;
3685
3686 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003687
3688 for (i = 0; i < 4; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07003689 int offsetr = blk_row + (i >> 1) * bsl;
3690 int offsetc = blk_col + (i & 0x01) * bsl;
3691
3692 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
3693
3694 tx_block_rd(cpi, x, offsetr, offsetc, plane, block, sub_txs, plane_bsize,
3695 above_ctx, left_ctx, rd_stats);
3696 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003697 }
3698 }
3699}
3700
3701// Return value 0: early termination triggered, no valid rd cost available;
3702// 1: rd cost values are valid.
Angie Chiangb5dda482016-11-02 16:19:58 -07003703static int inter_block_uvrd(const AV1_COMP *cpi, MACROBLOCK *x,
3704 RD_STATS *rd_stats, BLOCK_SIZE bsize,
3705 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003706 MACROBLOCKD *const xd = &x->e_mbd;
3707 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3708 int plane;
3709 int is_cost_valid = 1;
3710 int64_t this_rd;
3711
3712 if (ref_best_rd < 0) is_cost_valid = 0;
3713
Angie Chiangc0feea82016-11-03 15:36:18 -07003714 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003715
3716#if CONFIG_EXT_TX && CONFIG_RECT_TX
3717 if (is_rect_tx(mbmi->tx_size)) {
Angie Chiang284d7772016-11-08 11:06:45 -08003718 return super_block_uvrd(cpi, x, rd_stats, bsize, ref_best_rd);
Yue Chena1e48dc2016-08-29 17:29:33 -07003719 }
3720#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
3721
Yaowu Xuc27fc142016-08-22 16:08:15 -07003722 if (is_inter_block(mbmi) && is_cost_valid) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003723 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
Yaowu Xuf883b422016-08-30 14:01:10 -07003724 av1_subtract_plane(x, bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003725 }
3726
Yaowu Xuc27fc142016-08-22 16:08:15 -07003727 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
3728 const struct macroblockd_plane *const pd = &xd->plane[plane];
3729 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
3730 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
3731 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han70e5f3f2016-11-09 17:03:07 -08003732 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07003733 const int bh = tx_size_high_unit[max_tx_size];
3734 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003735 int idx, idy;
3736 int block = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07003737 const int step = bh * bw;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003738 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE];
3739 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE];
Angie Chiangb5dda482016-11-02 16:19:58 -07003740 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07003741 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003742
Yaowu Xuf883b422016-08-30 14:01:10 -07003743 av1_get_entropy_contexts(bsize, TX_4X4, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003744
3745 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07003746 for (idx = 0; idx < mi_width; idx += bw) {
3747 tx_block_rd(cpi, x, idy, idx, plane, block, max_tx_size, plane_bsize,
Angie Chiangb5dda482016-11-02 16:19:58 -07003748 ta, tl, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003749 block += step;
3750 }
3751 }
3752
Angie Chiangb5dda482016-11-02 16:19:58 -07003753 if (pn_rd_stats.rate == INT_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003754 is_cost_valid = 0;
3755 break;
3756 }
3757
Angie Chiang628d7c92016-11-03 16:24:56 -07003758 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003759
Angie Chiangb5dda482016-11-02 16:19:58 -07003760 this_rd =
3761 AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
3762 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003763
3764 if (this_rd > ref_best_rd) {
3765 is_cost_valid = 0;
3766 break;
3767 }
3768 }
3769
3770 if (!is_cost_valid) {
3771 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07003772 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003773 }
3774
3775 return is_cost_valid;
3776}
3777#endif // CONFIG_VAR_TX
3778
Urvang Joshib100db72016-10-12 16:28:56 -07003779#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003780static void rd_pick_palette_intra_sbuv(
Urvang Joshi52648442016-10-13 17:27:51 -07003781 const AV1_COMP *const cpi, MACROBLOCK *x, int dc_mode_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003782 PALETTE_MODE_INFO *palette_mode_info, uint8_t *best_palette_color_map,
3783 PREDICTION_MODE *mode_selected, int64_t *best_rd, int *rate,
3784 int *rate_tokenonly, int64_t *distortion, int *skippable) {
3785 MACROBLOCKD *const xd = &x->e_mbd;
3786 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3787 const BLOCK_SIZE bsize = mbmi->sb_type;
Jingning Hanae5cfde2016-11-30 12:01:44 -08003788 const int rows = block_size_high[bsize] >> (xd->plane[1].subsampling_y);
3789 const int cols = block_size_wide[bsize] >> (xd->plane[1].subsampling_x);
Angie Chiang284d7772016-11-08 11:06:45 -08003790 int this_rate;
3791 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003792 int colors_u, colors_v, colors;
3793 const int src_stride = x->plane[1].src.stride;
3794 const uint8_t *const src_u = x->plane[1].src.buf;
3795 const uint8_t *const src_v = x->plane[2].src.buf;
Angie Chiang284d7772016-11-08 11:06:45 -08003796 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003797
3798 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return;
3799
hui su5db97432016-10-14 16:10:14 -07003800#if CONFIG_FILTER_INTRA
3801 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
3802#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003803
Yaowu Xuf883b422016-08-30 14:01:10 -07003804#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003805 if (cpi->common.use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003806 colors_u = av1_count_colors_highbd(src_u, src_stride, rows, cols,
3807 cpi->common.bit_depth);
3808 colors_v = av1_count_colors_highbd(src_v, src_stride, rows, cols,
3809 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003810 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003811#endif // CONFIG_AOM_HIGHBITDEPTH
3812 colors_u = av1_count_colors(src_u, src_stride, rows, cols);
3813 colors_v = av1_count_colors(src_v, src_stride, rows, cols);
3814#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003815 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003816#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003817
3818 colors = colors_u > colors_v ? colors_u : colors_v;
3819 if (colors > 1 && colors <= 64) {
3820 int r, c, n, i, j;
3821 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07003822 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003823 float lb_u, ub_u, val_u;
3824 float lb_v, ub_v, val_v;
3825 float *const data = x->palette_buffer->kmeans_data_buf;
3826 float centroids[2 * PALETTE_MAX_SIZE];
3827 uint8_t *const color_map = xd->plane[1].color_index_map;
3828 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
3829
Yaowu Xuf883b422016-08-30 14:01:10 -07003830#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003831 uint16_t *src_u16 = CONVERT_TO_SHORTPTR(src_u);
3832 uint16_t *src_v16 = CONVERT_TO_SHORTPTR(src_v);
3833 if (cpi->common.use_highbitdepth) {
3834 lb_u = src_u16[0];
3835 ub_u = src_u16[0];
3836 lb_v = src_v16[0];
3837 ub_v = src_v16[0];
3838 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003839#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003840 lb_u = src_u[0];
3841 ub_u = src_u[0];
3842 lb_v = src_v[0];
3843 ub_v = src_v[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07003844#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003845 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003846#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003847
3848 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07003849#if CONFIG_FILTER_INTRA
3850 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
3851#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003852 for (r = 0; r < rows; ++r) {
3853 for (c = 0; c < cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003854#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003855 if (cpi->common.use_highbitdepth) {
3856 val_u = src_u16[r * src_stride + c];
3857 val_v = src_v16[r * src_stride + c];
3858 data[(r * cols + c) * 2] = val_u;
3859 data[(r * cols + c) * 2 + 1] = val_v;
3860 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003861#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003862 val_u = src_u[r * src_stride + c];
3863 val_v = src_v[r * src_stride + c];
3864 data[(r * cols + c) * 2] = val_u;
3865 data[(r * cols + c) * 2 + 1] = val_v;
Yaowu Xuf883b422016-08-30 14:01:10 -07003866#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003867 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003868#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003869 if (val_u < lb_u)
3870 lb_u = val_u;
3871 else if (val_u > ub_u)
3872 ub_u = val_u;
3873 if (val_v < lb_v)
3874 lb_v = val_v;
3875 else if (val_v > ub_v)
3876 ub_v = val_v;
3877 }
3878 }
3879
3880 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
3881 --n) {
3882 for (i = 0; i < n; ++i) {
3883 centroids[i * 2] = lb_u + (2 * i + 1) * (ub_u - lb_u) / n / 2;
3884 centroids[i * 2 + 1] = lb_v + (2 * i + 1) * (ub_v - lb_v) / n / 2;
3885 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003886 av1_k_means(data, centroids, color_map, rows * cols, n, 2, max_itr);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003887 pmi->palette_size[1] = n;
3888 for (i = 1; i < 3; ++i) {
3889 for (j = 0; j < n; ++j) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003890#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003891 if (cpi->common.use_highbitdepth)
3892 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] = clip_pixel_highbd(
3893 (int)centroids[j * 2 + i - 1], cpi->common.bit_depth);
3894 else
Yaowu Xuf883b422016-08-30 14:01:10 -07003895#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003896 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
3897 clip_pixel((int)centroids[j * 2 + i - 1]);
3898 }
3899 }
3900
Angie Chiang284d7772016-11-08 11:06:45 -08003901 super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
3902 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003903 this_rate =
Angie Chiang284d7772016-11-08 11:06:45 -08003904 tokenonly_rd_stats.rate + dc_mode_cost +
Yaowu Xuf883b422016-08-30 14:01:10 -07003905 2 * cpi->common.bit_depth * n * av1_cost_bit(128, 0) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003906 cpi->palette_uv_size_cost[bsize - BLOCK_8X8][n - 2] +
3907 write_uniform_cost(n, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07003908 av1_cost_bit(
3909 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003910
3911 for (i = 0; i < rows; ++i) {
3912 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07003913 int color_idx;
3914 const int color_ctx = av1_get_palette_color_context(
3915 color_map, cols, i, j, n, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003916 assert(color_idx >= 0 && color_idx < n);
3917 this_rate += cpi->palette_uv_color_cost[n - 2][color_ctx][color_idx];
3918 }
3919 }
3920
Angie Chiang284d7772016-11-08 11:06:45 -08003921 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003922 if (this_rd < *best_rd) {
3923 *best_rd = this_rd;
3924 *palette_mode_info = *pmi;
3925 memcpy(best_palette_color_map, color_map,
3926 rows * cols * sizeof(best_palette_color_map[0]));
3927 *mode_selected = DC_PRED;
3928 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08003929 *distortion = tokenonly_rd_stats.dist;
3930 *rate_tokenonly = tokenonly_rd_stats.rate;
3931 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003932 }
3933 }
3934 }
3935}
Urvang Joshib100db72016-10-12 16:28:56 -07003936#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003937
hui su5db97432016-10-14 16:10:14 -07003938#if CONFIG_FILTER_INTRA
3939// Return 1 if an filter intra mode is selected; return 0 otherwise.
3940static int rd_pick_filter_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
3941 int *rate, int *rate_tokenonly,
3942 int64_t *distortion, int *skippable,
3943 BLOCK_SIZE bsize, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003944 MACROBLOCKD *const xd = &x->e_mbd;
3945 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su5db97432016-10-14 16:10:14 -07003946 int filter_intra_selected_flag = 0;
Angie Chiang284d7772016-11-08 11:06:45 -08003947 int this_rate;
3948 int64_t this_rd;
hui su5db97432016-10-14 16:10:14 -07003949 FILTER_INTRA_MODE mode;
3950 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Angie Chiang284d7772016-11-08 11:06:45 -08003951 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003952
hui su5db97432016-10-14 16:10:14 -07003953 av1_zero(filter_intra_mode_info);
3954 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003955 mbmi->uv_mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07003956#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003957 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003958#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003959
3960 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su5db97432016-10-14 16:10:14 -07003961 mbmi->filter_intra_mode_info.filter_intra_mode[1] = mode;
Angie Chiang284d7772016-11-08 11:06:45 -08003962 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07003963 continue;
3964
Angie Chiang284d7772016-11-08 11:06:45 -08003965 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07003966 av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003967 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
3968 write_uniform_cost(FILTER_INTRA_MODES, mode);
Angie Chiang284d7772016-11-08 11:06:45 -08003969 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003970 if (this_rd < *best_rd) {
3971 *best_rd = this_rd;
3972 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08003973 *rate_tokenonly = tokenonly_rd_stats.rate;
3974 *distortion = tokenonly_rd_stats.dist;
3975 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07003976 filter_intra_mode_info = mbmi->filter_intra_mode_info;
3977 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003978 }
3979 }
3980
hui su5db97432016-10-14 16:10:14 -07003981 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003982 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07003983 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
3984 filter_intra_mode_info.use_filter_intra_mode[1];
3985 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
3986 filter_intra_mode_info.filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003987 return 1;
3988 } else {
3989 return 0;
3990 }
3991}
hui su5db97432016-10-14 16:10:14 -07003992#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003993
hui su5db97432016-10-14 16:10:14 -07003994#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08003995// Run RD calculation with given chroma intra prediction angle., and return
3996// the RD cost. Update the best mode info. if the RD cost is the best so far.
3997static int64_t pick_intra_angle_routine_sbuv(
3998 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
3999 int rate_overhead, int64_t best_rd_in, int *rate, RD_STATS *rd_stats,
4000 int *best_angle_delta, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004001 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Angie Chiang284d7772016-11-08 11:06:45 -08004002 int this_rate;
4003 int64_t this_rd;
4004 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004005
hui su45dc5972016-12-08 17:42:50 -08004006 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in))
4007 return INT64_MAX;
Angie Chiang284d7772016-11-08 11:06:45 -08004008 this_rate = tokenonly_rd_stats.rate + rate_overhead;
4009 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004010 if (this_rd < *best_rd) {
4011 *best_rd = this_rd;
4012 *best_angle_delta = mbmi->angle_delta[1];
4013 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08004014 rd_stats->rate = tokenonly_rd_stats.rate;
4015 rd_stats->dist = tokenonly_rd_stats.dist;
4016 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004017 }
hui su45dc5972016-12-08 17:42:50 -08004018 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004019}
4020
hui su45dc5972016-12-08 17:42:50 -08004021// With given chroma directional intra prediction mode, pick the best angle
4022// delta. Return true if a RD cost that is smaller than the input one is found.
Urvang Joshi52648442016-10-13 17:27:51 -07004023static int rd_pick_intra_angle_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
Urvang Joshi52648442016-10-13 17:27:51 -07004024 BLOCK_SIZE bsize, int rate_overhead,
hui su45dc5972016-12-08 17:42:50 -08004025 int64_t best_rd, int *rate,
4026 RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004027 MACROBLOCKD *const xd = &x->e_mbd;
4028 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su45dc5972016-12-08 17:42:50 -08004029 int i, angle_delta, best_angle_delta = 0;
4030 int64_t this_rd, best_rd_in, rd_cost[2 * (MAX_ANGLE_DELTA_UV + 2)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004031
hui su45dc5972016-12-08 17:42:50 -08004032 rd_stats->rate = INT_MAX;
4033 rd_stats->skip = 0;
4034 rd_stats->dist = INT64_MAX;
4035 for (i = 0; i < 2 * (MAX_ANGLE_DELTA_UV + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004036
hui su45dc5972016-12-08 17:42:50 -08004037 for (angle_delta = 0; angle_delta <= MAX_ANGLE_DELTA_UV; angle_delta += 2) {
4038 for (i = 0; i < 2; ++i) {
4039 best_rd_in = (best_rd == INT64_MAX)
4040 ? INT64_MAX
4041 : (best_rd + (best_rd >> ((angle_delta == 0) ? 3 : 5)));
4042 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
4043 this_rd = pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead,
4044 best_rd_in, rate, rd_stats,
4045 &best_angle_delta, &best_rd);
4046 rd_cost[2 * angle_delta + i] = this_rd;
4047 if (angle_delta == 0) {
4048 if (this_rd == INT64_MAX) return 0;
4049 rd_cost[1] = this_rd;
4050 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004051 }
4052 }
hui su45dc5972016-12-08 17:42:50 -08004053 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004054
hui su45dc5972016-12-08 17:42:50 -08004055 assert(best_rd != INT64_MAX);
4056 for (angle_delta = 1; angle_delta <= MAX_ANGLE_DELTA_UV; angle_delta += 2) {
4057 int64_t rd_thresh;
4058 for (i = 0; i < 2; ++i) {
4059 int skip_search = 0;
4060 rd_thresh = best_rd + (best_rd >> 5);
4061 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
4062 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
4063 skip_search = 1;
4064 if (!skip_search) {
4065 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
4066 this_rd = pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead,
4067 best_rd, rate, rd_stats,
4068 &best_angle_delta, &best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004069 }
4070 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004071 }
4072
4073 mbmi->angle_delta[1] = best_angle_delta;
hui su45dc5972016-12-08 17:42:50 -08004074 return rd_stats->rate != INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004075}
4076#endif // CONFIG_EXT_INTRA
4077
Urvang Joshi52648442016-10-13 17:27:51 -07004078static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
4079 int *rate, int *rate_tokenonly,
4080 int64_t *distortion, int *skippable,
4081 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004082 MACROBLOCKD *xd = &x->e_mbd;
4083 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4084 PREDICTION_MODE mode;
4085 PREDICTION_MODE mode_selected = DC_PRED;
4086 int64_t best_rd = INT64_MAX, this_rd;
Angie Chiang284d7772016-11-08 11:06:45 -08004087 int this_rate;
4088 RD_STATS tokenonly_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004089#if CONFIG_PVQ
4090 od_rollback_buffer buf;
4091
4092 od_encode_checkpoint(&x->daala_enc, &buf);
4093#endif
Urvang Joshib100db72016-10-12 16:28:56 -07004094#if CONFIG_PALETTE
Jingning Hanae5cfde2016-11-30 12:01:44 -08004095 const int rows = block_size_high[bsize] >> (xd->plane[1].subsampling_y);
4096 const int cols = block_size_wide[bsize] >> (xd->plane[1].subsampling_x);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004097 PALETTE_MODE_INFO palette_mode_info;
4098 PALETTE_MODE_INFO *const pmi = &xd->mi[0]->mbmi.palette_mode_info;
4099 uint8_t *best_palette_color_map = NULL;
Urvang Joshib100db72016-10-12 16:28:56 -07004100#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004101#if CONFIG_EXT_INTRA
4102 int is_directional_mode, rate_overhead, best_angle_delta = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004103#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07004104#if CONFIG_FILTER_INTRA
4105 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
4106
4107 filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4108 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4109#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004110#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004111 palette_mode_info.palette_size[1] = 0;
4112 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004113#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004114 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
4115 if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode))) continue;
4116
4117 mbmi->uv_mode = mode;
4118#if CONFIG_EXT_INTRA
hui su0c628e62016-11-30 15:20:48 -08004119 is_directional_mode = av1_is_directional_mode(mode, mbmi->sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004120 rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
hui su45dc5972016-12-08 17:42:50 -08004121 write_uniform_cost(2 * MAX_ANGLE_DELTA_UV + 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004122 mbmi->angle_delta[1] = 0;
hui su0c628e62016-11-30 15:20:48 -08004123 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -08004124 if (!rd_pick_intra_angle_sbuv(cpi, x, bsize, rate_overhead, best_rd,
4125 &this_rate, &tokenonly_rd_stats))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004126 continue;
4127 } else {
Angie Chiang284d7772016-11-08 11:06:45 -08004128 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd)) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004129#if CONFIG_PVQ
4130 od_encode_rollback(&x->daala_enc, &buf);
4131#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004132 continue;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004133 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004134 }
Angie Chiang284d7772016-11-08 11:06:45 -08004135 this_rate =
4136 tokenonly_rd_stats.rate + cpi->intra_uv_mode_cost[mbmi->mode][mode];
hui su45dc5972016-12-08 17:42:50 -08004137 if (is_directional_mode) {
4138 this_rate +=
4139 write_uniform_cost(2 * MAX_ANGLE_DELTA_UV + 1,
4140 MAX_ANGLE_DELTA_UV + mbmi->angle_delta[1]);
4141 }
4142#else // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08004143 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd)) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004144#if CONFIG_PVQ
4145 od_encode_rollback(&x->daala_enc, &buf);
4146#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004147 continue;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004148 }
Angie Chiang284d7772016-11-08 11:06:45 -08004149 this_rate =
4150 tokenonly_rd_stats.rate + cpi->intra_uv_mode_cost[mbmi->mode][mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004151#endif // CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08004152
hui su5db97432016-10-14 16:10:14 -07004153#if CONFIG_FILTER_INTRA
4154 if (mbmi->sb_type >= BLOCK_8X8 && mode == DC_PRED)
4155 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 0);
4156#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004157#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004158 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8 &&
4159 mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07004160 this_rate += av1_cost_bit(
4161 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07004162#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004163
Yushin Cho77bba8d2016-11-04 16:36:56 -07004164#if CONFIG_PVQ
4165 // For chroma channels, multiply lambda by 0.5 when doing intra prediction
4166 // NOTE: Chroma intra prediction itself has a separate RDO,
4167 // though final chroma intra mode's D and R is simply added to
4168 // those of luma then global RDO is performed to decide the modes of SB.
4169 // Also, for chroma, the RDO cannot decide tx_size (follow luma's decision)
4170 // or tx_type (DCT only), then only the intra prediction is
4171 // chroma's own mode decision based on separate RDO.
4172 // TODO(yushin) : Seek for more reasonable solution than this.
4173 this_rd = RDCOST(x->rdmult >> (1 * PVQ_CHROMA_RD), x->rddiv, this_rate,
Angie Chiang284d7772016-11-08 11:06:45 -08004174 tokenonly_rd_stats.dist);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004175 od_encode_rollback(&x->daala_enc, &buf);
4176#else
Angie Chiang284d7772016-11-08 11:06:45 -08004177 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004178#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004179
4180 if (this_rd < best_rd) {
4181 mode_selected = mode;
4182#if CONFIG_EXT_INTRA
4183 best_angle_delta = mbmi->angle_delta[1];
4184#endif // CONFIG_EXT_INTRA
4185 best_rd = this_rd;
4186 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004187 *rate_tokenonly = tokenonly_rd_stats.rate;
4188 *distortion = tokenonly_rd_stats.dist;
4189 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004190 }
4191 }
4192
Urvang Joshib100db72016-10-12 16:28:56 -07004193#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004194 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8) {
4195 best_palette_color_map = x->palette_buffer->best_palette_color_map;
4196 rd_pick_palette_intra_sbuv(
4197 cpi, x, cpi->intra_uv_mode_cost[mbmi->mode][DC_PRED],
4198 &palette_mode_info, best_palette_color_map, &mode_selected, &best_rd,
4199 rate, rate_tokenonly, distortion, skippable);
4200 }
Urvang Joshib100db72016-10-12 16:28:56 -07004201#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004202
hui su5db97432016-10-14 16:10:14 -07004203#if CONFIG_FILTER_INTRA
4204 if (mbmi->sb_type >= BLOCK_8X8) {
4205 if (rd_pick_filter_intra_sbuv(cpi, x, rate, rate_tokenonly, distortion,
4206 skippable, bsize, &best_rd)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004207 mode_selected = mbmi->uv_mode;
hui su5db97432016-10-14 16:10:14 -07004208 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004209 }
4210 }
4211
hui su5db97432016-10-14 16:10:14 -07004212 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
4213 filter_intra_mode_info.use_filter_intra_mode[1];
4214 if (filter_intra_mode_info.use_filter_intra_mode[1]) {
4215 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
4216 filter_intra_mode_info.filter_intra_mode[1];
Urvang Joshib100db72016-10-12 16:28:56 -07004217#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004218 palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004219#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004220 }
hui su5db97432016-10-14 16:10:14 -07004221#endif // CONFIG_FILTER_INTRA
4222
4223#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004224 mbmi->angle_delta[1] = best_angle_delta;
4225#endif // CONFIG_EXT_INTRA
4226 mbmi->uv_mode = mode_selected;
Urvang Joshib100db72016-10-12 16:28:56 -07004227#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004228 pmi->palette_size[1] = palette_mode_info.palette_size[1];
4229 if (palette_mode_info.palette_size[1] > 0) {
4230 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
4231 palette_mode_info.palette_colors + PALETTE_MAX_SIZE,
4232 2 * PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
4233 memcpy(xd->plane[1].color_index_map, best_palette_color_map,
4234 rows * cols * sizeof(best_palette_color_map[0]));
4235 }
Urvang Joshib100db72016-10-12 16:28:56 -07004236#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004237
4238 return best_rd;
4239}
4240
Urvang Joshi52648442016-10-13 17:27:51 -07004241static void choose_intra_uv_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004242 PICK_MODE_CONTEXT *ctx, BLOCK_SIZE bsize,
4243 TX_SIZE max_tx_size, int *rate_uv,
4244 int *rate_uv_tokenonly, int64_t *dist_uv,
4245 int *skip_uv, PREDICTION_MODE *mode_uv) {
4246 // Use an estimated rd for uv_intra based on DC_PRED if the
4247 // appropriate speed flag is set.
Jingning Han3f167252016-06-07 16:11:42 -07004248 (void)ctx;
Jingning Han271bb2c2016-12-14 12:34:46 -08004249#if CONFIG_CB4X4
4250 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4251 bsize, max_tx_size);
4252#else
Jingning Han3f167252016-06-07 16:11:42 -07004253 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4254 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
Jingning Han271bb2c2016-12-14 12:34:46 -08004255#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004256 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
4257}
4258
Urvang Joshi52648442016-10-13 17:27:51 -07004259static int cost_mv_ref(const AV1_COMP *const cpi, PREDICTION_MODE mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004260#if CONFIG_REF_MV && CONFIG_EXT_INTER
4261 int is_compound,
4262#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4263 int16_t mode_context) {
4264#if CONFIG_REF_MV
4265 int mode_cost = 0;
4266#if CONFIG_EXT_INTER
4267 int16_t mode_ctx =
4268 is_compound ? mode_context : (mode_context & NEWMV_CTX_MASK);
4269#else
4270 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
4271#endif // CONFIG_EXT_INTER
4272 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
4273
4274 assert(is_inter_mode(mode));
4275
4276#if CONFIG_EXT_INTER
4277 if (is_compound) {
clang-format67948d32016-09-07 22:40:40 -07004278 return cpi->inter_compound_mode_cost[mode_context]
4279 [INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004280 } else {
4281 if (mode == NEWMV || mode == NEWFROMNEARMV) {
4282#else
4283 if (mode == NEWMV) {
4284#endif // CONFIG_EXT_INTER
4285 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
4286#if CONFIG_EXT_INTER
4287 if (!is_compound)
4288 mode_cost += cpi->new2mv_mode_cost[mode == NEWFROMNEARMV];
4289#endif // CONFIG_EXT_INTER
4290 return mode_cost;
4291 } else {
4292 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
4293 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
4294
4295 if (is_all_zero_mv) return mode_cost;
4296
4297 if (mode == ZEROMV) {
4298 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
4299 return mode_cost;
4300 } else {
4301 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
4302 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
4303
4304 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
4305 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
4306 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
4307
4308 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
4309 return mode_cost;
4310 }
4311 }
4312#if CONFIG_EXT_INTER
4313 }
4314#endif // CONFIG_EXT_INTER
4315#else
4316 assert(is_inter_mode(mode));
4317#if CONFIG_EXT_INTER
4318 if (is_inter_compound_mode(mode)) {
clang-format67948d32016-09-07 22:40:40 -07004319 return cpi->inter_compound_mode_cost[mode_context]
4320 [INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004321 } else {
4322#endif // CONFIG_EXT_INTER
4323 return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
4324#if CONFIG_EXT_INTER
4325 }
4326#endif // CONFIG_EXT_INTER
4327#endif
4328}
4329
Sarah Parker6fdc8532016-11-16 17:47:13 -08004330#if CONFIG_EXT_INTER
4331static int get_interinter_compound_type_bits(BLOCK_SIZE bsize,
4332 COMPOUND_TYPE comp_type) {
4333 switch (comp_type) {
4334 case COMPOUND_AVERAGE: return 0;
4335 case COMPOUND_WEDGE: return get_interinter_wedge_bits(bsize);
Sarah Parker2f6ce752016-12-08 15:26:46 -08004336#if CONFIG_COMPOUND_SEGMENT
4337 // TODO(sarahparker) this 0 is just a placeholder, it is possible this will
4338 // need to change once this mode is fully implemented
4339 case COMPOUND_SEG: return 0;
4340#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08004341 default: assert(0); return 0;
4342 }
4343}
4344#endif // CONFIG_EXT_INTER
4345
Sarah Parkere5299862016-08-16 14:57:37 -07004346#if CONFIG_GLOBAL_MOTION
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08004347static int GLOBAL_MOTION_RATE(const AV1_COMP *const cpi, int ref) {
4348 static const int gm_amortization_blks[TRANS_TYPES] = { 4, 6, 8, 10, 12 };
Debargha Mukherjee9febfc12016-12-07 13:20:44 -08004349 static const int gm_params_cost[TRANS_TYPES] = {
4350 GM_IDENTITY_BITS, GM_TRANSLATION_BITS, GM_ROTZOOM_BITS,
4351 GM_AFFINE_BITS, GM_HOMOGRAPHY_BITS,
4352 };
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08004353 const WarpedMotionParams *gm = &cpi->common.global_motion[(ref)];
Debargha Mukherjee9febfc12016-12-07 13:20:44 -08004354 assert(gm->wmtype < GLOBAL_TRANS_TYPES);
Debargha Mukherjee705544c2016-11-22 08:55:49 -08004355 if (cpi->global_motion_used[ref][0] >= gm_amortization_blks[gm->wmtype]) {
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08004356 return 0;
4357 } else {
4358 const int cost = (gm_params_cost[gm->wmtype] << AV1_PROB_COST_SHIFT) +
4359 cpi->gmtype_cost[gm->wmtype];
4360 return cost / gm_amortization_blks[gm->wmtype];
4361 }
Sarah Parkere5299862016-08-16 14:57:37 -07004362}
Sarah Parkere5299862016-08-16 14:57:37 -07004363#endif // CONFIG_GLOBAL_MOTION
4364
Urvang Joshi52648442016-10-13 17:27:51 -07004365static int set_and_cost_bmi_mvs(const AV1_COMP *const cpi, MACROBLOCK *x,
4366 MACROBLOCKD *xd, int i, PREDICTION_MODE mode,
4367 int_mv this_mv[2],
clang-format67948d32016-09-07 22:40:40 -07004368 int_mv frame_mv[MB_MODE_COUNT]
4369 [TOTAL_REFS_PER_FRAME],
4370 int_mv seg_mvs[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004371#if CONFIG_EXT_INTER
clang-format67948d32016-09-07 22:40:40 -07004372 int_mv compound_seg_newmvs[2],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004373#endif // CONFIG_EXT_INTER
clang-format67948d32016-09-07 22:40:40 -07004374 int_mv *best_ref_mv[2], const int *mvjcost,
4375 int *mvcost[2]) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004376 MODE_INFO *const mic = xd->mi[0];
4377 const MB_MODE_INFO *const mbmi = &mic->mbmi;
4378 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4379 int thismvcost = 0;
4380 int idx, idy;
4381 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
4382 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
4383 const int is_compound = has_second_ref(mbmi);
Yaowu Xub0d0d002016-11-22 09:26:43 -08004384 int mode_ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004385
4386 switch (mode) {
4387 case NEWMV:
4388#if CONFIG_EXT_INTER
4389 case NEWFROMNEARMV:
4390#endif // CONFIG_EXT_INTER
4391 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
4392#if CONFIG_EXT_INTER
Alex Converse6317c882016-09-29 14:21:37 -07004393 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004394 lower_mv_precision(&this_mv[0].as_mv, 0);
4395#endif // CONFIG_EXT_INTER
4396
4397#if CONFIG_REF_MV
4398 for (idx = 0; idx < 1 + is_compound; ++idx) {
4399 this_mv[idx] = seg_mvs[mbmi->ref_frame[idx]];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07004400 av1_set_mvcost(x, mbmi->ref_frame[idx], idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004401 thismvcost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07004402 av1_mv_bit_cost(&this_mv[idx].as_mv, &best_ref_mv[idx]->as_mv,
4403 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004404 }
4405 (void)mvjcost;
4406 (void)mvcost;
4407#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004408 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4409 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004410#if !CONFIG_EXT_INTER
4411 if (is_compound) {
4412 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07004413 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4414 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004415 }
4416#endif // !CONFIG_EXT_INTER
4417#endif
4418 break;
4419 case NEARMV:
4420 case NEARESTMV:
4421 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4422 if (is_compound)
4423 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4424 break;
4425 case ZEROMV:
Sarah Parkere5299862016-08-16 14:57:37 -07004426#if CONFIG_GLOBAL_MOTION
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004427 this_mv[0].as_int =
David Barkercdcac6d2016-12-01 17:04:16 +00004428 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[0]],
4429 cpi->common.allow_high_precision_mv)
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004430 .as_int;
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08004431 thismvcost += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[0]);
Sarah Parkere5299862016-08-16 14:57:37 -07004432 if (is_compound) {
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004433 this_mv[1].as_int =
David Barkercdcac6d2016-12-01 17:04:16 +00004434 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[1]],
4435 cpi->common.allow_high_precision_mv)
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004436 .as_int;
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08004437 thismvcost += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[1]);
Sarah Parkere5299862016-08-16 14:57:37 -07004438 }
4439#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004440 this_mv[0].as_int = 0;
4441 if (is_compound) this_mv[1].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07004442#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004443 break;
4444#if CONFIG_EXT_INTER
4445 case NEW_NEWMV:
4446 if (compound_seg_newmvs[0].as_int == INVALID_MV ||
4447 compound_seg_newmvs[1].as_int == INVALID_MV) {
4448 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
4449 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
4450 } else {
4451 this_mv[0].as_int = compound_seg_newmvs[0].as_int;
4452 this_mv[1].as_int = compound_seg_newmvs[1].as_int;
4453 }
Alex Converse6317c882016-09-29 14:21:37 -07004454 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004455 lower_mv_precision(&this_mv[0].as_mv, 0);
Alex Converse6317c882016-09-29 14:21:37 -07004456 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004457 lower_mv_precision(&this_mv[1].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07004458 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4459 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
4460 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4461 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004462 break;
4463 case NEW_NEARMV:
4464 case NEW_NEARESTMV:
4465 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07004466 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004467 lower_mv_precision(&this_mv[0].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07004468 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4469 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004470 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4471 break;
4472 case NEAR_NEWMV:
4473 case NEAREST_NEWMV:
4474 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4475 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07004476 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004477 lower_mv_precision(&this_mv[1].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07004478 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4479 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004480 break;
4481 case NEAREST_NEARMV:
4482 case NEAR_NEARESTMV:
4483 case NEAREST_NEARESTMV:
4484 case NEAR_NEARMV:
4485 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4486 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4487 break;
4488 case ZERO_ZEROMV:
4489 this_mv[0].as_int = 0;
4490 this_mv[1].as_int = 0;
4491 break;
4492#endif // CONFIG_EXT_INTER
4493 default: break;
4494 }
4495
4496 mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
4497 if (is_compound) mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
4498
4499 mic->bmi[i].as_mode = mode;
4500
4501#if CONFIG_REF_MV
4502 if (mode == NEWMV) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07004503 mic->bmi[i].pred_mv[0].as_int =
4504 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_int;
4505 if (is_compound)
4506 mic->bmi[i].pred_mv[1].as_int =
4507 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004508 } else {
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07004509 mic->bmi[i].pred_mv[0].as_int = this_mv[0].as_int;
4510 if (is_compound) mic->bmi[i].pred_mv[1].as_int = this_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004511 }
4512#endif
4513
4514 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
4515 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
4516 memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
4517
4518#if CONFIG_REF_MV
4519#if CONFIG_EXT_INTER
4520 if (is_compound)
4521 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
4522 else
4523#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07004524 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
4525 mbmi->ref_frame, mbmi->sb_type, i);
Yaowu Xub0d0d002016-11-22 09:26:43 -08004526#else // CONFIG_REF_MV
4527 mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
4528#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07004529#if CONFIG_REF_MV && CONFIG_EXT_INTER
4530 return cost_mv_ref(cpi, mode, is_compound, mode_ctx) + thismvcost;
4531#else
4532 return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
4533#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4534}
4535
Urvang Joshi52648442016-10-13 17:27:51 -07004536static int64_t encode_inter_mb_segment(const AV1_COMP *const cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004537 int64_t best_yrd, int i, int *labelyrate,
4538 int64_t *distortion, int64_t *sse,
4539 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
4540 int ir, int ic, int mi_row, int mi_col) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004541#if !CONFIG_PVQ
Angie Chiang22ba7512016-10-20 17:10:33 -07004542 const AV1_COMMON *const cm = &cpi->common;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004543#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004544 int k;
4545 MACROBLOCKD *xd = &x->e_mbd;
4546 struct macroblockd_plane *const pd = &xd->plane[0];
4547 struct macroblock_plane *const p = &x->plane[0];
4548 MODE_INFO *const mi = xd->mi[0];
4549 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
Jingning Hanbafee8d2016-12-02 10:25:03 -08004550 const int txb_width = max_block_wide(xd, plane_bsize, 0);
4551 const int txb_height = max_block_high(xd, plane_bsize, 0);
4552#if !CONFIG_PVQ
Jingning Hanc4049db2016-10-27 14:44:13 -07004553 const int width = block_size_wide[plane_bsize];
4554 const int height = block_size_high[plane_bsize];
Jingning Hanbafee8d2016-12-02 10:25:03 -08004555#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004556 int idx, idy;
4557 const uint8_t *const src =
Yaowu Xuf883b422016-08-30 14:01:10 -07004558 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004559 uint8_t *const dst =
Yaowu Xuf883b422016-08-30 14:01:10 -07004560 &pd->dst.buf[av1_raster_block_offset(BLOCK_8X8, i, pd->dst.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004561 int64_t thisdistortion = 0, thissse = 0;
4562 int thisrate = 0;
4563 TX_SIZE tx_size = mi->mbmi.tx_size;
4564
4565 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, i, tx_size);
Jingning Hanc4049db2016-10-27 14:44:13 -07004566 const int num_4x4_w = tx_size_wide_unit[tx_size];
4567 const int num_4x4_h = tx_size_high_unit[tx_size];
Yushin Cho77bba8d2016-11-04 16:36:56 -07004568#if !CONFIG_PVQ
4569 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 1);
4570#else
4571 (void)cpi;
4572 (void)ta;
4573 (void)tl;
4574#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004575
4576#if CONFIG_EXT_TX && CONFIG_RECT_TX
4577 assert(IMPLIES(xd->lossless[mi->mbmi.segment_id], tx_size == TX_4X4));
4578 assert(IMPLIES(!xd->lossless[mi->mbmi.segment_id],
4579 tx_size == max_txsize_rect_lookup[mi->mbmi.sb_type]));
4580#else
4581 assert(tx_size == TX_4X4);
4582#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4583 assert(tx_type == DCT_DCT);
4584
Yaowu Xuf883b422016-08-30 14:01:10 -07004585 av1_build_inter_predictor_sub8x8(xd, 0, i, ir, ic, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004586
Yushin Cho77bba8d2016-11-04 16:36:56 -07004587#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -07004588#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004589 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004590 aom_highbd_subtract_block(
4591 height, width, av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
4592 8, src, p->src.stride, dst, pd->dst.stride, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004593 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004594 aom_subtract_block(height, width,
4595 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07004596 8, src, p->src.stride, dst, pd->dst.stride);
4597 }
4598#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004599 aom_subtract_block(height, width,
4600 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07004601 8, src, p->src.stride, dst, pd->dst.stride);
Yaowu Xuf883b422016-08-30 14:01:10 -07004602#endif // CONFIG_AOM_HIGHBITDEPTH
Yushin Cho77bba8d2016-11-04 16:36:56 -07004603#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004604
4605 k = i;
Jingning Hanbafee8d2016-12-02 10:25:03 -08004606 for (idy = 0; idy < txb_height; idy += num_4x4_h) {
4607 for (idx = 0; idx < txb_width; idx += num_4x4_w) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004608 int64_t dist, ssz, rd, rd1, rd2;
4609 int block;
Yaowu Xu02d4c3b2016-11-07 10:45:56 -08004610#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004611 int coeff_ctx;
Yaowu Xu02d4c3b2016-11-07 10:45:56 -08004612#else
Yushin Cho77bba8d2016-11-04 16:36:56 -07004613 const int src_stride = p->src.stride;
4614 const int dst_stride = pd->dst.stride;
4615 const int diff_stride = 8;
4616 tran_low_t *coeff;
4617 tran_low_t *dqcoeff;
4618 tran_low_t *ref_coeff;
4619 int16_t *pred = &pd->pred[4 * (ir * diff_stride + ic)];
4620 int16_t *src_int16 = &p->src_int16[4 * (ir * diff_stride + ic)];
4621 int ii, j, tx_blk_size;
4622 int rate_pvq;
4623#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004624 k += (idy * 2 + idx);
4625 if (tx_size == TX_4X4)
4626 block = k;
4627 else
4628 block = (i ? 2 : 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004629#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004630 coeff_ctx = combine_entropy_contexts(*(ta + (k & 1)), *(tl + (k >> 1)));
4631#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08004632 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
4633 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004634#else
Angie Chiangff6d8902016-10-21 11:02:09 -07004635 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
Debargha Mukherjeef0305582016-11-24 09:55:34 -08004636 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004637#endif // CONFIG_NEW_QUANT
4638 if (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0)
Angie Chiangff6d8902016-10-21 11:02:09 -07004639 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004640#else
4641 coeff = BLOCK_OFFSET(p->coeff, k);
4642 dqcoeff = BLOCK_OFFSET(pd->dqcoeff, k);
4643 ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, k);
4644
4645 // transform block size in pixels
4646 tx_blk_size = 4;
4647
4648 // copy uint8 orig and predicted block to int16 buffer
4649 // in order to use existing VP10 transform functions
4650 for (j = 0; j < tx_blk_size; j++)
4651 for (ii = 0; ii < tx_blk_size; ii++) {
4652 src_int16[diff_stride * j + ii] =
4653 src[src_stride * (j + 4 * idy) + (ii + 4 * idx)];
4654 pred[diff_stride * j + ii] =
4655 dst[dst_stride * (j + 4 * idy) + (ii + 4 * idx)];
4656 }
4657
Yaowu Xu3442b4b2016-11-07 10:40:41 -08004658 {
4659 FWD_TXFM_PARAM fwd_txfm_param;
4660 fwd_txfm_param.tx_type = DCT_DCT;
4661 fwd_txfm_param.tx_size = TX_4X4;
4662 fwd_txfm_param.fwd_txfm_opt = FWD_TXFM_OPT_NORMAL;
4663 fwd_txfm_param.rd_transform = 0;
4664 fwd_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
Yushin Cho77bba8d2016-11-04 16:36:56 -07004665
Yaowu Xu3442b4b2016-11-07 10:40:41 -08004666 fwd_txfm(src_int16, coeff, diff_stride, &fwd_txfm_param);
4667 fwd_txfm(pred, ref_coeff, diff_stride, &fwd_txfm_param);
4668 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004669 av1_pvq_encode_helper(&x->daala_enc, coeff, ref_coeff, dqcoeff,
4670 &p->eobs[k], pd->dequant, 0, TX_4X4, tx_type,
4671 &rate_pvq, x->pvq_speed, NULL);
4672#endif
4673
Yaowu Xuc27fc142016-08-22 16:08:15 -07004674 dist_block(cpi, x, 0, block, idy + (i >> 1), idx + (i & 0x1), tx_size,
4675 &dist, &ssz);
4676 thisdistortion += dist;
4677 thissse += ssz;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004678#if !CONFIG_PVQ
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07004679 thisrate +=
Angie Chiang22ba7512016-10-20 17:10:33 -07004680 av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size, scan_order->scan,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07004681 scan_order->neighbors, cpi->sf.use_fast_coef_costing);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004682#else
4683 thisrate += rate_pvq;
4684#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004685 *(ta + (k & 1)) = !(p->eobs[block] == 0);
4686 *(tl + (k >> 1)) = !(p->eobs[block] == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004687#if CONFIG_EXT_TX
4688 if (tx_size == TX_8X4) {
4689 *(ta + (k & 1) + 1) = *(ta + (k & 1));
4690 }
4691 if (tx_size == TX_4X8) {
4692 *(tl + (k >> 1) + 1) = *(tl + (k >> 1));
4693 }
4694#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004695 rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion);
4696 rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse);
Yaowu Xuf883b422016-08-30 14:01:10 -07004697 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004698 if (rd >= best_yrd) return INT64_MAX;
4699 }
4700 }
4701
4702 *distortion = thisdistortion;
4703 *labelyrate = thisrate;
4704 *sse = thissse;
4705
4706 return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
4707}
4708
4709typedef struct {
4710 int eobs;
4711 int brate;
4712 int byrate;
4713 int64_t bdist;
4714 int64_t bsse;
4715 int64_t brdcost;
4716 int_mv mvs[2];
4717#if CONFIG_REF_MV
4718 int_mv pred_mv[2];
4719#endif
4720#if CONFIG_EXT_INTER
4721 int_mv ref_mv[2];
4722#endif // CONFIG_EXT_INTER
Jingning Han276c2942016-12-05 12:37:02 -08004723
4724#if CONFIG_CB4X4
4725 ENTROPY_CONTEXT ta[4];
4726 ENTROPY_CONTEXT tl[4];
4727#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07004728 ENTROPY_CONTEXT ta[2];
4729 ENTROPY_CONTEXT tl[2];
Jingning Han276c2942016-12-05 12:37:02 -08004730#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004731} SEG_RDSTAT;
4732
4733typedef struct {
4734 int_mv *ref_mv[2];
4735 int_mv mvp;
4736
4737 int64_t segment_rd;
4738 int r;
4739 int64_t d;
4740 int64_t sse;
4741 int segment_yrate;
4742 PREDICTION_MODE modes[4];
4743#if CONFIG_EXT_INTER
4744 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
4745#else
4746 SEG_RDSTAT rdstat[4][INTER_MODES];
4747#endif // CONFIG_EXT_INTER
4748 int mvthresh;
4749} BEST_SEG_INFO;
4750
4751static INLINE int mv_check_bounds(const MACROBLOCK *x, const MV *mv) {
4752 return (mv->row >> 3) < x->mv_row_min || (mv->row >> 3) > x->mv_row_max ||
4753 (mv->col >> 3) < x->mv_col_min || (mv->col >> 3) > x->mv_col_max;
4754}
4755
4756static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
4757 MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
4758 struct macroblock_plane *const p = &x->plane[0];
4759 struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
4760
4761 p->src.buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07004762 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004763 assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
4764 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07004765 &pd->pre[0].buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[0].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004766 if (has_second_ref(mbmi))
4767 pd->pre[1].buf =
4768 &pd->pre[1]
Yaowu Xuf883b422016-08-30 14:01:10 -07004769 .buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[1].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004770}
4771
4772static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
4773 struct buf_2d orig_pre[2]) {
4774 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
4775 x->plane[0].src = orig_src;
4776 x->e_mbd.plane[0].pre[0] = orig_pre[0];
4777 if (has_second_ref(mbmi)) x->e_mbd.plane[0].pre[1] = orig_pre[1];
4778}
4779
4780// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
4781// TODO(aconverse): Find out if this is still productive then clean up or remove
4782static int check_best_zero_mv(
Urvang Joshi52648442016-10-13 17:27:51 -07004783 const AV1_COMP *const cpi, const int16_t mode_context[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004784#if CONFIG_REF_MV && CONFIG_EXT_INTER
4785 const int16_t compound_mode_context[TOTAL_REFS_PER_FRAME],
4786#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4787 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME], int this_mode,
4788 const MV_REFERENCE_FRAME ref_frames[2], const BLOCK_SIZE bsize, int block) {
4789
4790#if !CONFIG_EXT_INTER
4791 assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
4792#endif
4793
4794 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
4795 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
4796 (ref_frames[1] <= INTRA_FRAME ||
4797 frame_mv[this_mode][ref_frames[1]].as_int == 0)) {
4798#if CONFIG_REF_MV
4799 int16_t rfc =
Yaowu Xuf883b422016-08-30 14:01:10 -07004800 av1_mode_context_analyzer(mode_context, ref_frames, bsize, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004801#else
4802 int16_t rfc = mode_context[ref_frames[0]];
4803#endif
4804#if CONFIG_REF_MV && CONFIG_EXT_INTER
4805 int c1 = cost_mv_ref(cpi, NEARMV, ref_frames[1] > INTRA_FRAME, rfc);
4806 int c2 = cost_mv_ref(cpi, NEARESTMV, ref_frames[1] > INTRA_FRAME, rfc);
4807 int c3 = cost_mv_ref(cpi, ZEROMV, ref_frames[1] > INTRA_FRAME, rfc);
4808#else
4809 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
4810 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
4811 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
4812#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4813
4814#if !CONFIG_REF_MV
4815 (void)bsize;
4816 (void)block;
4817#endif
4818
4819 if (this_mode == NEARMV) {
4820 if (c1 > c3) return 0;
4821 } else if (this_mode == NEARESTMV) {
4822 if (c2 > c3) return 0;
4823 } else {
4824 assert(this_mode == ZEROMV);
4825 if (ref_frames[1] <= INTRA_FRAME) {
4826 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
4827 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
4828 return 0;
4829 } else {
4830 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
4831 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
4832 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
4833 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
4834 return 0;
4835 }
4836 }
4837 }
4838#if CONFIG_EXT_INTER
4839 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
4840 this_mode == NEAR_NEARESTMV || this_mode == NEAR_NEARMV ||
4841 this_mode == ZERO_ZEROMV) &&
4842 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
4843 frame_mv[this_mode][ref_frames[1]].as_int == 0) {
4844#if CONFIG_REF_MV
4845 int16_t rfc = compound_mode_context[ref_frames[0]];
4846 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, 1, rfc);
4847 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, 1, rfc);
4848 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, 1, rfc);
4849 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, 1, rfc);
4850 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, 1, rfc);
4851#else
4852 int16_t rfc = mode_context[ref_frames[0]];
4853 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
4854 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
4855 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
4856 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
4857 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, rfc);
4858#endif
4859
4860 if (this_mode == NEAREST_NEARMV) {
4861 if (c1 > c3) return 0;
4862 } else if (this_mode == NEAREST_NEARESTMV) {
4863 if (c2 > c3) return 0;
4864 } else if (this_mode == NEAR_NEARESTMV) {
4865 if (c4 > c3) return 0;
4866 } else if (this_mode == NEAR_NEARMV) {
4867 if (c5 > c3) return 0;
4868 } else {
4869 assert(this_mode == ZERO_ZEROMV);
4870 if ((c3 >= c2 && frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
4871 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
4872 (c3 >= c1 && frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
4873 frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
4874 (c3 >= c5 && frame_mv[NEAR_NEARMV][ref_frames[0]].as_int == 0 &&
4875 frame_mv[NEAR_NEARMV][ref_frames[1]].as_int == 0) ||
4876 (c3 >= c4 && frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
4877 frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
4878 return 0;
4879 }
4880 }
4881#endif // CONFIG_EXT_INTER
4882 return 1;
4883}
4884
Urvang Joshi52648442016-10-13 17:27:51 -07004885static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
4886 BLOCK_SIZE bsize, int_mv *frame_mv, int mi_row,
4887 int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004888#if CONFIG_EXT_INTER
4889 int_mv *ref_mv_sub8x8[2],
4890#endif
4891 int_mv single_newmv[TOTAL_REFS_PER_FRAME],
4892 int *rate_mv, const int block) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004893 const AV1_COMMON *const cm = &cpi->common;
Jingning Hanae5cfde2016-11-30 12:01:44 -08004894 const int pw = block_size_wide[bsize];
4895 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004896 MACROBLOCKD *xd = &x->e_mbd;
4897 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4898 const int refs[2] = { mbmi->ref_frame[0],
4899 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
4900 int_mv ref_mv[2];
4901 int ite, ref;
4902#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07004903 InterpFilter interp_filter[4] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004904 mbmi->interp_filter[0], mbmi->interp_filter[1], mbmi->interp_filter[2],
4905 mbmi->interp_filter[3],
4906 };
4907#else
James Zern7b9407a2016-05-18 23:48:05 -07004908 const InterpFilter interp_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004909#endif
4910 struct scale_factors sf;
4911
4912 // Do joint motion search in compound mode to get more accurate mv.
4913 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
4914 int last_besterr[2] = { INT_MAX, INT_MAX };
4915 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
Yaowu Xuf883b422016-08-30 14:01:10 -07004916 av1_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
4917 av1_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
Yaowu Xuc27fc142016-08-22 16:08:15 -07004918 };
4919
4920// Prediction buffer from second frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07004921#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004922 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
4923 uint8_t *second_pred;
4924#else
4925 DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07004926#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004927
4928 for (ref = 0; ref < 2; ++ref) {
4929#if CONFIG_EXT_INTER
4930 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
4931 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
4932 else
4933#endif // CONFIG_EXT_INTER
4934 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
4935
4936 if (scaled_ref_frame[ref]) {
4937 int i;
4938 // Swap out the reference frame for a version that's been scaled to
4939 // match the resolution of the current frame, allowing the existing
4940 // motion search code to be used without additional modifications.
4941 for (i = 0; i < MAX_MB_PLANE; i++)
4942 backup_yv12[ref][i] = xd->plane[i].pre[ref];
Yaowu Xuf883b422016-08-30 14:01:10 -07004943 av1_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
4944 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004945 }
4946
4947 frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
4948 }
4949
4950// Since we have scaled the reference frames to match the size of the current
4951// frame we must use a unit scaling factor during mode selection.
Yaowu Xuf883b422016-08-30 14:01:10 -07004952#if CONFIG_AOM_HIGHBITDEPTH
4953 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
4954 cm->height, cm->use_highbitdepth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004955#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004956 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
4957 cm->height);
4958#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004959
4960 // Allow joint search multiple times iteratively for each reference frame
4961 // and break out of the search loop if it couldn't find a better mv.
4962 for (ite = 0; ite < 4; ite++) {
4963 struct buf_2d ref_yv12[2];
4964 int bestsme = INT_MAX;
4965 int sadpb = x->sadperbit16;
4966 MV *const best_mv = &x->best_mv.as_mv;
4967 int search_range = 3;
4968
4969 int tmp_col_min = x->mv_col_min;
4970 int tmp_col_max = x->mv_col_max;
4971 int tmp_row_min = x->mv_row_min;
4972 int tmp_row_max = x->mv_row_max;
4973 int id = ite % 2; // Even iterations search in the first reference frame,
4974 // odd iterations search in the second. The predictor
4975 // found for the 'other' reference frame is factored in.
4976
4977 // Initialized here because of compiler problem in Visual Studio.
4978 ref_yv12[0] = xd->plane[0].pre[0];
4979 ref_yv12[1] = xd->plane[0].pre[1];
4980
4981#if CONFIG_DUAL_FILTER
4982 // reload the filter types
4983 interp_filter[0] =
4984 (id == 0) ? mbmi->interp_filter[2] : mbmi->interp_filter[0];
4985 interp_filter[1] =
4986 (id == 0) ? mbmi->interp_filter[3] : mbmi->interp_filter[1];
4987#endif
4988
4989// Get the prediction block from the 'other' reference frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07004990#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004991 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
4992 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
Yaowu Xuf883b422016-08-30 14:01:10 -07004993 av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004994 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
4995 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, 0, interp_filter,
4996 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd->bd);
4997 } else {
4998 second_pred = (uint8_t *)second_pred_alloc_16;
Yaowu Xuf883b422016-08-30 14:01:10 -07004999 av1_build_inter_predictor(ref_yv12[!id].buf, ref_yv12[!id].stride,
5000 second_pred, pw, &frame_mv[refs[!id]].as_mv,
5001 &sf, pw, ph, 0, interp_filter, MV_PRECISION_Q3,
5002 mi_col * MI_SIZE, mi_row * MI_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005003 }
5004#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005005 av1_build_inter_predictor(ref_yv12[!id].buf, ref_yv12[!id].stride,
5006 second_pred, pw, &frame_mv[refs[!id]].as_mv, &sf,
5007 pw, ph, 0, interp_filter, MV_PRECISION_Q3,
5008 mi_col * MI_SIZE, mi_row * MI_SIZE);
5009#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005010
5011 // Do compound motion search on the current reference frame.
5012 if (id) xd->plane[0].pre[0] = ref_yv12[id];
Yaowu Xuf883b422016-08-30 14:01:10 -07005013 av1_set_mv_search_range(x, &ref_mv[id].as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005014
5015 // Use the mv result from the single mode as mv predictor.
5016 *best_mv = frame_mv[refs[id]].as_mv;
5017
5018 best_mv->col >>= 3;
5019 best_mv->row >>= 3;
5020
5021#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005022 av1_set_mvcost(x, refs[id], id, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005023#endif
5024
5025 // Small-range full-pixel motion search.
5026 bestsme =
Yaowu Xuf883b422016-08-30 14:01:10 -07005027 av1_refining_search_8p_c(x, sadpb, search_range, &cpi->fn_ptr[bsize],
5028 &ref_mv[id].as_mv, second_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005029 if (bestsme < INT_MAX)
Yaowu Xuf883b422016-08-30 14:01:10 -07005030 bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv[id].as_mv,
5031 second_pred, &cpi->fn_ptr[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005032
5033 x->mv_col_min = tmp_col_min;
5034 x->mv_col_max = tmp_col_max;
5035 x->mv_row_min = tmp_row_min;
5036 x->mv_row_max = tmp_row_max;
5037
5038 if (bestsme < INT_MAX) {
5039 int dis; /* TODO: use dis in distortion calculation later. */
5040 unsigned int sse;
5041 if (cpi->sf.use_upsampled_references) {
5042 // Use up-sampled reference frames.
5043 struct macroblockd_plane *const pd = &xd->plane[0];
5044 struct buf_2d backup_pred = pd->pre[0];
5045 const YV12_BUFFER_CONFIG *upsampled_ref =
5046 get_upsampled_ref(cpi, refs[id]);
5047
5048 // Set pred for Y plane
5049 setup_pred_plane(&pd->pre[0], upsampled_ref->y_buffer,
5050 upsampled_ref->y_crop_width,
5051 upsampled_ref->y_crop_height, upsampled_ref->y_stride,
5052 (mi_row << 3), (mi_col << 3), NULL, pd->subsampling_x,
5053 pd->subsampling_y);
5054
Jingning Han271bb2c2016-12-14 12:34:46 -08005055// If bsize < BLOCK_8X8, adjust pred pointer for this block
5056#if !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005057 if (bsize < BLOCK_8X8)
5058 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005059 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, block,
5060 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005061 << 3];
Jingning Han271bb2c2016-12-14 12:34:46 -08005062#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005063
5064 bestsme = cpi->find_fractional_mv_step(
5065 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5066 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5067 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5068 &dis, &sse, second_pred, pw, ph, 1);
5069
5070 // Restore the reference frames.
5071 pd->pre[0] = backup_pred;
5072 } else {
5073 (void)block;
5074 bestsme = cpi->find_fractional_mv_step(
5075 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5076 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5077 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5078 &dis, &sse, second_pred, pw, ph, 0);
5079 }
5080 }
5081
5082 // Restore the pointer to the first (possibly scaled) prediction buffer.
5083 if (id) xd->plane[0].pre[0] = ref_yv12[0];
5084
5085 if (bestsme < last_besterr[id]) {
5086 frame_mv[refs[id]].as_mv = *best_mv;
5087 last_besterr[id] = bestsme;
5088 } else {
5089 break;
5090 }
5091 }
5092
5093 *rate_mv = 0;
5094
5095 for (ref = 0; ref < 2; ++ref) {
5096 if (scaled_ref_frame[ref]) {
5097 // Restore the prediction frame pointers to their unscaled versions.
5098 int i;
5099 for (i = 0; i < MAX_MB_PLANE; i++)
5100 xd->plane[i].pre[ref] = backup_yv12[ref][i];
5101 }
5102#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005103 av1_set_mvcost(x, refs[ref], ref, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005104#endif
5105#if CONFIG_EXT_INTER
5106 if (bsize >= BLOCK_8X8)
5107#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005108 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5109 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
5110 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005111#if CONFIG_EXT_INTER
5112 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005113 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5114 &ref_mv_sub8x8[ref]->as_mv, x->nmvjointcost,
5115 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005116#endif // CONFIG_EXT_INTER
5117 }
5118}
5119
5120static int64_t rd_pick_best_sub8x8_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07005121 const AV1_COMP *const cpi, MACROBLOCK *x, int_mv *best_ref_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005122 int_mv *second_best_ref_mv, int64_t best_rd, int *returntotrate,
5123 int *returnyrate, int64_t *returndistortion, int *skippable, int64_t *psse,
5124 int mvthresh,
5125#if CONFIG_EXT_INTER
5126 int_mv seg_mvs[4][2][TOTAL_REFS_PER_FRAME],
5127 int_mv compound_seg_newmvs[4][2],
5128#else
5129 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME],
5130#endif // CONFIG_EXT_INTER
5131 BEST_SEG_INFO *bsi_buf, int filter_idx, int mi_row, int mi_col) {
5132 BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
5133#if CONFIG_REF_MV
5134 int_mv tmp_ref_mv[2];
5135#endif
5136 MACROBLOCKD *xd = &x->e_mbd;
5137 MODE_INFO *mi = xd->mi[0];
5138 MB_MODE_INFO *mbmi = &mi->mbmi;
5139 int mode_idx;
5140 int k, br = 0, idx, idy;
5141 int64_t bd = 0, block_sse = 0;
5142 PREDICTION_MODE this_mode;
Urvang Joshi52648442016-10-13 17:27:51 -07005143 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005144 struct macroblock_plane *const p = &x->plane[0];
5145 struct macroblockd_plane *const pd = &xd->plane[0];
5146 const int label_count = 4;
5147 int64_t this_segment_rd = 0;
5148 int label_mv_thresh;
5149 int segmentyrate = 0;
5150 const BLOCK_SIZE bsize = mbmi->sb_type;
5151 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
5152 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
Jingning Han276c2942016-12-05 12:37:02 -08005153#if CONFIG_CB4X4
5154 ENTROPY_CONTEXT t_above[4], t_left[4];
5155#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005156 ENTROPY_CONTEXT t_above[2], t_left[2];
Jingning Han276c2942016-12-05 12:37:02 -08005157#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005158 int subpelmv = 1, have_ref = 0;
5159 const int has_second_rf = has_second_ref(mbmi);
5160 const int inter_mode_mask = cpi->sf.inter_mode_mask[bsize];
5161 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005162#if CONFIG_PVQ
5163 od_rollback_buffer pre_buf;
5164
5165 od_encode_checkpoint(&x->daala_enc, &pre_buf);
5166#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005167#if CONFIG_EXT_TX && CONFIG_RECT_TX
5168 mbmi->tx_size =
5169 xd->lossless[mbmi->segment_id] ? TX_4X4 : max_txsize_rect_lookup[bsize];
5170#else
5171 mbmi->tx_size = TX_4X4;
5172#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5173
Yaowu Xuf883b422016-08-30 14:01:10 -07005174 av1_zero(*bsi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005175
5176 bsi->segment_rd = best_rd;
5177 bsi->ref_mv[0] = best_ref_mv;
5178 bsi->ref_mv[1] = second_best_ref_mv;
5179 bsi->mvp.as_int = best_ref_mv->as_int;
5180 bsi->mvthresh = mvthresh;
5181
5182 for (idx = 0; idx < 4; ++idx) bsi->modes[idx] = ZEROMV;
5183
5184#if CONFIG_REFMV
5185 for (idx = 0; idx < 4; ++idx) {
5186 for (k = NEARESTMV; k <= NEWMV; ++k) {
5187 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[0].as_int = INVALID_MV;
5188 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[1].as_int = INVALID_MV;
5189
5190 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[0].as_int = INVALID_MV;
5191 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[1].as_int = INVALID_MV;
5192 }
5193 }
5194#endif
5195
5196 memcpy(t_above, pd->above_context, sizeof(t_above));
5197 memcpy(t_left, pd->left_context, sizeof(t_left));
5198
5199 // 64 makes this threshold really big effectively
5200 // making it so that we very rarely check mvs on
5201 // segments. setting this to 1 would make mv thresh
5202 // roughly equal to what it is for macroblocks
5203 label_mv_thresh = 1 * bsi->mvthresh / label_count;
5204
5205 // Segmentation method overheads
5206 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
5207 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
5208 // TODO(jingning,rbultje): rewrite the rate-distortion optimization
5209 // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
5210 int_mv mode_mv[MB_MODE_COUNT][2];
5211 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
5212 PREDICTION_MODE mode_selected = ZEROMV;
Urvang Joshi454280d2016-10-14 16:51:44 -07005213 int64_t new_best_rd = INT64_MAX;
5214 const int index = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005215 int ref;
5216#if CONFIG_REF_MV
5217 CANDIDATE_MV ref_mv_stack[2][MAX_REF_MV_STACK_SIZE];
5218 uint8_t ref_mv_count[2];
5219#endif
5220#if CONFIG_EXT_INTER
5221 int mv_idx;
5222 int_mv ref_mvs_sub8x8[2][2];
5223#endif // CONFIG_EXT_INTER
Yushin Cho77bba8d2016-11-04 16:36:56 -07005224#if CONFIG_PVQ
5225 od_rollback_buffer idx_buf, post_buf;
5226 od_encode_checkpoint(&x->daala_enc, &idx_buf);
5227 od_encode_checkpoint(&x->daala_enc, &post_buf);
5228#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005229
5230 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5231 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
5232#if CONFIG_EXT_INTER
5233 int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
Urvang Joshi454280d2016-10-14 16:51:44 -07005234 av1_update_mv_context(xd, mi, frame, mv_ref_list, index, mi_row, mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -07005235 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005236#endif // CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005237#if CONFIG_GLOBAL_MOTION
5238 frame_mv[ZEROMV][frame].as_int =
David Barkercdcac6d2016-12-01 17:04:16 +00005239 gm_get_motion_vector(&cm->global_motion[frame],
5240 cm->allow_high_precision_mv)
5241 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07005242#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005243 frame_mv[ZEROMV][frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07005244#endif // CONFIG_GLOBAL_MOTION
Urvang Joshi454280d2016-10-14 16:51:44 -07005245 av1_append_sub8x8_mvs_for_idx(cm, xd, index, ref, mi_row, mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005246#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07005247 ref_mv_stack[ref], &ref_mv_count[ref],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005248#endif
5249#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005250 mv_ref_list,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005251#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005252 &frame_mv[NEARESTMV][frame],
5253 &frame_mv[NEARMV][frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005254
5255#if CONFIG_REF_MV
5256 tmp_ref_mv[ref] = frame_mv[NEARESTMV][mbmi->ref_frame[ref]];
5257 lower_mv_precision(&tmp_ref_mv[ref].as_mv, cm->allow_high_precision_mv);
5258 bsi->ref_mv[ref] = &tmp_ref_mv[ref];
5259 mbmi_ext->ref_mvs[frame][0] = tmp_ref_mv[ref];
5260#endif
5261
5262#if CONFIG_EXT_INTER
5263 mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
5264 mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07005265 av1_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
5266 &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005267
5268 if (has_second_rf) {
5269 frame_mv[ZERO_ZEROMV][frame].as_int = 0;
5270 frame_mv[NEAREST_NEARESTMV][frame].as_int =
5271 frame_mv[NEARESTMV][frame].as_int;
5272
5273 if (ref == 0) {
5274 frame_mv[NEAREST_NEARMV][frame].as_int =
5275 frame_mv[NEARESTMV][frame].as_int;
5276 frame_mv[NEAR_NEARESTMV][frame].as_int =
5277 frame_mv[NEARMV][frame].as_int;
5278 frame_mv[NEAREST_NEWMV][frame].as_int =
5279 frame_mv[NEARESTMV][frame].as_int;
5280 frame_mv[NEAR_NEWMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5281 frame_mv[NEAR_NEARMV][frame].as_int =
5282 frame_mv[NEARMV][frame].as_int;
5283 } else if (ref == 1) {
5284 frame_mv[NEAREST_NEARMV][frame].as_int =
5285 frame_mv[NEARMV][frame].as_int;
5286 frame_mv[NEAR_NEARESTMV][frame].as_int =
5287 frame_mv[NEARESTMV][frame].as_int;
5288 frame_mv[NEW_NEARESTMV][frame].as_int =
5289 frame_mv[NEARESTMV][frame].as_int;
5290 frame_mv[NEW_NEARMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5291 frame_mv[NEAR_NEARMV][frame].as_int =
5292 frame_mv[NEARMV][frame].as_int;
5293 }
5294 }
5295#endif // CONFIG_EXT_INTER
5296 }
5297
5298// search for the best motion vector on this segment
5299#if CONFIG_EXT_INTER
5300 for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
5301 this_mode <= (has_second_rf ? NEW_NEWMV : NEWFROMNEARMV);
5302 ++this_mode)
5303#else
5304 for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode)
5305#endif // CONFIG_EXT_INTER
5306 {
5307 const struct buf_2d orig_src = x->plane[0].src;
5308 struct buf_2d orig_pre[2];
5309 // This flag controls if the motion estimation will kick off. When it
5310 // is set to a non-zero value, the encoder will force motion estimation.
5311 int run_mv_search = 0;
5312
5313 mode_idx = INTER_OFFSET(this_mode);
5314#if CONFIG_EXT_INTER
5315 mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
5316
5317 for (ref = 0; ref < 1 + has_second_rf; ++ref)
5318 bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[mv_idx][ref].as_int;
5319#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005320 bsi->rdstat[index][mode_idx].brdcost = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005321 if (!(inter_mode_mask & (1 << this_mode))) continue;
5322
5323#if CONFIG_REF_MV
5324 run_mv_search = 2;
5325#if !CONFIG_EXT_INTER
5326 if (filter_idx > 0 && this_mode == NEWMV) {
5327 BEST_SEG_INFO *ref_bsi = bsi_buf;
Urvang Joshi454280d2016-10-14 16:51:44 -07005328 SEG_RDSTAT *ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005329
5330 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005331 if (seg_mvs[index][mbmi->ref_frame[0]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005332 ref_rdstat->mvs[0].as_int &&
5333 ref_rdstat->mvs[0].as_int != INVALID_MV)
5334 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
5335 --run_mv_search;
5336
Urvang Joshi454280d2016-10-14 16:51:44 -07005337 if (seg_mvs[index][mbmi->ref_frame[1]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005338 ref_rdstat->mvs[1].as_int &&
5339 ref_rdstat->mvs[1].as_int != INVALID_MV)
5340 if (bsi->ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
5341 --run_mv_search;
5342 } else {
5343 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
5344 ref_rdstat->mvs[0].as_int != INVALID_MV) {
5345 run_mv_search = 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005346 seg_mvs[index][mbmi->ref_frame[0]].as_int =
5347 ref_rdstat->mvs[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005348 }
5349 }
5350
5351 if (run_mv_search != 0 && filter_idx > 1) {
5352 ref_bsi = bsi_buf + 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07005353 ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005354 run_mv_search = 2;
5355
5356 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005357 if (seg_mvs[index][mbmi->ref_frame[0]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005358 ref_rdstat->mvs[0].as_int &&
5359 ref_rdstat->mvs[0].as_int != INVALID_MV)
5360 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
5361 --run_mv_search;
5362
Urvang Joshi454280d2016-10-14 16:51:44 -07005363 if (seg_mvs[index][mbmi->ref_frame[1]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005364 ref_rdstat->mvs[1].as_int &&
5365 ref_rdstat->mvs[1].as_int != INVALID_MV)
5366 if (bsi->ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
5367 --run_mv_search;
5368 } else {
5369 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
5370 ref_rdstat->mvs[0].as_int != INVALID_MV) {
5371 run_mv_search = 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005372 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005373 ref_rdstat->mvs[0].as_int;
5374 }
5375 }
5376 }
5377 }
5378#endif // CONFIG_EXT_INTER
5379#endif // CONFIG_REF_MV
5380
Sarah Parkere5299862016-08-16 14:57:37 -07005381#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +00005382 if (cm->global_motion[mbmi->ref_frame[0]].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -07005383 (!has_second_rf ||
David Barkercf3d0b02016-11-10 10:14:49 +00005384 cm->global_motion[mbmi->ref_frame[1]].wmtype == IDENTITY))
Sarah Parkere5299862016-08-16 14:57:37 -07005385#endif // CONFIG_GLOBAL_MOTION
5386
5387 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005388#if CONFIG_REF_MV && CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005389 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005390#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005391 frame_mv, this_mode, mbmi->ref_frame, bsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07005392 index))
Sarah Parkere5299862016-08-16 14:57:37 -07005393 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005394
5395 memcpy(orig_pre, pd->pre, sizeof(orig_pre));
Urvang Joshi454280d2016-10-14 16:51:44 -07005396 memcpy(bsi->rdstat[index][mode_idx].ta, t_above,
5397 sizeof(bsi->rdstat[index][mode_idx].ta));
5398 memcpy(bsi->rdstat[index][mode_idx].tl, t_left,
5399 sizeof(bsi->rdstat[index][mode_idx].tl));
Yushin Cho77bba8d2016-11-04 16:36:56 -07005400#if CONFIG_PVQ
5401 od_encode_rollback(&x->daala_enc, &idx_buf);
5402#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005403
5404 // motion search for newmv (single predictor case only)
5405 if (!has_second_rf &&
5406#if CONFIG_EXT_INTER
5407 have_newmv_in_inter_mode(this_mode) &&
Alex Converse6317c882016-09-29 14:21:37 -07005408 (seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005409#else
5410 this_mode == NEWMV &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005411 (seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07005412 run_mv_search)
5413#endif // CONFIG_EXT_INTER
5414 ) {
5415 int step_param = 0;
5416 int bestsme = INT_MAX;
5417 int sadpb = x->sadperbit4;
5418 MV mvp_full;
5419 int max_mv;
5420 int cost_list[5];
5421 int tmp_col_min = x->mv_col_min;
5422 int tmp_col_max = x->mv_col_max;
5423 int tmp_row_min = x->mv_row_min;
5424 int tmp_row_max = x->mv_row_max;
5425
5426 /* Is the best so far sufficiently good that we cant justify doing
5427 * and new motion search. */
Urvang Joshi454280d2016-10-14 16:51:44 -07005428 if (new_best_rd < label_mv_thresh) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005429
5430 if (cpi->oxcf.mode != BEST) {
5431#if CONFIG_EXT_INTER
5432 bsi->mvp.as_int = bsi->ref_mv[0]->as_int;
5433#else
5434// use previous block's result as next block's MV predictor.
5435#if !CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07005436 if (index > 0) {
5437 bsi->mvp.as_int = mi->bmi[index - 1].as_mv[0].as_int;
5438 if (index == 2)
5439 bsi->mvp.as_int = mi->bmi[index - 2].as_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005440 }
5441#endif
5442#endif // CONFIG_EXT_INTER
5443 }
Urvang Joshi454280d2016-10-14 16:51:44 -07005444 max_mv = (index == 0) ? (int)x->max_mv_context[mbmi->ref_frame[0]]
5445 : AOMMAX(abs(bsi->mvp.as_mv.row),
5446 abs(bsi->mvp.as_mv.col)) >>
5447 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005448
5449 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
5450 // Take wtd average of the step_params based on the last frame's
5451 // max mv magnitude and the best ref mvs of the current block for
5452 // the given reference.
5453 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07005454 (av1_init_search_range(max_mv) + cpi->mv_step_param) / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005455 } else {
5456 step_param = cpi->mv_step_param;
5457 }
5458
5459#if CONFIG_REF_MV
5460 mvp_full.row = bsi->ref_mv[0]->as_mv.row >> 3;
5461 mvp_full.col = bsi->ref_mv[0]->as_mv.col >> 3;
5462#else
5463 mvp_full.row = bsi->mvp.as_mv.row >> 3;
5464 mvp_full.col = bsi->mvp.as_mv.col >> 3;
5465#endif
5466
5467 if (cpi->sf.adaptive_motion_search) {
5468 mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
5469 mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
Yaowu Xuf883b422016-08-30 14:01:10 -07005470 step_param = AOMMAX(step_param, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005471 }
5472
5473 // adjust src pointer for this block
Urvang Joshi454280d2016-10-14 16:51:44 -07005474 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005475
Yaowu Xuf883b422016-08-30 14:01:10 -07005476 av1_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005477
5478 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
5479
5480#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005481 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005482#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07005483 bestsme = av1_full_pixel_search(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005484 cpi, x, bsize, &mvp_full, step_param, sadpb,
5485 cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
5486 &bsi->ref_mv[0]->as_mv, INT_MAX, 1);
5487
5488 x->mv_col_min = tmp_col_min;
5489 x->mv_col_max = tmp_col_max;
5490 x->mv_row_min = tmp_row_min;
5491 x->mv_row_max = tmp_row_max;
5492
5493 if (bestsme < INT_MAX) {
5494 int distortion;
5495 if (cpi->sf.use_upsampled_references) {
5496 int best_mv_var;
5497 const int try_second =
5498 x->second_best_mv.as_int != INVALID_MV &&
5499 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08005500 const int pw = block_size_wide[bsize];
5501 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005502 // Use up-sampled reference frames.
Yaowu Xuc27fc142016-08-22 16:08:15 -07005503 struct buf_2d backup_pred = pd->pre[0];
5504 const YV12_BUFFER_CONFIG *upsampled_ref =
5505 get_upsampled_ref(cpi, mbmi->ref_frame[0]);
5506
5507 // Set pred for Y plane
5508 setup_pred_plane(
5509 &pd->pre[0], upsampled_ref->y_buffer,
5510 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
5511 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
5512 pd->subsampling_x, pd->subsampling_y);
5513
5514 // adjust pred pointer for this block
5515 pd->pre[0].buf =
Urvang Joshi454280d2016-10-14 16:51:44 -07005516 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, index,
Yaowu Xuf883b422016-08-30 14:01:10 -07005517 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005518 << 3];
5519
5520 best_mv_var = cpi->find_fractional_mv_step(
5521 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
5522 x->errorperbit, &cpi->fn_ptr[bsize],
5523 cpi->sf.mv.subpel_force_stop,
5524 cpi->sf.mv.subpel_iters_per_step,
5525 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
5526 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, pw, ph,
5527 1);
5528
5529 if (try_second) {
5530 int this_var;
5531 MV best_mv = x->best_mv.as_mv;
5532 const MV ref_mv = bsi->ref_mv[0]->as_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07005533 const int minc = AOMMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
5534 const int maxc = AOMMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
5535 const int minr = AOMMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
5536 const int maxr = AOMMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005537
5538 x->best_mv = x->second_best_mv;
5539 if (x->best_mv.as_mv.row * 8 <= maxr &&
5540 x->best_mv.as_mv.row * 8 >= minr &&
5541 x->best_mv.as_mv.col * 8 <= maxc &&
5542 x->best_mv.as_mv.col * 8 >= minc) {
5543 this_var = cpi->find_fractional_mv_step(
5544 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
5545 x->errorperbit, &cpi->fn_ptr[bsize],
5546 cpi->sf.mv.subpel_force_stop,
5547 cpi->sf.mv.subpel_iters_per_step,
5548 cond_cost_list(cpi, cost_list), x->nmvjointcost,
5549 x->mvcost, &distortion, &x->pred_sse[mbmi->ref_frame[0]],
5550 NULL, pw, ph, 1);
5551 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
5552 x->best_mv.as_mv = best_mv;
5553 }
5554 }
5555
5556 // Restore the reference frames.
5557 pd->pre[0] = backup_pred;
5558 } else {
5559 cpi->find_fractional_mv_step(
5560 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
5561 x->errorperbit, &cpi->fn_ptr[bsize],
5562 cpi->sf.mv.subpel_force_stop,
5563 cpi->sf.mv.subpel_iters_per_step,
5564 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
5565 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, 0, 0, 0);
5566 }
5567
5568// save motion search result for use in compound prediction
5569#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005570 seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005571#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005572 seg_mvs[index][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005573#endif // CONFIG_EXT_INTER
5574 }
5575
5576 if (cpi->sf.adaptive_motion_search)
5577 x->pred_mv[mbmi->ref_frame[0]] = x->best_mv.as_mv;
5578
5579#if CONFIG_EXT_INTER
5580 mode_mv[this_mode][0] = x->best_mv;
5581#else
5582 mode_mv[NEWMV][0] = x->best_mv;
5583#endif // CONFIG_EXT_INTER
5584
5585 // restore src pointers
5586 mi_buf_restore(x, orig_src, orig_pre);
5587 }
5588
5589 if (has_second_rf) {
5590#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005591 if (seg_mvs[index][mv_idx][mbmi->ref_frame[1]].as_int == INVALID_MV ||
5592 seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005593#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005594 if (seg_mvs[index][mbmi->ref_frame[1]].as_int == INVALID_MV ||
5595 seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005596#endif // CONFIG_EXT_INTER
5597 continue;
5598 }
5599
5600#if CONFIG_DUAL_FILTER
5601 (void)run_mv_search;
5602#endif
5603
5604 if (has_second_rf &&
5605#if CONFIG_EXT_INTER
5606 this_mode == NEW_NEWMV &&
5607#else
5608 this_mode == NEWMV &&
5609#endif // CONFIG_EXT_INTER
5610#if CONFIG_DUAL_FILTER
5611 (mbmi->interp_filter[0] == EIGHTTAP_REGULAR || run_mv_search))
5612#else
5613 (mbmi->interp_filter == EIGHTTAP_REGULAR || run_mv_search))
5614#endif
5615 {
5616 // adjust src pointers
Urvang Joshi454280d2016-10-14 16:51:44 -07005617 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005618 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
5619 int rate_mv;
5620 joint_motion_search(cpi, x, bsize, frame_mv[this_mode], mi_row,
5621 mi_col,
5622#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005623 bsi->ref_mv, seg_mvs[index][mv_idx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005624#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005625 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005626#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005627 &rate_mv, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005628#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005629 compound_seg_newmvs[index][0].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005630 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07005631 compound_seg_newmvs[index][1].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005632 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
5633#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005634 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005635 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07005636 seg_mvs[index][mbmi->ref_frame[1]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005637 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
5638#endif // CONFIG_EXT_INTER
5639 }
5640 // restore src pointers
5641 mi_buf_restore(x, orig_src, orig_pre);
5642 }
5643
Urvang Joshi454280d2016-10-14 16:51:44 -07005644 bsi->rdstat[index][mode_idx].brate = set_and_cost_bmi_mvs(
5645 cpi, x, xd, index, this_mode, mode_mv[this_mode], frame_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005646#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005647 seg_mvs[index][mv_idx], compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005648#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005649 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005650#endif // CONFIG_EXT_INTER
5651 bsi->ref_mv, x->nmvjointcost, x->mvcost);
5652
5653 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005654 bsi->rdstat[index][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005655 mode_mv[this_mode][ref].as_int;
5656 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005657 bsi->rdstat[index + 1][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005658 mode_mv[this_mode][ref].as_int;
5659 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005660 bsi->rdstat[index + 2][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005661 mode_mv[this_mode][ref].as_int;
5662#if CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07005663 bsi->rdstat[index][mode_idx].pred_mv[ref].as_int =
5664 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005665 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005666 bsi->rdstat[index + 1][mode_idx].pred_mv[ref].as_int =
5667 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005668 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005669 bsi->rdstat[index + 2][mode_idx].pred_mv[ref].as_int =
5670 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005671#endif
5672#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005673 bsi->rdstat[index][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005674 bsi->ref_mv[ref]->as_int;
5675 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005676 bsi->rdstat[index + 1][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005677 bsi->ref_mv[ref]->as_int;
5678 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005679 bsi->rdstat[index + 2][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005680 bsi->ref_mv[ref]->as_int;
5681#endif // CONFIG_EXT_INTER
5682 }
5683
5684 // Trap vectors that reach beyond the UMV borders
5685 if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
5686 (has_second_rf && mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
5687 continue;
5688
5689 if (filter_idx > 0) {
5690 BEST_SEG_INFO *ref_bsi = bsi_buf;
5691 subpelmv = 0;
5692 have_ref = 1;
5693
5694 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5695 subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
5696#if CONFIG_EXT_INTER
5697 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07005698 have_ref &=
5699 ((mode_mv[this_mode][ref].as_int ==
5700 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
5701 (bsi->ref_mv[ref]->as_int ==
5702 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005703 else
5704#endif // CONFIG_EXT_INTER
5705 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07005706 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005707 }
5708
Urvang Joshi454280d2016-10-14 16:51:44 -07005709 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005710
5711 if (filter_idx > 1 && !subpelmv && !have_ref) {
5712 ref_bsi = bsi_buf + 1;
5713 have_ref = 1;
5714 for (ref = 0; ref < 1 + has_second_rf; ++ref)
5715#if CONFIG_EXT_INTER
5716 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07005717 have_ref &=
5718 ((mode_mv[this_mode][ref].as_int ==
5719 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
5720 (bsi->ref_mv[ref]->as_int ==
5721 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005722 else
5723#endif // CONFIG_EXT_INTER
5724 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07005725 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005726
Urvang Joshi454280d2016-10-14 16:51:44 -07005727 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005728 }
5729
5730 if (!subpelmv && have_ref &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005731 ref_bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005732#if CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07005733 bsi->rdstat[index][mode_idx].byrate =
5734 ref_bsi->rdstat[index][mode_idx].byrate;
5735 bsi->rdstat[index][mode_idx].bdist =
5736 ref_bsi->rdstat[index][mode_idx].bdist;
5737 bsi->rdstat[index][mode_idx].bsse =
5738 ref_bsi->rdstat[index][mode_idx].bsse;
5739 bsi->rdstat[index][mode_idx].brate +=
5740 ref_bsi->rdstat[index][mode_idx].byrate;
5741 bsi->rdstat[index][mode_idx].eobs =
5742 ref_bsi->rdstat[index][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005743
Urvang Joshi454280d2016-10-14 16:51:44 -07005744 bsi->rdstat[index][mode_idx].brdcost =
5745 RDCOST(x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate,
5746 bsi->rdstat[index][mode_idx].bdist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005747
Urvang Joshi454280d2016-10-14 16:51:44 -07005748 memcpy(bsi->rdstat[index][mode_idx].ta,
5749 ref_bsi->rdstat[index][mode_idx].ta,
5750 sizeof(bsi->rdstat[index][mode_idx].ta));
5751 memcpy(bsi->rdstat[index][mode_idx].tl,
5752 ref_bsi->rdstat[index][mode_idx].tl,
5753 sizeof(bsi->rdstat[index][mode_idx].tl));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005754#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005755 memcpy(&bsi->rdstat[index][mode_idx],
5756 &ref_bsi->rdstat[index][mode_idx], sizeof(SEG_RDSTAT));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005757#endif
5758 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005759 bsi->rdstat[index + 1][mode_idx].eobs =
5760 ref_bsi->rdstat[index + 1][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005761 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005762 bsi->rdstat[index + 2][mode_idx].eobs =
5763 ref_bsi->rdstat[index + 2][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005764
Urvang Joshi454280d2016-10-14 16:51:44 -07005765 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005766#if CONFIG_REF_MV
5767 // If the NEWMV mode is using the same motion vector as the
5768 // NEARESTMV mode, skip the rest rate-distortion calculations
5769 // and use the inferred motion vector modes.
5770 if (this_mode == NEWMV) {
5771 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005772 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005773 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005774 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005775 bsi->ref_mv[1]->as_int)
5776 continue;
5777 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07005778 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005779 bsi->ref_mv[0]->as_int)
5780 continue;
5781 }
5782 }
5783#endif
5784 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07005785 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005786#if CONFIG_PVQ
5787 od_encode_checkpoint(&x->daala_enc, &post_buf);
5788#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005789 }
5790 continue;
5791 }
5792 }
5793
Urvang Joshi454280d2016-10-14 16:51:44 -07005794 bsi->rdstat[index][mode_idx].brdcost = encode_inter_mb_segment(
5795 cpi, x, bsi->segment_rd - this_segment_rd, index,
5796 &bsi->rdstat[index][mode_idx].byrate,
5797 &bsi->rdstat[index][mode_idx].bdist,
5798 &bsi->rdstat[index][mode_idx].bsse, bsi->rdstat[index][mode_idx].ta,
5799 bsi->rdstat[index][mode_idx].tl, idy, idx, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005800
Urvang Joshi454280d2016-10-14 16:51:44 -07005801 if (bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
5802 bsi->rdstat[index][mode_idx].brdcost += RDCOST(
5803 x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate, 0);
5804 bsi->rdstat[index][mode_idx].brate +=
5805 bsi->rdstat[index][mode_idx].byrate;
5806 bsi->rdstat[index][mode_idx].eobs = p->eobs[index];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005807 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005808 bsi->rdstat[index + 1][mode_idx].eobs = p->eobs[index + 1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005809 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005810 bsi->rdstat[index + 2][mode_idx].eobs = p->eobs[index + 2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005811 }
5812
Urvang Joshi454280d2016-10-14 16:51:44 -07005813 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005814#if CONFIG_REF_MV
5815 // If the NEWMV mode is using the same motion vector as the
5816 // NEARESTMV mode, skip the rest rate-distortion calculations
5817 // and use the inferred motion vector modes.
5818 if (this_mode == NEWMV) {
5819 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005820 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005821 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005822 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005823 bsi->ref_mv[1]->as_int)
5824 continue;
5825 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07005826 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005827 bsi->ref_mv[0]->as_int)
5828 continue;
5829 }
5830 }
5831#endif
5832 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07005833 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005834
5835#if CONFIG_PVQ
5836 od_encode_checkpoint(&x->daala_enc, &post_buf);
5837#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005838 }
5839 } /*for each 4x4 mode*/
5840
Urvang Joshi454280d2016-10-14 16:51:44 -07005841 if (new_best_rd == INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005842 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07005843 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005844#if CONFIG_EXT_INTER
5845 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
5846#else
5847 for (midx = 0; midx < INTER_MODES; ++midx)
5848#endif // CONFIG_EXT_INTER
5849 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
5850 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005851#if CONFIG_PVQ
5852 od_encode_rollback(&x->daala_enc, &pre_buf);
5853#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005854 return INT64_MAX;
5855 }
5856
5857 mode_idx = INTER_OFFSET(mode_selected);
Urvang Joshi454280d2016-10-14 16:51:44 -07005858 memcpy(t_above, bsi->rdstat[index][mode_idx].ta, sizeof(t_above));
5859 memcpy(t_left, bsi->rdstat[index][mode_idx].tl, sizeof(t_left));
Yushin Cho77bba8d2016-11-04 16:36:56 -07005860#if CONFIG_PVQ
5861 od_encode_rollback(&x->daala_enc, &post_buf);
5862#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005863
5864#if CONFIG_EXT_INTER
5865 mv_idx = (mode_selected == NEWFROMNEARMV) ? 1 : 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005866 bsi->ref_mv[0]->as_int = bsi->rdstat[index][mode_idx].ref_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005867 if (has_second_rf)
Urvang Joshi454280d2016-10-14 16:51:44 -07005868 bsi->ref_mv[1]->as_int = bsi->rdstat[index][mode_idx].ref_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005869#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005870 set_and_cost_bmi_mvs(cpi, x, xd, index, mode_selected,
5871 mode_mv[mode_selected], frame_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005872#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005873 seg_mvs[index][mv_idx], compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005874#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005875 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005876#endif // CONFIG_EXT_INTER
5877 bsi->ref_mv, x->nmvjointcost, x->mvcost);
5878
Urvang Joshi454280d2016-10-14 16:51:44 -07005879 br += bsi->rdstat[index][mode_idx].brate;
5880 bd += bsi->rdstat[index][mode_idx].bdist;
5881 block_sse += bsi->rdstat[index][mode_idx].bsse;
5882 segmentyrate += bsi->rdstat[index][mode_idx].byrate;
5883 this_segment_rd += bsi->rdstat[index][mode_idx].brdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005884
5885 if (this_segment_rd > bsi->segment_rd) {
5886 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07005887 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005888#if CONFIG_EXT_INTER
5889 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
5890#else
5891 for (midx = 0; midx < INTER_MODES; ++midx)
5892#endif // CONFIG_EXT_INTER
5893 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
5894 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005895#if CONFIG_PVQ
5896 od_encode_rollback(&x->daala_enc, &pre_buf);
5897#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005898 return INT64_MAX;
5899 }
5900 }
5901 } /* for each label */
Yushin Cho77bba8d2016-11-04 16:36:56 -07005902#if CONFIG_PVQ
5903 od_encode_rollback(&x->daala_enc, &pre_buf);
5904#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005905
5906 bsi->r = br;
5907 bsi->d = bd;
5908 bsi->segment_yrate = segmentyrate;
5909 bsi->segment_rd = this_segment_rd;
5910 bsi->sse = block_sse;
5911
5912 // update the coding decisions
5913 for (k = 0; k < 4; ++k) bsi->modes[k] = mi->bmi[k].as_mode;
5914
5915 if (bsi->segment_rd > best_rd) return INT64_MAX;
5916 /* set it to the best */
5917 for (idx = 0; idx < 4; idx++) {
5918 mode_idx = INTER_OFFSET(bsi->modes[idx]);
5919 mi->bmi[idx].as_mv[0].as_int = bsi->rdstat[idx][mode_idx].mvs[0].as_int;
5920 if (has_second_ref(mbmi))
5921 mi->bmi[idx].as_mv[1].as_int = bsi->rdstat[idx][mode_idx].mvs[1].as_int;
5922#if CONFIG_REF_MV
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07005923 mi->bmi[idx].pred_mv[0] = bsi->rdstat[idx][mode_idx].pred_mv[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005924 if (has_second_ref(mbmi))
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07005925 mi->bmi[idx].pred_mv[1] = bsi->rdstat[idx][mode_idx].pred_mv[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005926#endif
5927#if CONFIG_EXT_INTER
5928 mi->bmi[idx].ref_mv[0].as_int = bsi->rdstat[idx][mode_idx].ref_mv[0].as_int;
5929 if (has_second_rf)
5930 mi->bmi[idx].ref_mv[1].as_int =
5931 bsi->rdstat[idx][mode_idx].ref_mv[1].as_int;
5932#endif // CONFIG_EXT_INTER
5933 x->plane[0].eobs[idx] = bsi->rdstat[idx][mode_idx].eobs;
5934 mi->bmi[idx].as_mode = bsi->modes[idx];
5935 }
5936
5937 /*
5938 * used to set mbmi->mv.as_int
5939 */
5940 *returntotrate = bsi->r;
5941 *returndistortion = bsi->d;
5942 *returnyrate = bsi->segment_yrate;
Yaowu Xuf883b422016-08-30 14:01:10 -07005943 *skippable = av1_is_skippable_in_plane(x, BLOCK_8X8, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005944 *psse = bsi->sse;
5945 mbmi->mode = bsi->modes[3];
5946
5947 return bsi->segment_rd;
5948}
5949
Yaowu Xuf883b422016-08-30 14:01:10 -07005950static void estimate_ref_frame_costs(const AV1_COMMON *cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005951 const MACROBLOCKD *xd, int segment_id,
5952 unsigned int *ref_costs_single,
5953 unsigned int *ref_costs_comp,
Yaowu Xuf883b422016-08-30 14:01:10 -07005954 aom_prob *comp_mode_p) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005955 int seg_ref_active =
5956 segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
5957 if (seg_ref_active) {
5958 memset(ref_costs_single, 0,
5959 TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_single));
5960 memset(ref_costs_comp, 0, TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_comp));
5961 *comp_mode_p = 128;
5962 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005963 aom_prob intra_inter_p = av1_get_intra_inter_prob(cm, xd);
5964 aom_prob comp_inter_p = 128;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005965
5966 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005967 comp_inter_p = av1_get_reference_mode_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005968 *comp_mode_p = comp_inter_p;
5969 } else {
5970 *comp_mode_p = 128;
5971 }
5972
Yaowu Xuf883b422016-08-30 14:01:10 -07005973 ref_costs_single[INTRA_FRAME] = av1_cost_bit(intra_inter_p, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005974
5975 if (cm->reference_mode != COMPOUND_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005976 aom_prob ref_single_p1 = av1_get_pred_prob_single_ref_p1(cm, xd);
5977 aom_prob ref_single_p2 = av1_get_pred_prob_single_ref_p2(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005978#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005979 aom_prob ref_single_p3 = av1_get_pred_prob_single_ref_p3(cm, xd);
5980 aom_prob ref_single_p4 = av1_get_pred_prob_single_ref_p4(cm, xd);
5981 aom_prob ref_single_p5 = av1_get_pred_prob_single_ref_p5(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005982#endif // CONFIG_EXT_REFS
5983
Yaowu Xuf883b422016-08-30 14:01:10 -07005984 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005985
5986 ref_costs_single[LAST_FRAME] =
5987#if CONFIG_EXT_REFS
5988 ref_costs_single[LAST2_FRAME] = ref_costs_single[LAST3_FRAME] =
5989 ref_costs_single[BWDREF_FRAME] =
5990#endif // CONFIG_EXT_REFS
5991 ref_costs_single[GOLDEN_FRAME] =
5992 ref_costs_single[ALTREF_FRAME] = base_cost;
5993
5994#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005995 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
5996 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p1, 0);
5997 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p1, 0);
5998 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 0);
5999 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
6000 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006001
Yaowu Xuf883b422016-08-30 14:01:10 -07006002 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p3, 0);
6003 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p3, 0);
6004 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p3, 1);
6005 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p3, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006006
Yaowu Xuf883b422016-08-30 14:01:10 -07006007 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p2, 0);
6008 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006009
Yaowu Xuf883b422016-08-30 14:01:10 -07006010 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p4, 0);
6011 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p4, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006012
Yaowu Xuf883b422016-08-30 14:01:10 -07006013 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p5, 0);
6014 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p5, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006015#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006016 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
6017 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 1);
6018 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006019
Yaowu Xuf883b422016-08-30 14:01:10 -07006020 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p2, 0);
6021 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006022#endif // CONFIG_EXT_REFS
6023 } else {
6024 ref_costs_single[LAST_FRAME] = 512;
6025#if CONFIG_EXT_REFS
6026 ref_costs_single[LAST2_FRAME] = 512;
6027 ref_costs_single[LAST3_FRAME] = 512;
6028 ref_costs_single[BWDREF_FRAME] = 512;
6029#endif // CONFIG_EXT_REFS
6030 ref_costs_single[GOLDEN_FRAME] = 512;
6031 ref_costs_single[ALTREF_FRAME] = 512;
6032 }
6033
6034 if (cm->reference_mode != SINGLE_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006035 aom_prob ref_comp_p = av1_get_pred_prob_comp_ref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006036#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006037 aom_prob ref_comp_p1 = av1_get_pred_prob_comp_ref_p1(cm, xd);
6038 aom_prob ref_comp_p2 = av1_get_pred_prob_comp_ref_p2(cm, xd);
6039 aom_prob bwdref_comp_p = av1_get_pred_prob_comp_bwdref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006040#endif // CONFIG_EXT_REFS
6041
Yaowu Xuf883b422016-08-30 14:01:10 -07006042 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006043
6044 ref_costs_comp[LAST_FRAME] =
6045#if CONFIG_EXT_REFS
6046 ref_costs_comp[LAST2_FRAME] = ref_costs_comp[LAST3_FRAME] =
6047#endif // CONFIG_EXT_REFS
6048 ref_costs_comp[GOLDEN_FRAME] = base_cost;
6049
6050#if CONFIG_EXT_REFS
6051 ref_costs_comp[BWDREF_FRAME] = ref_costs_comp[ALTREF_FRAME] = 0;
6052#endif // CONFIG_EXT_REFS
6053
6054#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006055 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6056 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p, 0);
6057 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p, 1);
6058 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006059
Yaowu Xuf883b422016-08-30 14:01:10 -07006060 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p1, 1);
6061 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006062
Yaowu Xuf883b422016-08-30 14:01:10 -07006063 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p2, 0);
6064 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006065
6066 // NOTE(zoeliu): BWDREF and ALTREF each add an extra cost by coding 1
6067 // more bit.
Yaowu Xuf883b422016-08-30 14:01:10 -07006068 ref_costs_comp[BWDREF_FRAME] += av1_cost_bit(bwdref_comp_p, 0);
6069 ref_costs_comp[ALTREF_FRAME] += av1_cost_bit(bwdref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006070#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006071 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6072 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006073#endif // CONFIG_EXT_REFS
6074 } else {
6075 ref_costs_comp[LAST_FRAME] = 512;
6076#if CONFIG_EXT_REFS
6077 ref_costs_comp[LAST2_FRAME] = 512;
6078 ref_costs_comp[LAST3_FRAME] = 512;
6079 ref_costs_comp[BWDREF_FRAME] = 512;
6080 ref_costs_comp[ALTREF_FRAME] = 512;
6081#endif // CONFIG_EXT_REFS
6082 ref_costs_comp[GOLDEN_FRAME] = 512;
6083 }
6084 }
6085}
6086
6087static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
6088 int mode_index,
6089 int64_t comp_pred_diff[REFERENCE_MODES],
6090 int skippable) {
6091 MACROBLOCKD *const xd = &x->e_mbd;
6092
6093 // Take a snapshot of the coding context so it can be
6094 // restored if we decide to encode this way
6095 ctx->skip = x->skip;
6096 ctx->skippable = skippable;
6097 ctx->best_mode_index = mode_index;
6098 ctx->mic = *xd->mi[0];
6099 ctx->mbmi_ext = *x->mbmi_ext;
6100 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
6101 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
6102 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
6103}
6104
Urvang Joshi52648442016-10-13 17:27:51 -07006105static void setup_buffer_inter(const AV1_COMP *const cpi, MACROBLOCK *x,
clang-format67948d32016-09-07 22:40:40 -07006106 MV_REFERENCE_FRAME ref_frame,
6107 BLOCK_SIZE block_size, int mi_row, int mi_col,
6108 int_mv frame_nearest_mv[TOTAL_REFS_PER_FRAME],
6109 int_mv frame_near_mv[TOTAL_REFS_PER_FRAME],
6110 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME]
6111 [MAX_MB_PLANE]) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006112 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006113 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
6114 MACROBLOCKD *const xd = &x->e_mbd;
6115 MODE_INFO *const mi = xd->mi[0];
6116 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
6117 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
6118 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6119
6120 assert(yv12 != NULL);
6121
6122 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
6123 // use the UV scaling factors.
Yaowu Xuf883b422016-08-30 14:01:10 -07006124 av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006125
6126 // Gets an initial list of candidate vectors from neighbours and orders them
Yaowu Xuf883b422016-08-30 14:01:10 -07006127 av1_find_mv_refs(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006128 cm, xd, mi, ref_frame,
6129#if CONFIG_REF_MV
6130 &mbmi_ext->ref_mv_count[ref_frame], mbmi_ext->ref_mv_stack[ref_frame],
6131#if CONFIG_EXT_INTER
6132 mbmi_ext->compound_mode_context,
6133#endif // CONFIG_EXT_INTER
6134#endif
6135 candidates, mi_row, mi_col, NULL, NULL, mbmi_ext->mode_context);
6136
6137 // Candidate refinement carried out at encoder and decoder
Yaowu Xuf883b422016-08-30 14:01:10 -07006138 av1_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
6139 &frame_nearest_mv[ref_frame],
6140 &frame_near_mv[ref_frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006141
Jingning Han271bb2c2016-12-14 12:34:46 -08006142// Further refinement that is encode side only to test the top few candidates
6143// in full and choose the best as the centre point for subsequent searches.
6144// The current implementation doesn't support scaling.
6145#if CONFIG_CB4X4
6146 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6147 block_size);
6148#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006149 if (!av1_is_scaled(sf) && block_size >= BLOCK_8X8)
6150 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6151 block_size);
Jingning Han271bb2c2016-12-14 12:34:46 -08006152#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07006153}
6154
Urvang Joshi52648442016-10-13 17:27:51 -07006155static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
6156 BLOCK_SIZE bsize, int mi_row, int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006157#if CONFIG_EXT_INTER
6158 int ref_idx, int mv_idx,
6159#endif // CONFIG_EXT_INTER
6160 int *rate_mv) {
6161 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07006162 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006163 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6164 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
6165 int bestsme = INT_MAX;
6166 int step_param;
6167 int sadpb = x->sadperbit16;
6168 MV mvp_full;
6169#if CONFIG_EXT_INTER
6170 int ref = mbmi->ref_frame[ref_idx];
6171 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
6172#else
6173 int ref = mbmi->ref_frame[0];
6174 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6175 int ref_idx = 0;
6176#endif // CONFIG_EXT_INTER
6177
6178 int tmp_col_min = x->mv_col_min;
6179 int tmp_col_max = x->mv_col_max;
6180 int tmp_row_min = x->mv_row_min;
6181 int tmp_row_max = x->mv_row_max;
6182 int cost_list[5];
6183
6184 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07006185 av1_get_scaled_ref_frame(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006186
6187 MV pred_mv[3];
6188 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6189 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
6190 pred_mv[2] = x->pred_mv[ref];
6191
Yaowu Xuc27fc142016-08-22 16:08:15 -07006192 if (scaled_ref_frame) {
6193 int i;
6194 // Swap out the reference frame for a version that's been scaled to
6195 // match the resolution of the current frame, allowing the existing
6196 // motion search code to be used without additional modifications.
6197 for (i = 0; i < MAX_MB_PLANE; i++)
6198 backup_yv12[i] = xd->plane[i].pre[ref_idx];
6199
Yaowu Xuf883b422016-08-30 14:01:10 -07006200 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006201 }
6202
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006203 av1_set_mv_search_range(x, &ref_mv);
6204
6205#if CONFIG_REF_MV
6206 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
6207#endif
6208
Yaowu Xuc27fc142016-08-22 16:08:15 -07006209 // Work out the size of the first step in the mv step search.
Yaowu Xuf883b422016-08-30 14:01:10 -07006210 // 0 here is maximum length first step. 1 is AOMMAX >> 1 etc.
Yaowu Xuc27fc142016-08-22 16:08:15 -07006211 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6212 // Take wtd average of the step_params based on the last frame's
6213 // max mv magnitude and that based on the best ref mvs of the current
6214 // block for the given reference.
6215 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006216 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07006217 2;
6218 } else {
6219 step_param = cpi->mv_step_param;
6220 }
6221
6222 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size) {
6223 int boffset =
6224 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07006225 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
6226 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006227 }
6228
6229 if (cpi->sf.adaptive_motion_search) {
6230 int bwl = b_width_log2_lookup[bsize];
6231 int bhl = b_height_log2_lookup[bsize];
6232 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
6233
6234 if (tlevel < 5) step_param += 2;
6235
6236 // prev_mv_sad is not setup for dynamically scaled frames.
6237 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
6238 int i;
6239 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
6240 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
6241 x->pred_mv[ref].row = 0;
6242 x->pred_mv[ref].col = 0;
6243 x->best_mv.as_int = INVALID_MV;
6244
6245 if (scaled_ref_frame) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006246 int j;
6247 for (j = 0; j < MAX_MB_PLANE; ++j)
6248 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006249 }
6250 return;
6251 }
6252 }
6253 }
6254 }
6255
Yaowu Xuf883b422016-08-30 14:01:10 -07006256 av1_set_mv_search_range(x, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006257
Yue Chene9638cc2016-10-10 12:37:54 -07006258#if CONFIG_MOTION_VAR
6259 if (mbmi->motion_mode != SIMPLE_TRANSLATION)
6260 mvp_full = mbmi->mv[0].as_mv;
6261 else
6262#endif // CONFIG_MOTION_VAR
6263 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006264
6265 mvp_full.col >>= 3;
6266 mvp_full.row >>= 3;
6267
6268 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
6269
Yue Chene9638cc2016-10-10 12:37:54 -07006270#if CONFIG_MOTION_VAR
6271 switch (mbmi->motion_mode) {
6272 case SIMPLE_TRANSLATION:
6273#endif // CONFIG_MOTION_VAR
6274 bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
6275 sadpb, cond_cost_list(cpi, cost_list),
6276 &ref_mv, INT_MAX, 1);
6277#if CONFIG_MOTION_VAR
6278 break;
6279 case OBMC_CAUSAL:
6280 bestsme = av1_obmc_full_pixel_diamond(
6281 cpi, x, &mvp_full, step_param, sadpb,
6282 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
6283 &(x->best_mv.as_mv), 0);
6284 break;
6285 default: assert("Invalid motion mode!\n");
6286 }
6287#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006288
6289 x->mv_col_min = tmp_col_min;
6290 x->mv_col_max = tmp_col_max;
6291 x->mv_row_min = tmp_row_min;
6292 x->mv_row_max = tmp_row_max;
6293
6294 if (bestsme < INT_MAX) {
6295 int dis; /* TODO: use dis in distortion calculation later. */
Yue Chene9638cc2016-10-10 12:37:54 -07006296#if CONFIG_MOTION_VAR
6297 switch (mbmi->motion_mode) {
6298 case SIMPLE_TRANSLATION:
6299#endif // CONFIG_MOTION_VAR
6300 if (cpi->sf.use_upsampled_references) {
6301 int best_mv_var;
6302 const int try_second = x->second_best_mv.as_int != INVALID_MV &&
6303 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006304 const int pw = block_size_wide[bsize];
6305 const int ph = block_size_high[bsize];
Yue Chene9638cc2016-10-10 12:37:54 -07006306 // Use up-sampled reference frames.
6307 struct macroblockd_plane *const pd = &xd->plane[0];
6308 struct buf_2d backup_pred = pd->pre[ref_idx];
6309 const YV12_BUFFER_CONFIG *upsampled_ref = get_upsampled_ref(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006310
Yue Chene9638cc2016-10-10 12:37:54 -07006311 // Set pred for Y plane
6312 setup_pred_plane(
6313 &pd->pre[ref_idx], upsampled_ref->y_buffer,
6314 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
6315 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
6316 pd->subsampling_x, pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006317
Yue Chene9638cc2016-10-10 12:37:54 -07006318 best_mv_var = cpi->find_fractional_mv_step(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006319 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6320 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6321 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
6322 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, pw, ph,
6323 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006324
Yue Chene9638cc2016-10-10 12:37:54 -07006325 if (try_second) {
6326 const int minc = AOMMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
6327 const int maxc = AOMMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
6328 const int minr = AOMMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
6329 const int maxr = AOMMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
6330 int this_var;
6331 MV best_mv = x->best_mv.as_mv;
6332
6333 x->best_mv = x->second_best_mv;
6334 if (x->best_mv.as_mv.row * 8 <= maxr &&
6335 x->best_mv.as_mv.row * 8 >= minr &&
6336 x->best_mv.as_mv.col * 8 <= maxc &&
6337 x->best_mv.as_mv.col * 8 >= minc) {
6338 this_var = cpi->find_fractional_mv_step(
6339 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6340 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6341 cpi->sf.mv.subpel_iters_per_step,
6342 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
6343 &dis, &x->pred_sse[ref], NULL, pw, ph, 1);
6344 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
6345 x->best_mv.as_mv = best_mv;
6346 }
6347 }
6348
6349 // Restore the reference frames.
6350 pd->pre[ref_idx] = backup_pred;
6351 } else {
6352 cpi->find_fractional_mv_step(
6353 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6354 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6355 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
6356 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, 0, 0,
6357 0);
6358 }
6359#if CONFIG_MOTION_VAR
6360 break;
6361 case OBMC_CAUSAL:
6362 av1_find_best_obmc_sub_pixel_tree_up(
6363 cpi, x, mi_row, mi_col, &x->best_mv.as_mv, &ref_mv,
6364 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
6365 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
6366 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], 0,
6367 cpi->sf.use_upsampled_references);
6368 break;
6369 default: assert("Invalid motion mode!\n");
Yaowu Xuc27fc142016-08-22 16:08:15 -07006370 }
Yue Chene9638cc2016-10-10 12:37:54 -07006371#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006372 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006373 *rate_mv = av1_mv_bit_cost(&x->best_mv.as_mv, &ref_mv, x->nmvjointcost,
6374 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006375
Yue Chene9638cc2016-10-10 12:37:54 -07006376#if CONFIG_MOTION_VAR
6377 if (cpi->sf.adaptive_motion_search && mbmi->motion_mode == SIMPLE_TRANSLATION)
6378#else
6379 if (cpi->sf.adaptive_motion_search)
6380#endif // CONFIG_MOTION_VAR
6381 x->pred_mv[ref] = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006382
6383 if (scaled_ref_frame) {
6384 int i;
6385 for (i = 0; i < MAX_MB_PLANE; i++)
6386 xd->plane[i].pre[ref_idx] = backup_yv12[i];
6387 }
6388}
6389
David Barkerac37fa32016-12-02 12:30:21 +00006390static INLINE void restore_dst_buf(MACROBLOCKD *xd, BUFFER_SET dst) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006391 int i;
6392 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00006393 xd->plane[i].dst.buf = dst.plane[i];
6394 xd->plane[i].dst.stride = dst.stride[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006395 }
6396}
6397
Yaowu Xuc27fc142016-08-22 16:08:15 -07006398#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07006399static void do_masked_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006400 const uint8_t *mask, int mask_stride,
6401 BLOCK_SIZE bsize, int mi_row, int mi_col,
6402 int_mv *tmp_mv, int *rate_mv, int ref_idx,
6403 int mv_idx) {
6404 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07006405 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006406 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6407 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
6408 int bestsme = INT_MAX;
6409 int step_param;
6410 int sadpb = x->sadperbit16;
6411 MV mvp_full;
6412 int ref = mbmi->ref_frame[ref_idx];
6413 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
6414
6415 int tmp_col_min = x->mv_col_min;
6416 int tmp_col_max = x->mv_col_max;
6417 int tmp_row_min = x->mv_row_min;
6418 int tmp_row_max = x->mv_row_max;
6419
6420 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07006421 av1_get_scaled_ref_frame(cpi, ref);
Urvang Joshi368fbc92016-10-17 16:31:34 -07006422 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006423
6424 MV pred_mv[3];
6425 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6426 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
6427 pred_mv[2] = x->pred_mv[ref];
6428
6429#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006430 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006431#endif
6432
6433 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006434 // Swap out the reference frame for a version that's been scaled to
6435 // match the resolution of the current frame, allowing the existing
6436 // motion search code to be used without additional modifications.
6437 for (i = 0; i < MAX_MB_PLANE; i++)
6438 backup_yv12[i] = xd->plane[i].pre[ref_idx];
6439
Yaowu Xuf883b422016-08-30 14:01:10 -07006440 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006441 }
6442
Yaowu Xuf883b422016-08-30 14:01:10 -07006443 av1_set_mv_search_range(x, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006444
6445 // Work out the size of the first step in the mv step search.
6446 // 0 here is maximum length first step. 1 is MAX >> 1 etc.
6447 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6448 // Take wtd average of the step_params based on the last frame's
6449 // max mv magnitude and that based on the best ref mvs of the current
6450 // block for the given reference.
6451 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006452 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07006453 2;
6454 } else {
6455 step_param = cpi->mv_step_param;
6456 }
6457
6458 // TODO(debargha): is show_frame needed here?
6459 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size && cm->show_frame) {
6460 int boffset =
6461 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07006462 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
6463 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006464 }
6465
6466 if (cpi->sf.adaptive_motion_search) {
6467 int bwl = b_width_log2_lookup[bsize];
6468 int bhl = b_height_log2_lookup[bsize];
6469 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
6470
6471 if (tlevel < 5) step_param += 2;
6472
6473 // prev_mv_sad is not setup for dynamically scaled frames.
6474 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006475 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
6476 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
6477 x->pred_mv[ref].row = 0;
6478 x->pred_mv[ref].col = 0;
6479 tmp_mv->as_int = INVALID_MV;
6480
6481 if (scaled_ref_frame) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07006482 int j;
6483 for (j = 0; j < MAX_MB_PLANE; ++j)
6484 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006485 }
6486 return;
6487 }
6488 }
6489 }
6490 }
6491
6492 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
6493
6494 mvp_full.col >>= 3;
6495 mvp_full.row >>= 3;
6496
Yaowu Xuf883b422016-08-30 14:01:10 -07006497 bestsme = av1_masked_full_pixel_diamond(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006498 cpi, x, mask, mask_stride, &mvp_full, step_param, sadpb,
6499 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
6500 &tmp_mv->as_mv, ref_idx);
6501
6502 x->mv_col_min = tmp_col_min;
6503 x->mv_col_max = tmp_col_max;
6504 x->mv_row_min = tmp_row_min;
6505 x->mv_row_max = tmp_row_max;
6506
6507 if (bestsme < INT_MAX) {
6508 int dis; /* TODO: use dis in distortion calculation later. */
Yaowu Xuf883b422016-08-30 14:01:10 -07006509 av1_find_best_masked_sub_pixel_tree_up(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006510 cpi, x, mask, mask_stride, mi_row, mi_col, &tmp_mv->as_mv, &ref_mv,
6511 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
6512 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
6513 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], ref_idx,
6514 cpi->sf.use_upsampled_references);
6515 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006516 *rate_mv = av1_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmvjointcost,
6517 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006518
6519 if (cpi->sf.adaptive_motion_search && cm->show_frame)
6520 x->pred_mv[ref] = tmp_mv->as_mv;
6521
6522 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006523 for (i = 0; i < MAX_MB_PLANE; i++)
6524 xd->plane[i].pre[ref_idx] = backup_yv12[i];
6525 }
6526}
6527
Sarah Parker6fdc8532016-11-16 17:47:13 -08006528static void do_masked_motion_search_indexed(
6529 const AV1_COMP *const cpi, MACROBLOCK *x,
6530 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE bsize,
6531 int mi_row, int mi_col, int_mv *tmp_mv, int *rate_mv, int mv_idx[2],
6532 int which) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006533 // NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both
6534 MACROBLOCKD *xd = &x->e_mbd;
6535 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6536 BLOCK_SIZE sb_type = mbmi->sb_type;
6537 const uint8_t *mask;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006538 const int mask_stride = block_size_wide[bsize];
Sarah Parker6fdc8532016-11-16 17:47:13 -08006539 mask = av1_get_compound_type_mask(comp_data, sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006540
6541 if (which == 0 || which == 2)
6542 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
6543 &tmp_mv[0], &rate_mv[0], 0, mv_idx[0]);
6544
6545 if (which == 1 || which == 2) {
6546 // get the negative mask
Sarah Parker6fdc8532016-11-16 17:47:13 -08006547 mask = av1_get_compound_type_mask(comp_data, sb_type, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006548 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
6549 &tmp_mv[1], &rate_mv[1], 1, mv_idx[1]);
6550 }
6551}
6552#endif // CONFIG_EXT_INTER
6553
6554// In some situations we want to discount tha pparent cost of a new motion
6555// vector. Where there is a subtle motion field and especially where there is
6556// low spatial complexity then it can be hard to cover the cost of a new motion
6557// vector in a single block, even if that motion vector reduces distortion.
6558// However, once established that vector may be usable through the nearest and
6559// near mv modes to reduce distortion in subsequent blocks and also improve
6560// visual quality.
Urvang Joshi52648442016-10-13 17:27:51 -07006561static int discount_newmv_test(const AV1_COMP *const cpi, int this_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006562 int_mv this_mv,
6563 int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME],
6564 int ref_frame) {
6565 return (!cpi->rc.is_src_frame_alt_ref && (this_mode == NEWMV) &&
6566 (this_mv.as_int != 0) &&
6567 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
6568 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
6569 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
6570 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
6571}
6572
Yaowu Xu671f2bd2016-09-30 15:07:57 -07006573#define LEFT_TOP_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
6574#define RIGHT_BOTTOM_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006575
6576// TODO(jingning): this mv clamping function should be block size dependent.
6577static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
6578 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
6579 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
6580 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
6581 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
6582}
6583
6584#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006585static int estimate_wedge_sign(const AV1_COMP *cpi, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006586 const BLOCK_SIZE bsize, const uint8_t *pred0,
6587 int stride0, const uint8_t *pred1, int stride1) {
6588 const struct macroblock_plane *const p = &x->plane[0];
6589 const uint8_t *src = p->src.buf;
6590 int src_stride = p->src.stride;
6591 const int f_index = bsize - BLOCK_8X8;
6592 const int bw = 4 << (b_width_log2_lookup[bsize]);
6593 const int bh = 4 << (b_height_log2_lookup[bsize]);
6594 uint32_t esq[2][4], var;
6595 int64_t tl, br;
6596
Yaowu Xuf883b422016-08-30 14:01:10 -07006597#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006598 if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6599 pred0 = CONVERT_TO_BYTEPTR(pred0);
6600 pred1 = CONVERT_TO_BYTEPTR(pred1);
6601 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006602#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006603
6604 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred0, stride0, &esq[0][0]);
6605 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred0 + bw / 2,
6606 stride0, &esq[0][1]);
6607 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
6608 pred0 + bh / 2 * stride0, stride0, &esq[0][2]);
6609 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
6610 pred0 + bh / 2 * stride0 + bw / 2, stride0,
6611 &esq[0][3]);
6612 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred1, stride1, &esq[1][0]);
6613 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred1 + bw / 2,
6614 stride1, &esq[1][1]);
6615 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
6616 pred1 + bh / 2 * stride1, stride0, &esq[1][2]);
6617 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
6618 pred1 + bh / 2 * stride1 + bw / 2, stride0,
6619 &esq[1][3]);
6620 (void)var;
6621
6622 tl = (int64_t)(esq[0][0] + esq[0][1] + esq[0][2]) -
6623 (int64_t)(esq[1][0] + esq[1][1] + esq[1][2]);
6624 br = (int64_t)(esq[1][3] + esq[1][1] + esq[1][2]) -
6625 (int64_t)(esq[0][3] + esq[0][1] + esq[0][2]);
6626 return (tl + br > 0);
6627}
6628#endif // CONFIG_EXT_INTER
6629
6630#if !CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07006631static InterpFilter predict_interp_filter(
Yaowu Xuf883b422016-08-30 14:01:10 -07006632 const AV1_COMP *cpi, const MACROBLOCK *x, const BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006633 const int mi_row, const int mi_col,
James Zern7b9407a2016-05-18 23:48:05 -07006634 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME]) {
6635 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuf883b422016-08-30 14:01:10 -07006636 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006637 const MACROBLOCKD *xd = &x->e_mbd;
6638 int bsl = mi_width_log2_lookup[bsize];
6639 int pred_filter_search =
6640 cpi->sf.cb_pred_filter_search
6641 ? (((mi_row + mi_col) >> bsl) +
6642 get_chessboard_index(cm->current_video_frame)) &
6643 0x1
6644 : 0;
6645 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6646 const int is_comp_pred = has_second_ref(mbmi);
6647 const int this_mode = mbmi->mode;
6648 int refs[2] = { mbmi->ref_frame[0],
6649 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Yaowu Xuc27fc142016-08-22 16:08:15 -07006650 if (pred_filter_search) {
James Zern7b9407a2016-05-18 23:48:05 -07006651 InterpFilter af = SWITCHABLE, lf = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006652 if (xd->up_available) af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
6653 if (xd->left_available) lf = xd->mi[-1]->mbmi.interp_filter;
6654
6655#if CONFIG_EXT_INTER
6656 if ((this_mode != NEWMV && this_mode != NEWFROMNEARMV &&
6657 this_mode != NEW_NEWMV) ||
6658 (af == lf))
6659#else
6660 if ((this_mode != NEWMV) || (af == lf))
6661#endif // CONFIG_EXT_INTER
6662 best_filter = af;
6663 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006664 if (is_comp_pred) {
6665 if (cpi->sf.adaptive_mode_search) {
6666#if CONFIG_EXT_INTER
6667 switch (this_mode) {
6668 case NEAREST_NEARESTMV:
6669 if (single_filter[NEARESTMV][refs[0]] ==
6670 single_filter[NEARESTMV][refs[1]])
6671 best_filter = single_filter[NEARESTMV][refs[0]];
6672 break;
6673 case NEAREST_NEARMV:
6674 if (single_filter[NEARESTMV][refs[0]] ==
6675 single_filter[NEARMV][refs[1]])
6676 best_filter = single_filter[NEARESTMV][refs[0]];
6677 break;
6678 case NEAR_NEARESTMV:
6679 if (single_filter[NEARMV][refs[0]] ==
6680 single_filter[NEARESTMV][refs[1]])
6681 best_filter = single_filter[NEARMV][refs[0]];
6682 break;
6683 case NEAR_NEARMV:
6684 if (single_filter[NEARMV][refs[0]] == single_filter[NEARMV][refs[1]])
6685 best_filter = single_filter[NEARMV][refs[0]];
6686 break;
6687 case ZERO_ZEROMV:
6688 if (single_filter[ZEROMV][refs[0]] == single_filter[ZEROMV][refs[1]])
6689 best_filter = single_filter[ZEROMV][refs[0]];
6690 break;
6691 case NEW_NEWMV:
6692 if (single_filter[NEWMV][refs[0]] == single_filter[NEWMV][refs[1]])
6693 best_filter = single_filter[NEWMV][refs[0]];
6694 break;
6695 case NEAREST_NEWMV:
6696 if (single_filter[NEARESTMV][refs[0]] ==
6697 single_filter[NEWMV][refs[1]])
6698 best_filter = single_filter[NEARESTMV][refs[0]];
6699 break;
6700 case NEAR_NEWMV:
6701 if (single_filter[NEARMV][refs[0]] == single_filter[NEWMV][refs[1]])
6702 best_filter = single_filter[NEARMV][refs[0]];
6703 break;
6704 case NEW_NEARESTMV:
6705 if (single_filter[NEWMV][refs[0]] ==
6706 single_filter[NEARESTMV][refs[1]])
6707 best_filter = single_filter[NEWMV][refs[0]];
6708 break;
6709 case NEW_NEARMV:
6710 if (single_filter[NEWMV][refs[0]] == single_filter[NEARMV][refs[1]])
6711 best_filter = single_filter[NEWMV][refs[0]];
6712 break;
6713 default:
6714 if (single_filter[this_mode][refs[0]] ==
6715 single_filter[this_mode][refs[1]])
6716 best_filter = single_filter[this_mode][refs[0]];
6717 break;
6718 }
6719#else
6720 if (single_filter[this_mode][refs[0]] ==
6721 single_filter[this_mode][refs[1]])
6722 best_filter = single_filter[this_mode][refs[0]];
6723#endif // CONFIG_EXT_INTER
6724 }
6725 }
Angie Chiang75c22092016-10-25 12:19:16 -07006726 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
6727 best_filter = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006728 }
6729 return best_filter;
6730}
6731#endif
6732
6733#if CONFIG_EXT_INTER
6734// Choose the best wedge index and sign
Yaowu Xuf883b422016-08-30 14:01:10 -07006735static int64_t pick_wedge(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006736 const BLOCK_SIZE bsize, const uint8_t *const p0,
6737 const uint8_t *const p1, int *const best_wedge_sign,
6738 int *const best_wedge_index) {
6739 const MACROBLOCKD *const xd = &x->e_mbd;
6740 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006741 const int bw = block_size_wide[bsize];
6742 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006743 const int N = bw * bh;
6744 int rate;
6745 int64_t dist;
6746 int64_t rd, best_rd = INT64_MAX;
6747 int wedge_index;
6748 int wedge_sign;
6749 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
6750 const uint8_t *mask;
6751 uint64_t sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006752#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006753 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
6754 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
6755#else
6756 const int bd_round = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07006757#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006758
6759 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
6760 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
6761 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
6762 DECLARE_ALIGNED(32, int16_t, ds[MAX_SB_SQUARE]);
6763
6764 int64_t sign_limit;
6765
Yaowu Xuf883b422016-08-30 14:01:10 -07006766#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006767 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006768 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006769 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006770 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006771 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006772 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006773 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
6774 } else // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07006775#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006776 {
Yaowu Xuf883b422016-08-30 14:01:10 -07006777 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
6778 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
6779 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006780 }
6781
Yaowu Xuf883b422016-08-30 14:01:10 -07006782 sign_limit = ((int64_t)aom_sum_squares_i16(r0, N) -
6783 (int64_t)aom_sum_squares_i16(r1, N)) *
Yaowu Xuc27fc142016-08-22 16:08:15 -07006784 (1 << WEDGE_WEIGHT_BITS) / 2;
6785
Yaowu Xuf883b422016-08-30 14:01:10 -07006786 av1_wedge_compute_delta_squares(ds, r0, r1, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006787
6788 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006789 mask = av1_get_contiguous_soft_mask(wedge_index, 0, bsize);
6790 wedge_sign = av1_wedge_sign_from_residuals(ds, mask, N, sign_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006791
Yaowu Xuf883b422016-08-30 14:01:10 -07006792 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
6793 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006794 sse = ROUND_POWER_OF_TWO(sse, bd_round);
6795
6796 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
6797 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
6798
6799 if (rd < best_rd) {
6800 *best_wedge_index = wedge_index;
6801 *best_wedge_sign = wedge_sign;
6802 best_rd = rd;
6803 }
6804 }
6805
6806 return best_rd;
6807}
6808
6809// Choose the best wedge index the specified sign
6810static int64_t pick_wedge_fixed_sign(
Yaowu Xuf883b422016-08-30 14:01:10 -07006811 const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006812 const BLOCK_SIZE bsize, const uint8_t *const p0, const uint8_t *const p1,
6813 const int wedge_sign, int *const best_wedge_index) {
6814 const MACROBLOCKD *const xd = &x->e_mbd;
6815 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006816 const int bw = block_size_wide[bsize];
6817 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006818 const int N = bw * bh;
6819 int rate;
6820 int64_t dist;
6821 int64_t rd, best_rd = INT64_MAX;
6822 int wedge_index;
6823 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
6824 const uint8_t *mask;
6825 uint64_t sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006826#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006827 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
6828 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
6829#else
6830 const int bd_round = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07006831#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006832
6833 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
6834 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
6835
Yaowu Xuf883b422016-08-30 14:01:10 -07006836#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006837 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006838 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006839 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006840 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006841 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
6842 } else // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07006843#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006844 {
Yaowu Xuf883b422016-08-30 14:01:10 -07006845 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
6846 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006847 }
6848
6849 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006850 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
6851 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006852 sse = ROUND_POWER_OF_TWO(sse, bd_round);
6853
6854 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
6855 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
6856
6857 if (rd < best_rd) {
6858 *best_wedge_index = wedge_index;
6859 best_rd = rd;
6860 }
6861 }
6862
6863 return best_rd;
6864}
6865
Yaowu Xuf883b422016-08-30 14:01:10 -07006866static int64_t pick_interinter_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006867 const MACROBLOCK *const x,
6868 const BLOCK_SIZE bsize,
6869 const uint8_t *const p0,
6870 const uint8_t *const p1) {
6871 const MACROBLOCKD *const xd = &x->e_mbd;
6872 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006873 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006874
6875 int64_t rd;
6876 int wedge_index = -1;
6877 int wedge_sign = 0;
6878
6879 assert(is_interinter_wedge_used(bsize));
6880
6881 if (cpi->sf.fast_wedge_sign_estimate) {
6882 wedge_sign = estimate_wedge_sign(cpi, x, bsize, p0, bw, p1, bw);
6883 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, wedge_sign, &wedge_index);
6884 } else {
6885 rd = pick_wedge(cpi, x, bsize, p0, p1, &wedge_sign, &wedge_index);
6886 }
6887
Sarah Parker6fdc8532016-11-16 17:47:13 -08006888 mbmi->interinter_compound_data.wedge_sign = wedge_sign;
6889 mbmi->interinter_compound_data.wedge_index = wedge_index;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006890 return rd;
6891}
6892
Yaowu Xuf883b422016-08-30 14:01:10 -07006893static int64_t pick_interintra_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006894 const MACROBLOCK *const x,
6895 const BLOCK_SIZE bsize,
6896 const uint8_t *const p0,
6897 const uint8_t *const p1) {
6898 const MACROBLOCKD *const xd = &x->e_mbd;
6899 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6900
6901 int64_t rd;
6902 int wedge_index = -1;
6903
6904 assert(is_interintra_wedge_used(bsize));
6905
6906 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, 0, &wedge_index);
6907
6908 mbmi->interintra_wedge_sign = 0;
6909 mbmi->interintra_wedge_index = wedge_index;
6910 return rd;
6911}
Sarah Parker6fdc8532016-11-16 17:47:13 -08006912
6913static int interinter_compound_motion_search(const AV1_COMP *const cpi,
6914 MACROBLOCK *x,
6915 const BLOCK_SIZE bsize,
6916 const int this_mode, int mi_row,
6917 int mi_col) {
6918 const MACROBLOCKD *const xd = &x->e_mbd;
6919 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6920 int_mv tmp_mv[2];
6921 int rate_mvs[2], tmp_rate_mv = 0;
6922 if (this_mode == NEW_NEWMV) {
6923 int mv_idxs[2] = { 0, 0 };
6924 do_masked_motion_search_indexed(cpi, x, &mbmi->interinter_compound_data,
6925 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
6926 mv_idxs, 2);
6927 tmp_rate_mv = rate_mvs[0] + rate_mvs[1];
6928 mbmi->mv[0].as_int = tmp_mv[0].as_int;
6929 mbmi->mv[1].as_int = tmp_mv[1].as_int;
6930 } else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
6931 int mv_idxs[2] = { 0, 0 };
6932 do_masked_motion_search_indexed(cpi, x, &mbmi->interinter_compound_data,
6933 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
6934 mv_idxs, 0);
6935 tmp_rate_mv = rate_mvs[0];
6936 mbmi->mv[0].as_int = tmp_mv[0].as_int;
6937 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
6938 int mv_idxs[2] = { 0, 0 };
6939 do_masked_motion_search_indexed(cpi, x, &mbmi->interinter_compound_data,
6940 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
6941 mv_idxs, 1);
6942 tmp_rate_mv = rate_mvs[1];
6943 mbmi->mv[1].as_int = tmp_mv[1].as_int;
6944 }
6945 return tmp_rate_mv;
6946}
6947
6948static int64_t build_and_cost_compound_wedge(
6949 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
6950 const BLOCK_SIZE bsize, const int this_mode, int rs2, int rate_mv,
David Barkerac37fa32016-12-02 12:30:21 +00006951 BUFFER_SET *ctx, int *out_rate_mv, uint8_t **preds0, uint8_t **preds1,
6952 int *strides, int mi_row, int mi_col) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08006953 MACROBLOCKD *xd = &x->e_mbd;
6954 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6955 int rate_sum;
6956 int64_t dist_sum;
6957 int64_t best_rd_cur = INT64_MAX;
6958 int64_t rd = INT64_MAX;
6959 int tmp_skip_txfm_sb;
6960 int64_t tmp_skip_sse_sb;
6961
6962 best_rd_cur = pick_interinter_wedge(cpi, x, bsize, *preds0, *preds1);
6963 best_rd_cur += RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv, 0);
6964
6965 if (have_newmv_in_inter_mode(this_mode)) {
6966 *out_rate_mv = interinter_compound_motion_search(cpi, x, bsize, this_mode,
6967 mi_row, mi_col);
David Barkerac37fa32016-12-02 12:30:21 +00006968 av1_build_inter_predictors_sby(xd, mi_row, mi_col, ctx, bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08006969 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
6970 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
6971 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
Zoe Liu4d44f5a2016-12-14 17:46:19 -08006972 if (rd >= best_rd_cur) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08006973 mbmi->mv[0].as_int = cur_mv[0].as_int;
6974 mbmi->mv[1].as_int = cur_mv[1].as_int;
6975 *out_rate_mv = rate_mv;
6976 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0, preds0, strides,
6977 preds1, strides);
6978 }
6979 av1_subtract_plane(x, bsize, 0);
6980 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
6981 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
6982 if (rd != INT64_MAX)
6983 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
6984 best_rd_cur = rd;
6985
6986 } else {
6987 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0, preds0, strides,
6988 preds1, strides);
6989 av1_subtract_plane(x, bsize, 0);
6990 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
6991 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
6992 if (rd != INT64_MAX)
6993 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
6994 best_rd_cur = rd;
6995 }
6996 return best_rd_cur;
6997}
Yaowu Xuc27fc142016-08-22 16:08:15 -07006998#endif // CONFIG_EXT_INTER
6999
7000static int64_t handle_inter_mode(
Angie Chiang76159122016-11-09 12:13:22 -08007001 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
7002 RD_STATS *rd_stats, RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007003 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
7004 int mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07007005#if CONFIG_MOTION_VAR
Yue Chene9638cc2016-10-10 12:37:54 -07007006 uint8_t *above_pred_buf[3], int above_pred_stride[3],
7007 uint8_t *left_pred_buf[3], int left_pred_stride[3],
Yue Chencb60b182016-10-13 15:18:22 -07007008#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007009#if CONFIG_EXT_INTER
7010 int_mv single_newmvs[2][TOTAL_REFS_PER_FRAME],
7011 int single_newmvs_rate[2][TOTAL_REFS_PER_FRAME],
Sarah Parker6fdc8532016-11-16 17:47:13 -08007012 int *compmode_interintra_cost, int *compmode_interinter_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007013 int64_t (*const modelled_rd)[TOTAL_REFS_PER_FRAME],
7014#else
7015 int_mv single_newmv[TOTAL_REFS_PER_FRAME],
7016#endif // CONFIG_EXT_INTER
James Zern7b9407a2016-05-18 23:48:05 -07007017 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME],
Angie Chiang76159122016-11-09 12:13:22 -08007018 int (*single_skippable)[TOTAL_REFS_PER_FRAME], const int64_t ref_best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07007019 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007020 MACROBLOCKD *xd = &x->e_mbd;
7021 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7022 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
7023 const int is_comp_pred = has_second_ref(mbmi);
7024 const int this_mode = mbmi->mode;
7025 int_mv *frame_mv = mode_mv[this_mode];
7026 int i;
7027 int refs[2] = { mbmi->ref_frame[0],
7028 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
7029 int_mv cur_mv[2];
7030 int rate_mv = 0;
7031#if CONFIG_EXT_INTER
Angie Chiang75c22092016-10-25 12:19:16 -07007032 int pred_exists = 1;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007033 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007034 int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
7035 int_mv single_newmv[TOTAL_REFS_PER_FRAME];
7036 const unsigned int *const interintra_mode_cost =
7037 cpi->interintra_mode_cost[size_group_lookup[bsize]];
7038 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
7039#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07007040 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007041#endif
7042#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07007043#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007044 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
7045#else
7046 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07007047#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007048 uint8_t *tmp_buf;
7049
Yue Chencb60b182016-10-13 15:18:22 -07007050#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yue Chen69f18e12016-09-08 14:48:15 -07007051 MOTION_MODE motion_mode, last_motion_mode_allowed;
Angie Chiang76159122016-11-09 12:13:22 -08007052 int rate2_nocoeff = 0, best_xskip, best_disable_skip = 0;
7053 RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007054#if CONFIG_VAR_TX
7055 uint8_t best_blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
7056#endif // CONFIG_VAR_TX
Angie Chiang75c22092016-10-25 12:19:16 -07007057 int64_t best_rd = INT64_MAX;
Yue Chend326f762016-11-29 12:11:32 -08007058 MB_MODE_INFO base_mbmi, best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007059#if CONFIG_EXT_INTER
7060 int rate2_bmc_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007061 MB_MODE_INFO best_bmc_mbmi;
Yue Chen69f18e12016-09-08 14:48:15 -07007062#if CONFIG_MOTION_VAR
7063 int rate_mv_bmc;
7064#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007065#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07007066#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yue Chen69f18e12016-09-08 14:48:15 -07007067#if CONFIG_WARPED_MOTION
7068 double pts[144], pts_inref[144];
7069#endif // CONFIG_WARPED_MOTION
Angie Chiang75c22092016-10-25 12:19:16 -07007070 int64_t rd = INT64_MAX;
David Barkerac37fa32016-12-02 12:30:21 +00007071 BUFFER_SET orig_dst, tmp_dst;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007072 int rs = 0;
Angie Chiang75c22092016-10-25 12:19:16 -07007073 InterpFilter assign_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007074
7075 int skip_txfm_sb = 0;
7076 int64_t skip_sse_sb = INT64_MAX;
Yaowu Xub0d0d002016-11-22 09:26:43 -08007077 int16_t mode_ctx;
Angie Chiang76159122016-11-09 12:13:22 -08007078#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7079 av1_invalid_rd_stats(&best_rd_stats);
7080#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007081
7082#if CONFIG_EXT_INTER
7083 *compmode_interintra_cost = 0;
7084 mbmi->use_wedge_interintra = 0;
Sarah Parker6fdc8532016-11-16 17:47:13 -08007085 *compmode_interinter_cost = 0;
7086 mbmi->interinter_compound_data.type = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007087
7088 // is_comp_interintra_pred implies !is_comp_pred
7089 assert(!is_comp_interintra_pred || (!is_comp_pred));
7090 // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
7091 assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
7092#endif // CONFIG_EXT_INTER
7093
7094#if CONFIG_REF_MV
7095#if CONFIG_EXT_INTER
7096 if (is_comp_pred)
7097 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
7098 else
7099#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07007100 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
7101 mbmi->ref_frame, bsize, -1);
Yaowu Xub0d0d002016-11-22 09:26:43 -08007102#else // CONFIG_REF_MV
7103 mode_ctx = mbmi_ext->mode_context[refs[0]];
7104#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07007105
Yaowu Xuf883b422016-08-30 14:01:10 -07007106#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007107 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
7108 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf_);
7109 else
Yaowu Xuf883b422016-08-30 14:01:10 -07007110#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007111 tmp_buf = tmp_buf_;
David Barkerb8069f92016-11-18 14:49:56 +00007112 // Make sure that we didn't leave the plane destination buffers set
7113 // to tmp_buf at the end of the last iteration
7114 assert(xd->plane[0].dst.buf != tmp_buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007115
Yue Chen69f18e12016-09-08 14:48:15 -07007116#if CONFIG_WARPED_MOTION
7117 mbmi->num_proj_ref[0] = 0;
7118 mbmi->num_proj_ref[1] = 0;
7119#endif // CONFIG_WARPED_MOTION
7120
Yaowu Xuc27fc142016-08-22 16:08:15 -07007121 if (is_comp_pred) {
7122 if (frame_mv[refs[0]].as_int == INVALID_MV ||
7123 frame_mv[refs[1]].as_int == INVALID_MV)
7124 return INT64_MAX;
7125 }
7126
Yue Chene9638cc2016-10-10 12:37:54 -07007127 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007128 if (have_newmv_in_inter_mode(this_mode)) {
7129 if (is_comp_pred) {
7130#if CONFIG_EXT_INTER
7131 for (i = 0; i < 2; ++i) {
7132 single_newmv[refs[i]].as_int = single_newmvs[mv_idx][refs[i]].as_int;
7133 }
7134
7135 if (this_mode == NEW_NEWMV) {
7136 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7137 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7138
7139 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
7140 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, NULL,
7141 single_newmv, &rate_mv, 0);
7142 } else {
7143#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007144 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007145#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07007146 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007147 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007148 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007149#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007150 av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007151#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07007152 rate_mv += av1_mv_bit_cost(
Zoe Liu82c8c922016-11-01 14:52:34 -07007153 &frame_mv[refs[1]].as_mv, &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007154 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7155 }
7156 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
7157 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07007158 rate_mv = av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007159 &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007160 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007161 } else {
7162 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07007163 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007164 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007165 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007166 }
7167#else
7168 // Initialize mv using single prediction mode result.
7169 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7170 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7171
7172 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
7173 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col,
7174 single_newmv, &rate_mv, 0);
7175 } else {
7176#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007177 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007178#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07007179 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007180 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007181 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007182#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007183 av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007184#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07007185 rate_mv += av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007186 &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007187 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007188 }
7189#endif // CONFIG_EXT_INTER
7190 } else {
7191#if CONFIG_EXT_INTER
7192 if (is_comp_interintra_pred) {
7193 x->best_mv = single_newmvs[mv_idx][refs[0]];
7194 rate_mv = single_newmvs_rate[mv_idx][refs[0]];
7195 } else {
7196 single_motion_search(cpi, x, bsize, mi_row, mi_col, 0, mv_idx,
7197 &rate_mv);
7198 single_newmvs[mv_idx][refs[0]] = x->best_mv;
7199 single_newmvs_rate[mv_idx][refs[0]] = rate_mv;
7200 }
7201#else
7202 single_motion_search(cpi, x, bsize, mi_row, mi_col, &rate_mv);
7203 single_newmv[refs[0]] = x->best_mv;
7204#endif // CONFIG_EXT_INTER
7205
7206 if (x->best_mv.as_int == INVALID_MV) return INT64_MAX;
7207
7208 frame_mv[refs[0]] = x->best_mv;
7209 xd->mi[0]->bmi[0].as_mv[0] = x->best_mv;
7210
7211 // Estimate the rate implications of a new mv but discount this
7212 // under certain circumstances where we want to help initiate a weak
7213 // motion field, where the distortion gain for a single block may not
7214 // be enough to overcome the cost of a new mv.
7215 if (discount_newmv_test(cpi, this_mode, x->best_mv, mode_mv, refs[0])) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007216 rate_mv = AOMMAX((rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007217 }
7218 }
Angie Chiang76159122016-11-09 12:13:22 -08007219 rd_stats->rate += rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007220 }
7221
7222 for (i = 0; i < is_comp_pred + 1; ++i) {
7223 cur_mv[i] = frame_mv[refs[i]];
7224// Clip "next_nearest" so that it does not extend to far out of image
7225#if CONFIG_EXT_INTER
7226 if (this_mode != NEWMV && this_mode != NEWFROMNEARMV)
7227#else
7228 if (this_mode != NEWMV)
7229#endif // CONFIG_EXT_INTER
7230 clamp_mv2(&cur_mv[i].as_mv, xd);
7231
7232 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
7233 mbmi->mv[i].as_int = cur_mv[i].as_int;
7234 }
7235
7236#if CONFIG_REF_MV
7237#if CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08007238 if (this_mode == NEAREST_NEARESTMV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007239#else
Angie Chiang78a3bc12016-11-06 12:55:46 -08007240 if (this_mode == NEARESTMV && is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007241#endif // CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08007242 {
7243#if !CONFIG_EXT_INTER
7244 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
7245#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007246 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
7247 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
7248 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
7249
7250 for (i = 0; i < 2; ++i) {
7251 clamp_mv2(&cur_mv[i].as_mv, xd);
7252 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
7253 mbmi->mv[i].as_int = cur_mv[i].as_int;
7254 }
7255 }
7256 }
7257
7258#if CONFIG_EXT_INTER
7259 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
7260 if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
7261 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
7262
7263 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
7264 clamp_mv2(&cur_mv[0].as_mv, xd);
7265 if (mv_check_bounds(x, &cur_mv[0].as_mv)) return INT64_MAX;
7266 mbmi->mv[0].as_int = cur_mv[0].as_int;
7267 }
7268
7269 if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
7270 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
7271
7272 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
7273 clamp_mv2(&cur_mv[1].as_mv, xd);
7274 if (mv_check_bounds(x, &cur_mv[1].as_mv)) return INT64_MAX;
7275 mbmi->mv[1].as_int = cur_mv[1].as_int;
7276 }
7277 }
7278
7279 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
7280 if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV ||
7281 this_mode == NEAR_NEARMV) {
7282 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][1].this_mv;
7283
7284 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
7285 clamp_mv2(&cur_mv[0].as_mv, xd);
7286 if (mv_check_bounds(x, &cur_mv[0].as_mv)) return INT64_MAX;
7287 mbmi->mv[0].as_int = cur_mv[0].as_int;
7288 }
7289
7290 if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV ||
7291 this_mode == NEAR_NEARMV) {
7292 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][1].comp_mv;
7293
7294 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
7295 clamp_mv2(&cur_mv[1].as_mv, xd);
7296 if (mv_check_bounds(x, &cur_mv[1].as_mv)) return INT64_MAX;
7297 mbmi->mv[1].as_int = cur_mv[1].as_int;
7298 }
7299 }
7300#else
7301 if (this_mode == NEARMV && is_comp_pred) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007302 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007303 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
7304 int ref_mv_idx = mbmi->ref_mv_idx + 1;
7305 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
7306 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
7307
7308 for (i = 0; i < 2; ++i) {
7309 clamp_mv2(&cur_mv[i].as_mv, xd);
7310 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
7311 mbmi->mv[i].as_int = cur_mv[i].as_int;
7312 }
7313 }
7314 }
7315#endif // CONFIG_EXT_INTER
7316#endif // CONFIG_REF_MV
7317
7318 // do first prediction into the destination buffer. Do the next
7319 // prediction into a temporary buffer. Then keep track of which one
7320 // of these currently holds the best predictor, and use the other
7321 // one for future predictions. In the end, copy from tmp_buf to
7322 // dst if necessary.
7323 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00007324 tmp_dst.plane[i] = tmp_buf + i * MAX_SB_SQUARE;
7325 tmp_dst.stride[i] = MAX_SB_SIZE;
Angie Chiang75c22092016-10-25 12:19:16 -07007326 }
7327 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00007328 orig_dst.plane[i] = xd->plane[i].dst.buf;
7329 orig_dst.stride[i] = xd->plane[i].dst.stride;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007330 }
7331
7332 // We don't include the cost of the second reference here, because there
7333 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
7334 // words if you present them in that order, the second one is always known
7335 // if the first is known.
7336 //
7337 // Under some circumstances we discount the cost of new mv mode to encourage
7338 // initiation of a motion field.
7339 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]], mode_mv,
7340 refs[0])) {
7341#if CONFIG_REF_MV && CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08007342 rd_stats->rate +=
7343 AOMMIN(cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx),
7344 cost_mv_ref(cpi, NEARESTMV, is_comp_pred, mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007345#else
Angie Chiang76159122016-11-09 12:13:22 -08007346 rd_stats->rate += AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
7347 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007348#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
7349 } else {
7350#if CONFIG_REF_MV && CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08007351 rd_stats->rate += cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007352#else
Angie Chiang76159122016-11-09 12:13:22 -08007353 rd_stats->rate += cost_mv_ref(cpi, this_mode, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007354#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
7355 }
7356
Angie Chiang76159122016-11-09 12:13:22 -08007357 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, 0) > ref_best_rd &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07007358#if CONFIG_EXT_INTER
7359 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV
7360#else
7361 mbmi->mode != NEARESTMV
7362#endif // CONFIG_EXT_INTER
7363 )
7364 return INT64_MAX;
7365
Angie Chiang75c22092016-10-25 12:19:16 -07007366 if (cm->interp_filter == SWITCHABLE) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007367#if !CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007368 assign_filter =
7369 predict_interp_filter(cpi, x, bsize, mi_row, mi_col, single_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007370#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007371#if CONFIG_EXT_INTERP || CONFIG_DUAL_FILTER
7372 if (!av1_is_interp_needed(xd)) assign_filter = EIGHTTAP_REGULAR;
7373#endif
7374 } else {
7375 assign_filter = cm->interp_filter;
7376 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007377
Angie Chiang75c22092016-10-25 12:19:16 -07007378 { // Do interpolation filter search in the parentheses
7379 int tmp_rate;
7380 int64_t tmp_dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007381#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007382 mbmi->interp_filter[0] =
7383 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
7384 mbmi->interp_filter[1] =
7385 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
7386 mbmi->interp_filter[2] =
7387 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
7388 mbmi->interp_filter[3] =
7389 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007390#else
Angie Chiang75c22092016-10-25 12:19:16 -07007391 mbmi->interp_filter =
7392 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007393#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007394 rs = av1_get_switchable_rate(cpi, xd);
David Barkerac37fa32016-12-02 12:30:21 +00007395 av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
Angie Chiang75c22092016-10-25 12:19:16 -07007396 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7397 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7398 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007399
Angie Chiang75c22092016-10-25 12:19:16 -07007400 if (assign_filter == SWITCHABLE) {
7401 // do interp_filter search
7402 if (av1_is_interp_needed(xd)) {
Angie Chiang5678ad92016-11-21 09:38:40 -08007403#if CONFIG_DUAL_FILTER
7404 const int filter_set_size = DUAL_FILTER_SET_SIZE;
7405#else
7406 const int filter_set_size = SWITCHABLE_FILTERS;
7407#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007408 int best_in_temp = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007409#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007410 InterpFilter best_filter[4];
7411 av1_copy(best_filter, mbmi->interp_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007412#else
Angie Chiang75c22092016-10-25 12:19:16 -07007413 InterpFilter best_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007414#endif
David Barkerac37fa32016-12-02 12:30:21 +00007415 restore_dst_buf(xd, tmp_dst);
Angie Chiang75c22092016-10-25 12:19:16 -07007416 // EIGHTTAP_REGULAR mode is calculated beforehand
Angie Chiang5678ad92016-11-21 09:38:40 -08007417 for (i = 1; i < filter_set_size; ++i) {
Angie Chiang75c22092016-10-25 12:19:16 -07007418 int tmp_skip_sb = 0;
7419 int64_t tmp_skip_sse = INT64_MAX;
7420 int tmp_rs;
Angie Chiang3655dcd2016-10-28 09:05:27 -07007421 int64_t tmp_rd;
Angie Chiang75c22092016-10-25 12:19:16 -07007422#if CONFIG_DUAL_FILTER
7423 mbmi->interp_filter[0] = filter_sets[i][0];
7424 mbmi->interp_filter[1] = filter_sets[i][1];
7425 mbmi->interp_filter[2] = filter_sets[i][0];
7426 mbmi->interp_filter[3] = filter_sets[i][1];
7427#else
7428 mbmi->interp_filter = i;
7429#endif
7430 tmp_rs = av1_get_switchable_rate(cpi, xd);
David Barkerac37fa32016-12-02 12:30:21 +00007431 av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
Angie Chiang75c22092016-10-25 12:19:16 -07007432 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7433 &tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
7434 tmp_rd = RDCOST(x->rdmult, x->rddiv, tmp_rs + tmp_rate, tmp_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007435
Angie Chiang75c22092016-10-25 12:19:16 -07007436 if (tmp_rd < rd) {
7437 rd = tmp_rd;
7438 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007439#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007440 av1_copy(best_filter, mbmi->interp_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007441#else
Angie Chiang75c22092016-10-25 12:19:16 -07007442 best_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007443#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007444 skip_txfm_sb = tmp_skip_sb;
7445 skip_sse_sb = tmp_skip_sse;
7446 best_in_temp = !best_in_temp;
7447 if (best_in_temp) {
David Barkerac37fa32016-12-02 12:30:21 +00007448 restore_dst_buf(xd, orig_dst);
Angie Chiang75c22092016-10-25 12:19:16 -07007449 } else {
David Barkerac37fa32016-12-02 12:30:21 +00007450 restore_dst_buf(xd, tmp_dst);
Angie Chiang75c22092016-10-25 12:19:16 -07007451 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007452 }
7453 }
Angie Chiang75c22092016-10-25 12:19:16 -07007454 if (best_in_temp) {
David Barkerac37fa32016-12-02 12:30:21 +00007455 restore_dst_buf(xd, tmp_dst);
Angie Chiang75c22092016-10-25 12:19:16 -07007456 } else {
David Barkerac37fa32016-12-02 12:30:21 +00007457 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007458 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007459#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007460 av1_copy(mbmi->interp_filter, best_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007461#else
Angie Chiang75c22092016-10-25 12:19:16 -07007462 mbmi->interp_filter = best_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007463#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007464 } else {
Angie Chiang75c22092016-10-25 12:19:16 -07007465#if !CONFIG_EXT_INTERP && !CONFIG_DUAL_FILTER
7466 int tmp_rs;
7467 InterpFilter best_filter = mbmi->interp_filter;
7468 rs = av1_get_switchable_rate(cpi, xd);
7469 for (i = 1; i < SWITCHABLE_FILTERS; ++i) {
7470 mbmi->interp_filter = i;
7471 tmp_rs = av1_get_switchable_rate(cpi, xd);
7472 if (tmp_rs < rs) {
7473 rs = tmp_rs;
7474 best_filter = i;
7475 }
7476 }
7477 mbmi->interp_filter = best_filter;
7478#else
7479 assert(0);
7480#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007481 }
7482 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007483 }
7484
Yaowu Xuc27fc142016-08-22 16:08:15 -07007485#if CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07007486#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007487 best_bmc_mbmi = *mbmi;
Angie Chiang76159122016-11-09 12:13:22 -08007488 rate2_bmc_nocoeff = rd_stats->rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007489 if (cm->interp_filter == SWITCHABLE) rate2_bmc_nocoeff += rs;
Yue Chen69f18e12016-09-08 14:48:15 -07007490#if CONFIG_MOTION_VAR
7491 rate_mv_bmc = rate_mv;
Yue Chencb60b182016-10-13 15:18:22 -07007492#endif // CONFIG_MOTION_VAR
Yue Chen69f18e12016-09-08 14:48:15 -07007493#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007494
Sarah Parker6fdc8532016-11-16 17:47:13 -08007495 if (is_comp_pred) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07007496 int rate_sum, rs2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007497 int64_t dist_sum;
Sarah Parker6fdc8532016-11-16 17:47:13 -08007498 int64_t best_rd_compound = INT64_MAX, best_rd_cur = INT64_MAX;
7499 INTERINTER_COMPOUND_DATA best_compound_data;
7500 int_mv best_mv[2];
7501 int best_tmp_rate_mv = rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007502 int tmp_skip_txfm_sb;
7503 int64_t tmp_skip_sse_sb;
Sarah Parker6fddd182016-11-10 20:57:20 -08007504 int compound_type_cost[COMPOUND_TYPES];
Sarah Parker6fdc8532016-11-16 17:47:13 -08007505 uint8_t pred0[2 * MAX_SB_SQUARE];
7506 uint8_t pred1[2 * MAX_SB_SQUARE];
7507 uint8_t *preds0[1] = { pred0 };
7508 uint8_t *preds1[1] = { pred1 };
7509 int strides[1] = { bw };
7510 COMPOUND_TYPE cur_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007511
Sarah Parker6fdc8532016-11-16 17:47:13 -08007512 best_mv[0].as_int = cur_mv[0].as_int;
7513 best_mv[1].as_int = cur_mv[1].as_int;
7514 memset(&best_compound_data, 0, sizeof(INTERINTER_COMPOUND_DATA));
Sarah Parker6fddd182016-11-10 20:57:20 -08007515 av1_cost_tokens(compound_type_cost, cm->fc->compound_type_prob[bsize],
7516 av1_compound_type_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007517
Sarah Parker6fdc8532016-11-16 17:47:13 -08007518 if (is_interinter_wedge_used(bsize)) {
7519 // get inter predictors to use for masked compound modes
Yaowu Xuf883b422016-08-30 14:01:10 -07007520 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007521 xd, bsize, 0, 0, mi_row, mi_col, 0, preds0, strides);
Yaowu Xuf883b422016-08-30 14:01:10 -07007522 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007523 xd, bsize, 0, 0, mi_row, mi_col, 1, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007524 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007525
Sarah Parker6fdc8532016-11-16 17:47:13 -08007526 for (cur_type = COMPOUND_AVERAGE; cur_type < COMPOUND_TYPES; cur_type++) {
7527 best_rd_cur = INT64_MAX;
7528 mbmi->interinter_compound_data.type = cur_type;
7529 rs2 = av1_cost_literal(get_interinter_compound_type_bits(
7530 bsize, mbmi->interinter_compound_data.type)) +
7531 compound_type_cost[mbmi->interinter_compound_data.type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007532
Sarah Parker6fdc8532016-11-16 17:47:13 -08007533 switch (cur_type) {
7534 case COMPOUND_AVERAGE:
David Barkerac37fa32016-12-02 12:30:21 +00007535 av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007536 av1_subtract_plane(x, bsize, 0);
7537 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7538 &tmp_skip_txfm_sb, &tmp_skip_sse_sb,
7539 INT64_MAX);
7540 if (rd != INT64_MAX)
7541 rd =
7542 RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
7543 best_rd_compound = rd;
7544 break;
7545 case COMPOUND_WEDGE:
7546 if (!is_interinter_wedge_used(bsize)) break;
7547 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
7548 best_rd_compound / 3 < ref_best_rd) {
7549 int tmp_rate_mv = 0;
7550 best_rd_cur = build_and_cost_compound_wedge(
David Barkerac37fa32016-12-02 12:30:21 +00007551 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
7552 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007553
Sarah Parker6fdc8532016-11-16 17:47:13 -08007554 if (best_rd_cur < best_rd_compound) {
7555 best_rd_compound = best_rd_cur;
7556 memcpy(&best_compound_data, &mbmi->interinter_compound_data,
7557 sizeof(best_compound_data));
7558 if (have_newmv_in_inter_mode(this_mode)) {
7559 best_tmp_rate_mv = tmp_rate_mv;
7560 best_mv[0].as_int = mbmi->mv[0].as_int;
7561 best_mv[1].as_int = mbmi->mv[1].as_int;
7562 // reset to original mvs for next iteration
7563 mbmi->mv[0].as_int = cur_mv[0].as_int;
7564 mbmi->mv[1].as_int = cur_mv[1].as_int;
7565 }
7566 }
7567 }
7568 break;
Sarah Parker2f6ce752016-12-08 15:26:46 -08007569#if CONFIG_COMPOUND_SEGMENT
7570 case COMPOUND_SEG: break;
7571#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08007572 default: assert(0); return 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007573 }
7574 }
Sarah Parker6fdc8532016-11-16 17:47:13 -08007575 memcpy(&mbmi->interinter_compound_data, &best_compound_data,
7576 sizeof(INTERINTER_COMPOUND_DATA));
7577 if (have_newmv_in_inter_mode(this_mode)) {
7578 mbmi->mv[0].as_int = best_mv[0].as_int;
7579 mbmi->mv[1].as_int = best_mv[1].as_int;
7580 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
7581 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
7582 if (mbmi->interinter_compound_data.type) {
7583 rd_stats->rate += best_tmp_rate_mv - rate_mv;
7584 rate_mv = best_tmp_rate_mv;
7585 }
7586 }
7587
7588 if (ref_best_rd < INT64_MAX && best_rd_compound / 3 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00007589 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007590 return INT64_MAX;
David Barkerb8069f92016-11-18 14:49:56 +00007591 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007592
7593 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007594
Sarah Parker6fdc8532016-11-16 17:47:13 -08007595 *compmode_interinter_cost =
7596 compound_type_cost[mbmi->interinter_compound_data.type] +
7597 av1_cost_literal(get_interinter_compound_type_bits(
7598 bsize, mbmi->interinter_compound_data.type));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007599 }
7600
7601 if (is_comp_interintra_pred) {
7602 INTERINTRA_MODE best_interintra_mode = II_DC_PRED;
7603 int64_t best_interintra_rd = INT64_MAX;
7604 int rmode, rate_sum;
7605 int64_t dist_sum;
7606 int j;
7607 int64_t best_interintra_rd_nowedge = INT64_MAX;
7608 int64_t best_interintra_rd_wedge = INT64_MAX;
7609 int rwedge;
7610 int_mv tmp_mv;
7611 int tmp_rate_mv = 0;
7612 int tmp_skip_txfm_sb;
7613 int64_t tmp_skip_sse_sb;
7614 DECLARE_ALIGNED(16, uint8_t, intrapred_[2 * MAX_SB_SQUARE]);
7615 uint8_t *intrapred;
7616
Yaowu Xuf883b422016-08-30 14:01:10 -07007617#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007618 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
7619 intrapred = CONVERT_TO_BYTEPTR(intrapred_);
7620 else
Yaowu Xuf883b422016-08-30 14:01:10 -07007621#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007622 intrapred = intrapred_;
7623
7624 mbmi->ref_frame[1] = NONE;
7625 for (j = 0; j < MAX_MB_PLANE; j++) {
7626 xd->plane[j].dst.buf = tmp_buf + j * MAX_SB_SQUARE;
7627 xd->plane[j].dst.stride = bw;
7628 }
David Barkerac37fa32016-12-02 12:30:21 +00007629 av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
7630 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007631 mbmi->ref_frame[1] = INTRA_FRAME;
7632 mbmi->use_wedge_interintra = 0;
7633
7634 for (j = 0; j < INTERINTRA_MODES; ++j) {
7635 mbmi->interintra_mode = (INTERINTRA_MODE)j;
7636 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00007637 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
7638 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07007639 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007640 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7641 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7642 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate_mv + rate_sum, dist_sum);
7643 if (rd < best_interintra_rd) {
7644 best_interintra_rd = rd;
7645 best_interintra_mode = mbmi->interintra_mode;
7646 }
7647 }
7648 mbmi->interintra_mode = best_interintra_mode;
7649 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00007650 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
7651 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07007652 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
7653 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007654 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7655 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7656 if (rd != INT64_MAX)
7657 rd = RDCOST(x->rdmult, x->rddiv, rate_mv + rmode + rate_sum, dist_sum);
7658 best_interintra_rd = rd;
7659
7660 if (ref_best_rd < INT64_MAX && best_interintra_rd > 2 * ref_best_rd) {
David Barkerb8069f92016-11-18 14:49:56 +00007661 // Don't need to call restore_dst_buf here
Yaowu Xuc27fc142016-08-22 16:08:15 -07007662 return INT64_MAX;
7663 }
7664 if (is_interintra_wedge_used(bsize)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007665 rwedge = av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007666 if (rd != INT64_MAX)
7667 rd = RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge + rate_sum,
7668 dist_sum);
7669 best_interintra_rd_nowedge = rd;
7670
7671 // Disbale wedge search if source variance is small
7672 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh) {
7673 mbmi->use_wedge_interintra = 1;
7674
Yaowu Xuf883b422016-08-30 14:01:10 -07007675 rwedge = av1_cost_literal(get_interintra_wedge_bits(bsize)) +
7676 av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007677
7678 best_interintra_rd_wedge =
7679 pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
7680
7681 best_interintra_rd_wedge +=
7682 RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge, 0);
7683 // Refine motion vector.
7684 if (have_newmv_in_inter_mode(this_mode)) {
7685 // get negative of mask
Yaowu Xuf883b422016-08-30 14:01:10 -07007686 const uint8_t *mask = av1_get_contiguous_soft_mask(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007687 mbmi->interintra_wedge_index, 1, bsize);
7688 do_masked_motion_search(cpi, x, mask, bw, bsize, mi_row, mi_col,
7689 &tmp_mv, &tmp_rate_mv, 0, mv_idx);
7690 mbmi->mv[0].as_int = tmp_mv.as_int;
David Barkerac37fa32016-12-02 12:30:21 +00007691 av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007692 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7693 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7694 rd = RDCOST(x->rdmult, x->rddiv,
7695 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
7696 if (rd < best_interintra_rd_wedge) {
7697 best_interintra_rd_wedge = rd;
7698 } else {
7699 tmp_mv.as_int = cur_mv[0].as_int;
7700 tmp_rate_mv = rate_mv;
7701 }
7702 } else {
7703 tmp_mv.as_int = cur_mv[0].as_int;
7704 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07007705 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007706 }
7707 // Evaluate closer to true rd
Yaowu Xuf883b422016-08-30 14:01:10 -07007708 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007709 rd =
7710 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7711 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7712 if (rd != INT64_MAX)
7713 rd = RDCOST(x->rdmult, x->rddiv,
7714 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
7715 best_interintra_rd_wedge = rd;
7716 if (best_interintra_rd_wedge < best_interintra_rd_nowedge) {
7717 mbmi->use_wedge_interintra = 1;
7718 best_interintra_rd = best_interintra_rd_wedge;
7719 mbmi->mv[0].as_int = tmp_mv.as_int;
Angie Chiang76159122016-11-09 12:13:22 -08007720 rd_stats->rate += tmp_rate_mv - rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007721 rate_mv = tmp_rate_mv;
7722 } else {
7723 mbmi->use_wedge_interintra = 0;
7724 best_interintra_rd = best_interintra_rd_nowedge;
7725 mbmi->mv[0].as_int = cur_mv[0].as_int;
7726 }
7727 } else {
7728 mbmi->use_wedge_interintra = 0;
7729 best_interintra_rd = best_interintra_rd_nowedge;
7730 }
7731 }
7732
7733 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007734 *compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07007735 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007736 *compmode_interintra_cost += interintra_mode_cost[mbmi->interintra_mode];
7737 if (is_interintra_wedge_used(bsize)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007738 *compmode_interintra_cost += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007739 cm->fc->wedge_interintra_prob[bsize], mbmi->use_wedge_interintra);
7740 if (mbmi->use_wedge_interintra) {
7741 *compmode_interintra_cost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07007742 av1_cost_literal(get_interintra_wedge_bits(bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007743 }
7744 }
7745 } else if (is_interintra_allowed(mbmi)) {
7746 *compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07007747 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007748 }
7749
7750#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07007751 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007752#if CONFIG_DUAL_FILTER
7753 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = EIGHTTAP_REGULAR;
7754#else
7755 mbmi->interp_filter = EIGHTTAP_REGULAR;
7756#endif
7757 pred_exists = 0;
7758 }
7759#endif // CONFIG_EXT_INTERP
Angie Chiang75c22092016-10-25 12:19:16 -07007760 if (pred_exists == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007761 int tmp_rate;
7762 int64_t tmp_dist;
David Barkerac37fa32016-12-02 12:30:21 +00007763 av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007764 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7765 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7766 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
7767 }
Angie Chiang75c22092016-10-25 12:19:16 -07007768#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07007769
7770#if CONFIG_DUAL_FILTER
7771 if (!is_comp_pred) single_filter[this_mode][refs[0]] = mbmi->interp_filter[0];
7772#else
7773 if (!is_comp_pred) single_filter[this_mode][refs[0]] = mbmi->interp_filter;
7774#endif
7775
7776#if CONFIG_EXT_INTER
7777 if (modelled_rd != NULL) {
7778 if (is_comp_pred) {
7779 const int mode0 = compound_ref0_mode(this_mode);
7780 const int mode1 = compound_ref1_mode(this_mode);
7781 int64_t mrd =
Yaowu Xuf883b422016-08-30 14:01:10 -07007782 AOMMIN(modelled_rd[mode0][refs[0]], modelled_rd[mode1][refs[1]]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007783 if (rd / 4 * 3 > mrd && ref_best_rd < INT64_MAX) {
David Barkerac37fa32016-12-02 12:30:21 +00007784 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007785 return INT64_MAX;
7786 }
7787 } else if (!is_comp_interintra_pred) {
7788 modelled_rd[this_mode][refs[0]] = rd;
7789 }
7790 }
7791#endif // CONFIG_EXT_INTER
7792
7793 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
7794 // if current pred_error modeled rd is substantially more than the best
7795 // so far, do not bother doing full rd
7796 if (rd / 2 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00007797 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007798 return INT64_MAX;
7799 }
7800 }
7801
Angie Chiang76159122016-11-09 12:13:22 -08007802 if (cm->interp_filter == SWITCHABLE) rd_stats->rate += rs;
Yue Chen69f18e12016-09-08 14:48:15 -07007803#if CONFIG_WARPED_MOTION
7804 aom_clear_system_state();
7805 mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
7806#endif // CONFIG_WARPED_MOTION
7807#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08007808 rate2_nocoeff = rd_stats->rate;
Yue Chen69f18e12016-09-08 14:48:15 -07007809 last_motion_mode_allowed = motion_mode_allowed(mbmi);
Yue Chend326f762016-11-29 12:11:32 -08007810 base_mbmi = *mbmi;
Yue Chen69f18e12016-09-08 14:48:15 -07007811#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007812
Yue Chencb60b182016-10-13 15:18:22 -07007813#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007814 best_rd = INT64_MAX;
Yue Chend326f762016-11-29 12:11:32 -08007815 for (motion_mode = SIMPLE_TRANSLATION;
Yue Chen69f18e12016-09-08 14:48:15 -07007816 motion_mode <= last_motion_mode_allowed; motion_mode++) {
7817 int64_t tmp_rd = INT64_MAX;
Yue Chend326f762016-11-29 12:11:32 -08007818 int tmp_rate;
Yue Chen69f18e12016-09-08 14:48:15 -07007819 int64_t tmp_dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007820#if CONFIG_EXT_INTER
Yue Chend326f762016-11-29 12:11:32 -08007821 int tmp_rate2 =
7822 motion_mode != SIMPLE_TRANSLATION ? rate2_bmc_nocoeff : rate2_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007823#else
7824 int tmp_rate2 = rate2_nocoeff;
7825#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07007826
Yue Chend326f762016-11-29 12:11:32 -08007827 *mbmi = base_mbmi;
7828 mbmi->motion_mode = motion_mode;
Yue Chencb60b182016-10-13 15:18:22 -07007829#if CONFIG_MOTION_VAR
Yue Chencb60b182016-10-13 15:18:22 -07007830 if (mbmi->motion_mode == OBMC_CAUSAL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007831#if CONFIG_EXT_INTER
7832 *mbmi = best_bmc_mbmi;
Yue Chencb60b182016-10-13 15:18:22 -07007833 mbmi->motion_mode = OBMC_CAUSAL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007834#endif // CONFIG_EXT_INTER
7835 if (!is_comp_pred && have_newmv_in_inter_mode(this_mode)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007836 int tmp_rate_mv = 0;
7837
Yue Chene9638cc2016-10-10 12:37:54 -07007838 single_motion_search(cpi, x, bsize, mi_row, mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007839#if CONFIG_EXT_INTER
Yue Chene9638cc2016-10-10 12:37:54 -07007840 0, mv_idx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007841#endif // CONFIG_EXT_INTER
Yue Chene9638cc2016-10-10 12:37:54 -07007842 &tmp_rate_mv);
7843 mbmi->mv[0].as_int = x->best_mv.as_int;
7844 if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
7845 refs[0])) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007846 tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007847 }
7848#if CONFIG_EXT_INTER
7849 tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
7850#else
7851 tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
7852#endif // CONFIG_EXT_INTER
7853#if CONFIG_EXT_INTERP
7854#if CONFIG_DUAL_FILTER
7855 if (!has_subpel_mv_component(xd->mi[0], xd, 0))
Yue Chend326f762016-11-29 12:11:32 -08007856 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007857 if (!has_subpel_mv_component(xd->mi[0], xd, 1))
Yue Chend326f762016-11-29 12:11:32 -08007858 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007859#else
Yue Chend326f762016-11-29 12:11:32 -08007860 if (!av1_is_interp_needed(xd)) mbmi->interp_filter = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007861#endif // CONFIG_DUAL_FILTER
7862 // This is not quite correct with CONFIG_DUAL_FILTER when a filter
7863 // is needed in only one direction
Yaowu Xuf883b422016-08-30 14:01:10 -07007864 if (!av1_is_interp_needed(xd)) tmp_rate2 -= rs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007865#endif // CONFIG_EXT_INTERP
David Barkerac37fa32016-12-02 12:30:21 +00007866 av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007867#if CONFIG_EXT_INTER
7868 } else {
David Barkerac37fa32016-12-02 12:30:21 +00007869 av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007870#endif // CONFIG_EXT_INTER
7871 }
Yue Chene9638cc2016-10-10 12:37:54 -07007872 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, above_pred_buf,
7873 above_pred_stride, left_pred_buf,
7874 left_pred_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007875 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7876 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7877 }
Yue Chencb60b182016-10-13 15:18:22 -07007878#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007879
7880#if CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07007881 if (mbmi->motion_mode == WARPED_CAUSAL) {
Yue Chen69f18e12016-09-08 14:48:15 -07007882#if CONFIG_EXT_INTER
7883 *mbmi = best_bmc_mbmi;
7884 mbmi->motion_mode = WARPED_CAUSAL;
7885#endif // CONFIG_EXT_INTER
7886 mbmi->wm_params[0].wmtype = DEFAULT_WMTYPE;
7887#if CONFIG_DUAL_FILTER
7888 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
7889 ? EIGHTTAP_REGULAR
7890 : cm->interp_filter;
7891 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
7892 ? EIGHTTAP_REGULAR
7893 : cm->interp_filter;
7894#else
7895 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
7896 : cm->interp_filter;
7897#endif // CONFIG_DUAL_FILTER
7898
7899 if (find_projection(mbmi->num_proj_ref[0], pts, pts_inref,
7900 &mbmi->wm_params[0]) == 0) {
7901 int plane;
7902#if CONFIG_AOM_HIGHBITDEPTH
7903 int use_hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7904#endif // CONFIG_AOM_HIGHBITDEPTH
7905
7906 for (plane = 0; plane < 3; ++plane) {
7907 const struct macroblockd_plane *pd = &xd->plane[plane];
7908
7909 av1_warp_plane(&mbmi->wm_params[0],
7910#if CONFIG_AOM_HIGHBITDEPTH
7911 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
7912#endif // CONFIG_AOM_HIGHBITDEPTH
7913 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
7914 pd->pre[0].stride, pd->dst.buf,
7915 (mi_col * MI_SIZE) >> pd->subsampling_x,
7916 (mi_row * MI_SIZE) >> pd->subsampling_y,
Jingning Hanff6ee6a2016-12-07 09:55:21 -08007917 (xd->n8_w * MI_SIZE) >> pd->subsampling_x,
7918 (xd->n8_h * MI_SIZE) >> pd->subsampling_y,
7919 pd->dst.stride, pd->subsampling_x, pd->subsampling_y,
7920 16, 16, 0);
Yue Chen69f18e12016-09-08 14:48:15 -07007921 }
7922
7923 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7924 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7925 } else {
7926 continue;
7927 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007928 }
7929#endif // CONFIG_WARPED_MOTION
7930 x->skip = 0;
7931
Yue Chen8a78a2b2016-11-17 18:23:38 -08007932 rd_stats->dist = 0;
7933 rd_stats->sse = 0;
7934 rd_stats->skip = 1;
Angie Chiang76159122016-11-09 12:13:22 -08007935 rd_stats->rate = tmp_rate2;
Yue Chen69f18e12016-09-08 14:48:15 -07007936 if (last_motion_mode_allowed > SIMPLE_TRANSLATION) {
7937#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7938 if (last_motion_mode_allowed == WARPED_CAUSAL)
7939#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7940 rd_stats->rate += cpi->motion_mode_cost[bsize][mbmi->motion_mode];
7941#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7942 else
7943 rd_stats->rate += cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
7944#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7945 }
7946#if CONFIG_WARPED_MOTION
7947 if (mbmi->motion_mode == WARPED_CAUSAL) {
7948 rd_stats->rate -= rs;
7949 }
7950#endif // CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07007951#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007952 if (!skip_txfm_sb) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007953 int64_t rdcosty = INT64_MAX;
Angie Chiangb5dda482016-11-02 16:19:58 -07007954 int is_cost_valid_uv = 0;
Angie Chiang76159122016-11-09 12:13:22 -08007955
Yaowu Xu1e761992016-11-09 15:01:47 -08007956 // cost and distortion
Yaowu Xu1e761992016-11-09 15:01:47 -08007957 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007958#if CONFIG_VAR_TX
Yaowu Xu1e761992016-11-09 15:01:47 -08007959 if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id]) {
Angie Chiang76159122016-11-09 12:13:22 -08007960 select_tx_type_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
Yaowu Xu1e761992016-11-09 15:01:47 -08007961 } else {
7962 int idx, idy;
Angie Chiang76159122016-11-09 12:13:22 -08007963 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
Yaowu Xu1e761992016-11-09 15:01:47 -08007964 for (idy = 0; idy < xd->n8_h; ++idy)
7965 for (idx = 0; idx < xd->n8_w; ++idx)
7966 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang3aab6502016-11-10 17:48:16 -08007967 memset(x->blk_skip[0], rd_stats_y->skip,
Yaowu Xu1e761992016-11-09 15:01:47 -08007968 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7969 }
Angie Chiang0e9a2e92016-11-08 09:45:40 -08007970#else
Yaowu Xu1e761992016-11-09 15:01:47 -08007971 /* clang-format off */
Angie Chiang76159122016-11-09 12:13:22 -08007972 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
Yaowu Xu1e761992016-11-09 15:01:47 -08007973/* clang-format on */
Yaowu Xuc27fc142016-08-22 16:08:15 -07007974#endif // CONFIG_VAR_TX
7975
Angie Chiang76159122016-11-09 12:13:22 -08007976 if (rd_stats_y->rate == INT_MAX) {
7977 av1_invalid_rd_stats(rd_stats);
Yue Chencb60b182016-10-13 15:18:22 -07007978#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7979 if (mbmi->motion_mode != SIMPLE_TRANSLATION) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007980 continue;
7981 } else {
Yue Chencb60b182016-10-13 15:18:22 -07007982#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
David Barkerac37fa32016-12-02 12:30:21 +00007983 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007984 return INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007985#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007986 }
Yue Chencb60b182016-10-13 15:18:22 -07007987#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007988 }
7989
Angie Chiang76159122016-11-09 12:13:22 -08007990 av1_merge_rd_stats(rd_stats, rd_stats_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007991
Angie Chiang76159122016-11-09 12:13:22 -08007992 rdcosty = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
7993 rdcosty = AOMMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc1c6f6a2016-11-08 11:24:01 -08007994/* clang-format off */
Yaowu Xuc27fc142016-08-22 16:08:15 -07007995#if CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07007996 is_cost_valid_uv =
Angie Chiang76159122016-11-09 12:13:22 -08007997 inter_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
Angie Chiang284d7772016-11-08 11:06:45 -08007998#else
7999 is_cost_valid_uv =
Angie Chiang76159122016-11-09 12:13:22 -08008000 super_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
Angie Chiang284d7772016-11-08 11:06:45 -08008001#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07008002 if (!is_cost_valid_uv) {
Yue Chencb60b182016-10-13 15:18:22 -07008003#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008004 continue;
8005#else
David Barkerac37fa32016-12-02 12:30:21 +00008006 restore_dst_buf(xd, orig_dst);
Debargha Mukherjee0e119122016-11-04 12:10:23 -07008007 return INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07008008#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008009 }
Yaowu Xuc1c6f6a2016-11-08 11:24:01 -08008010 /* clang-format on */
Angie Chiang76159122016-11-09 12:13:22 -08008011 av1_merge_rd_stats(rd_stats, rd_stats_uv);
Angie Chiang3963d632016-11-10 18:41:40 -08008012#if CONFIG_RD_DEBUG
8013 // record transform block coefficient cost
8014 // TODO(angiebird): So far rd_debug tool only detects descrepancy of
8015 // coefficient cost. Therefore, it is fine to copy rd_stats into mbmi
8016 // here because we already collect the coefficient cost. Move this part to
8017 // other place when we need to compare non-coefficient cost.
8018 mbmi->rd_stats = *rd_stats;
8019#endif
Yue Chencb60b182016-10-13 15:18:22 -07008020#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08008021 if (rd_stats->skip) {
8022 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
8023 rd_stats_y->rate = 0;
8024 rd_stats_uv->rate = 0;
8025 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008026 mbmi->skip = 0;
8027 // here mbmi->skip temporarily plays a role as what this_skip2 does
8028 } else if (!xd->lossless[mbmi->segment_id] &&
8029 (RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08008030 rd_stats_y->rate + rd_stats_uv->rate +
Yaowu Xuf883b422016-08-30 14:01:10 -07008031 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Angie Chiang76159122016-11-09 12:13:22 -08008032 rd_stats->dist) >=
Yaowu Xuc27fc142016-08-22 16:08:15 -07008033 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08008034 av1_cost_bit(av1_get_skip_prob(cm, xd), 1),
8035 rd_stats->sse))) {
8036 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
8037 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8038 rd_stats->dist = rd_stats->sse;
8039 rd_stats_y->rate = 0;
8040 rd_stats_uv->rate = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008041 mbmi->skip = 1;
8042 } else {
Angie Chiang76159122016-11-09 12:13:22 -08008043 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008044 mbmi->skip = 0;
8045 }
8046 *disable_skip = 0;
Yue Chencb60b182016-10-13 15:18:22 -07008047#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008048 } else {
8049 x->skip = 1;
8050 *disable_skip = 1;
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07008051 mbmi->tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008052
8053// The cost of skip bit needs to be added.
Yue Chencb60b182016-10-13 15:18:22 -07008054#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008055 mbmi->skip = 0;
Yue Chencb60b182016-10-13 15:18:22 -07008056#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08008057 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008058
Angie Chiang76159122016-11-09 12:13:22 -08008059 rd_stats->dist = skip_sse_sb;
8060 rd_stats->sse = skip_sse_sb;
8061 rd_stats_y->rate = 0;
8062 rd_stats_uv->rate = 0;
8063 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008064 }
Yue Chen8a78a2b2016-11-17 18:23:38 -08008065#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8066 if (!is_comp_pred && mbmi->motion_mode == SIMPLE_TRANSLATION)
8067 single_skippable[this_mode][refs[0]] = rd_stats->skip;
8068#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parkere5299862016-08-16 14:57:37 -07008069#if CONFIG_GLOBAL_MOTION
8070 if (this_mode == ZEROMV) {
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08008071 rd_stats->rate += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[0]);
Angie Chiang76159122016-11-09 12:13:22 -08008072 if (is_comp_pred)
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08008073 rd_stats->rate += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[1]);
Sarah Parkere5299862016-08-16 14:57:37 -07008074 }
8075#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008076
Yue Chencb60b182016-10-13 15:18:22 -07008077#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08008078 tmp_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
Yue Chencb60b182016-10-13 15:18:22 -07008079 if (mbmi->motion_mode == SIMPLE_TRANSLATION || (tmp_rd < best_rd)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008080 best_mbmi = *mbmi;
8081 best_rd = tmp_rd;
Angie Chiang76159122016-11-09 12:13:22 -08008082 best_rd_stats = *rd_stats;
8083 best_rd_stats_y = *rd_stats_y;
8084 best_rd_stats_uv = *rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008085#if CONFIG_VAR_TX
8086 for (i = 0; i < MAX_MB_PLANE; ++i)
8087 memcpy(best_blk_skip[i], x->blk_skip[i],
8088 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8089#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07008090 best_xskip = x->skip;
8091 best_disable_skip = *disable_skip;
Yaowu Xuf883b422016-08-30 14:01:10 -07008092#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008093 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008094 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008095 cpi, &xd->plane[0].dst, bsize, xd->bd);
8096 } else {
8097 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008098 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008099 }
8100#else
8101 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008102 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
8103#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008104 }
8105 }
8106
8107 if (best_rd == INT64_MAX) {
Angie Chiang76159122016-11-09 12:13:22 -08008108 av1_invalid_rd_stats(rd_stats);
David Barkerac37fa32016-12-02 12:30:21 +00008109 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008110 return INT64_MAX;
8111 }
8112 *mbmi = best_mbmi;
Angie Chiang76159122016-11-09 12:13:22 -08008113 *rd_stats = best_rd_stats;
8114 *rd_stats_y = best_rd_stats_y;
8115 *rd_stats_uv = best_rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008116#if CONFIG_VAR_TX
8117 for (i = 0; i < MAX_MB_PLANE; ++i)
8118 memcpy(x->blk_skip[i], best_blk_skip[i],
8119 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8120#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07008121 x->skip = best_xskip;
8122 *disable_skip = best_disable_skip;
Yue Chencb60b182016-10-13 15:18:22 -07008123#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008124
Yue Chen8a78a2b2016-11-17 18:23:38 -08008125#if !(CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION)
Angie Chiang76159122016-11-09 12:13:22 -08008126 if (!is_comp_pred) single_skippable[this_mode][refs[0]] = rd_stats->skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008127
Yaowu Xuf883b422016-08-30 14:01:10 -07008128#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008129 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008130 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008131 cpi, &xd->plane[0].dst, bsize, xd->bd);
8132 } else {
8133 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008134 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008135 }
8136#else
8137 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008138 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
8139#endif // CONFIG_AOM_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07008140#endif // !(CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008141
David Barkerac37fa32016-12-02 12:30:21 +00008142 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008143 return 0; // The rate-distortion cost will be re-calculated by caller.
8144}
8145
Urvang Joshi52648442016-10-13 17:27:51 -07008146void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
8147 RD_COST *rd_cost, BLOCK_SIZE bsize,
8148 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
8149 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008150 MACROBLOCKD *const xd = &x->e_mbd;
8151 struct macroblockd_plane *const pd = xd->plane;
8152 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
8153 int y_skip = 0, uv_skip = 0;
8154 int64_t dist_y = 0, dist_uv = 0;
8155 TX_SIZE max_uv_tx_size;
Jingning Han271bb2c2016-12-14 12:34:46 -08008156 const int unify_bsize = CONFIG_CB4X4;
8157
Yaowu Xuc27fc142016-08-22 16:08:15 -07008158 ctx->skip = 0;
8159 xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
8160 xd->mi[0]->mbmi.ref_frame[1] = NONE;
8161
Jingning Han271bb2c2016-12-14 12:34:46 -08008162 if (bsize >= BLOCK_8X8 || unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008163 if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y,
8164 &y_skip, bsize, best_rd) >= best_rd) {
8165 rd_cost->rate = INT_MAX;
8166 return;
8167 }
8168 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008169 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07008170 &dist_y, &y_skip, best_rd) >= best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008171 rd_cost->rate = INT_MAX;
8172 return;
8173 }
8174 }
Debargha Mukherjee2f123402016-08-30 17:43:38 -07008175 max_uv_tx_size = uv_txsize_lookup[bsize][xd->mi[0]->mbmi.tx_size]
8176 [pd[1].subsampling_x][pd[1].subsampling_y];
Jingning Han271bb2c2016-12-14 12:34:46 -08008177
8178#if CONFIG_CB4X4
8179 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
8180 &uv_skip, bsize, max_uv_tx_size);
8181#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07008182 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
Yaowu Xuf883b422016-08-30 14:01:10 -07008183 &uv_skip, AOMMAX(BLOCK_8X8, bsize), max_uv_tx_size);
Jingning Han271bb2c2016-12-14 12:34:46 -08008184#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008185
8186 if (y_skip && uv_skip) {
8187 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
Yaowu Xuf883b422016-08-30 14:01:10 -07008188 av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008189 rd_cost->dist = dist_y + dist_uv;
8190 } else {
8191 rd_cost->rate =
Yaowu Xuf883b422016-08-30 14:01:10 -07008192 rate_y + rate_uv + av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008193 rd_cost->dist = dist_y + dist_uv;
8194 }
8195
8196 ctx->mic = *xd->mi[0];
8197 ctx->mbmi_ext = *x->mbmi_ext;
8198 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
8199}
8200
Yaowu Xuc27fc142016-08-22 16:08:15 -07008201// Do we have an internal image edge (e.g. formatting bars).
Urvang Joshi52648442016-10-13 17:27:51 -07008202int av1_internal_image_edge(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008203 return (cpi->oxcf.pass == 2) &&
8204 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
8205 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
8206}
8207
8208// Checks to see if a super block is on a horizontal image edge.
8209// In most cases this is the "real" edge unless there are formatting
8210// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07008211int av1_active_h_edge(const AV1_COMP *cpi, int mi_row, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008212 int top_edge = 0;
8213 int bottom_edge = cpi->common.mi_rows;
8214 int is_active_h_edge = 0;
8215
8216 // For two pass account for any formatting bars detected.
8217 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07008218 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008219
8220 // The inactive region is specified in MBs not mi units.
8221 // The image edge is in the following MB row.
8222 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
8223
8224 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07008225 bottom_edge = AOMMAX(top_edge, bottom_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008226 }
8227
8228 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
8229 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
8230 is_active_h_edge = 1;
8231 }
8232 return is_active_h_edge;
8233}
8234
8235// Checks to see if a super block is on a vertical image edge.
8236// In most cases this is the "real" edge unless there are formatting
8237// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07008238int av1_active_v_edge(const AV1_COMP *cpi, int mi_col, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008239 int left_edge = 0;
8240 int right_edge = cpi->common.mi_cols;
8241 int is_active_v_edge = 0;
8242
8243 // For two pass account for any formatting bars detected.
8244 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07008245 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008246
8247 // The inactive region is specified in MBs not mi units.
8248 // The image edge is in the following MB row.
8249 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
8250
8251 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07008252 right_edge = AOMMAX(left_edge, right_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008253 }
8254
8255 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
8256 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
8257 is_active_v_edge = 1;
8258 }
8259 return is_active_v_edge;
8260}
8261
8262// Checks to see if a super block is at the edge of the active image.
8263// In most cases this is the "real" edge unless there are formatting
8264// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07008265int av1_active_edge_sb(const AV1_COMP *cpi, int mi_row, int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008266 return av1_active_h_edge(cpi, mi_row, cpi->common.mib_size) ||
8267 av1_active_v_edge(cpi, mi_col, cpi->common.mib_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008268}
8269
Urvang Joshib100db72016-10-12 16:28:56 -07008270#if CONFIG_PALETTE
Urvang Joshi52648442016-10-13 17:27:51 -07008271static void restore_uv_color_map(const AV1_COMP *const cpi, MACROBLOCK *x) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008272 MACROBLOCKD *const xd = &x->e_mbd;
8273 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
8274 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
8275 const BLOCK_SIZE bsize = mbmi->sb_type;
Jingning Hanae5cfde2016-11-30 12:01:44 -08008276 const int rows = block_size_high[bsize] >> (xd->plane[1].subsampling_y);
8277 const int cols = block_size_wide[bsize] >> (xd->plane[1].subsampling_x);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008278 int src_stride = x->plane[1].src.stride;
8279 const uint8_t *const src_u = x->plane[1].src.buf;
8280 const uint8_t *const src_v = x->plane[2].src.buf;
8281 float *const data = x->palette_buffer->kmeans_data_buf;
8282 float centroids[2 * PALETTE_MAX_SIZE];
8283 uint8_t *const color_map = xd->plane[1].color_index_map;
8284 int r, c;
Yaowu Xuf883b422016-08-30 14:01:10 -07008285#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008286 const uint16_t *const src_u16 = CONVERT_TO_SHORTPTR(src_u);
8287 const uint16_t *const src_v16 = CONVERT_TO_SHORTPTR(src_v);
Yaowu Xuf883b422016-08-30 14:01:10 -07008288#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008289 (void)cpi;
8290
8291 for (r = 0; r < rows; ++r) {
8292 for (c = 0; c < cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008293#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008294 if (cpi->common.use_highbitdepth) {
8295 data[(r * cols + c) * 2] = src_u16[r * src_stride + c];
8296 data[(r * cols + c) * 2 + 1] = src_v16[r * src_stride + c];
8297 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07008298#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008299 data[(r * cols + c) * 2] = src_u[r * src_stride + c];
8300 data[(r * cols + c) * 2 + 1] = src_v[r * src_stride + c];
Yaowu Xuf883b422016-08-30 14:01:10 -07008301#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008302 }
Yaowu Xuf883b422016-08-30 14:01:10 -07008303#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008304 }
8305 }
8306
8307 for (r = 1; r < 3; ++r) {
8308 for (c = 0; c < pmi->palette_size[1]; ++c) {
8309 centroids[c * 2 + r - 1] = pmi->palette_colors[r * PALETTE_MAX_SIZE + c];
8310 }
8311 }
8312
Yaowu Xuf883b422016-08-30 14:01:10 -07008313 av1_calc_indices(data, centroids, color_map, rows * cols,
8314 pmi->palette_size[1], 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008315}
Urvang Joshib100db72016-10-12 16:28:56 -07008316#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008317
hui su5db97432016-10-14 16:10:14 -07008318#if CONFIG_FILTER_INTRA
8319static void pick_filter_intra_interframe(
8320 const AV1_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
Urvang Joshi52648442016-10-13 17:27:51 -07008321 BLOCK_SIZE bsize, int *rate_uv_intra, int *rate_uv_tokenonly,
8322 int64_t *dist_uv, int *skip_uv, PREDICTION_MODE *mode_uv,
hui su5db97432016-10-14 16:10:14 -07008323 FILTER_INTRA_MODE_INFO *filter_intra_mode_info_uv,
8324#if CONFIG_EXT_INTRA
8325 int8_t *uv_angle_delta,
8326#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07008327#if CONFIG_PALETTE
8328 PALETTE_MODE_INFO *pmi_uv, int palette_ctx,
8329#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008330 int skip_mask, unsigned int *ref_costs_single, int64_t *best_rd,
8331 int64_t *best_intra_rd, PREDICTION_MODE *best_intra_mode,
8332 int *best_mode_index, int *best_skip2, int *best_mode_skippable,
8333#if CONFIG_SUPERTX
8334 int *returnrate_nocoef,
8335#endif // CONFIG_SUPERTX
8336 int64_t *best_pred_rd, MB_MODE_INFO *best_mbmode, RD_COST *rd_cost) {
Urvang Joshi52648442016-10-13 17:27:51 -07008337 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008338 MACROBLOCKD *const xd = &x->e_mbd;
8339 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008340#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008341 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07008342#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008343 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
8344 int rate2 = 0, rate_y = INT_MAX, skippable = 0, rate_uv, rate_dummy, i;
8345 int dc_mode_index;
8346 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
8347 int64_t distortion2 = 0, distortion_y = 0, this_rd = *best_rd, distortion_uv;
8348 TX_SIZE uv_tx;
8349
8350 for (i = 0; i < MAX_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07008351 if (av1_mode_order[i].mode == DC_PRED &&
8352 av1_mode_order[i].ref_frame[0] == INTRA_FRAME)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008353 break;
8354 dc_mode_index = i;
8355 assert(i < MAX_MODES);
8356
8357 // TODO(huisu): use skip_mask for further speedup.
8358 (void)skip_mask;
8359 mbmi->mode = DC_PRED;
8360 mbmi->uv_mode = DC_PRED;
8361 mbmi->ref_frame[0] = INTRA_FRAME;
8362 mbmi->ref_frame[1] = NONE;
hui su5db97432016-10-14 16:10:14 -07008363 if (!rd_pick_filter_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
8364 &skippable, bsize, intra_mode_cost[mbmi->mode],
8365 &this_rd, 0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008366 return;
hui su5db97432016-10-14 16:10:14 -07008367 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008368 if (rate_y == INT_MAX) return;
8369
Debargha Mukherjee2f123402016-08-30 17:43:38 -07008370 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
8371 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008372 if (rate_uv_intra[uv_tx] == INT_MAX) {
8373 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
8374 &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx],
8375 &skip_uv[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07008376#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008377 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008378#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07008379 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
8380#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008381 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui su5db97432016-10-14 16:10:14 -07008382#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008383 }
8384
8385 rate_uv = rate_uv_tokenonly[uv_tx];
8386 distortion_uv = dist_uv[uv_tx];
8387 skippable = skippable && skip_uv[uv_tx];
8388 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07008389#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008390 if (cm->allow_screen_content_tools) {
8391 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
8392 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
8393 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
8394 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
8395 }
Urvang Joshib100db72016-10-12 16:28:56 -07008396#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07008397#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008398 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui su5db97432016-10-14 16:10:14 -07008399#endif // CONFIG_EXT_INTRA
8400 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
8401 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
8402 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
8403 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
8404 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008405 }
8406
8407 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
8408 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07008409#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008410 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07008411 rate2 += av1_cost_bit(
8412 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07008413#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008414
8415 if (!xd->lossless[mbmi->segment_id]) {
8416 // super_block_yrd above includes the cost of the tx_size in the
8417 // tokenonly rate, but for intra blocks, tx_size is always coded
8418 // (prediction granularity), so we account for it in the full rate,
8419 // not the tokenonly rate.
clang-format67948d32016-09-07 22:40:40 -07008420 rate_y -= cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
Jingning Hanb0a71302016-10-25 16:28:49 -07008421 [tx_size_to_depth(mbmi->tx_size)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008422 }
8423
hui su5db97432016-10-14 16:10:14 -07008424 rate2 += av1_cost_bit(cm->fc->filter_intra_probs[0],
8425 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
8426 rate2 += write_uniform_cost(
8427 FILTER_INTRA_MODES, mbmi->filter_intra_mode_info.filter_intra_mode[0]);
8428#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08008429 if (av1_is_directional_mode(mbmi->uv_mode, bsize)) {
8430 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA_UV + 1,
8431 MAX_ANGLE_DELTA_UV + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008432 }
hui su5db97432016-10-14 16:10:14 -07008433#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008434 if (mbmi->mode == DC_PRED) {
hui su5db97432016-10-14 16:10:14 -07008435 rate2 +=
8436 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
8437 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
8438 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
8439 rate2 +=
8440 write_uniform_cost(FILTER_INTRA_MODES,
8441 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008442 }
8443 distortion2 = distortion_y + distortion_uv;
Angie Chiangff6d8902016-10-21 11:02:09 -07008444 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07008445#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008446 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008447 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008448 cpi, &xd->plane[0].dst, bsize, xd->bd);
8449 } else {
8450 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008451 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008452 }
8453#else
8454 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008455 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
8456#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008457
8458 rate2 += ref_costs_single[INTRA_FRAME];
8459
8460 if (skippable) {
8461 rate2 -= (rate_y + rate_uv);
8462 rate_y = 0;
8463 rate_uv = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07008464 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008465 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07008466 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008467 }
8468 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008469
8470 if (this_rd < *best_intra_rd) {
8471 *best_intra_rd = this_rd;
8472 *best_intra_mode = mbmi->mode;
8473 }
8474 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07008475 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008476
8477 if (this_rd < *best_rd) {
8478 *best_mode_index = dc_mode_index;
8479 mbmi->mv[0].as_int = 0;
8480 rd_cost->rate = rate2;
8481#if CONFIG_SUPERTX
8482 if (x->skip)
8483 *returnrate_nocoef = rate2;
8484 else
8485 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07008486 *returnrate_nocoef -= av1_cost_bit(av1_get_skip_prob(cm, xd), skippable);
8487 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
8488 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008489#endif // CONFIG_SUPERTX
8490 rd_cost->dist = distortion2;
8491 rd_cost->rdcost = this_rd;
8492 *best_rd = this_rd;
8493 *best_mbmode = *mbmi;
8494 *best_skip2 = 0;
8495 *best_mode_skippable = skippable;
8496 }
8497}
hui su5db97432016-10-14 16:10:14 -07008498#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008499
Yue Chencb60b182016-10-13 15:18:22 -07008500#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008501static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
8502 const MACROBLOCKD *xd, int mi_row,
8503 int mi_col, const uint8_t *above,
8504 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -07008505 int left_stride);
Yue Chencb60b182016-10-13 15:18:22 -07008506#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008507
Urvang Joshi52648442016-10-13 17:27:51 -07008508void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
Yaowu Xuf883b422016-08-30 14:01:10 -07008509 MACROBLOCK *x, int mi_row, int mi_col,
8510 RD_COST *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008511#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07008512 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008513#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07008514 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
8515 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07008516 const AV1_COMMON *const cm = &cpi->common;
8517 const RD_OPT *const rd_opt = &cpi->rd;
8518 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008519 MACROBLOCKD *const xd = &x->e_mbd;
8520 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008521#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008522 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07008523#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008524 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
8525 const struct segmentation *const seg = &cm->seg;
8526 PREDICTION_MODE this_mode;
8527 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
8528 unsigned char segment_id = mbmi->segment_id;
8529 int comp_pred, i, k;
8530 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8531 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
8532#if CONFIG_EXT_INTER
8533 int_mv single_newmvs[2][TOTAL_REFS_PER_FRAME] = { { { 0 } }, { { 0 } } };
8534 int single_newmvs_rate[2][TOTAL_REFS_PER_FRAME] = { { 0 }, { 0 } };
8535 int64_t modelled_rd[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8536#else
8537 int_mv single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
8538#endif // CONFIG_EXT_INTER
James Zern7b9407a2016-05-18 23:48:05 -07008539 InterpFilter single_inter_filter[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008540 int single_skippable[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8541 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
8542 0,
Yaowu Xuf883b422016-08-30 14:01:10 -07008543 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008544#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008545 AOM_LAST2_FLAG,
8546 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008547#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008548 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008549#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008550 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008551#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008552 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07008553 };
8554 int64_t best_rd = best_rd_so_far;
8555 int best_rate_y = INT_MAX, best_rate_uv = INT_MAX;
8556 int64_t best_pred_diff[REFERENCE_MODES];
8557 int64_t best_pred_rd[REFERENCE_MODES];
8558 MB_MODE_INFO best_mbmode;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07008559#if CONFIG_REF_MV
8560 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
8561 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8562#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008563 int best_mode_skippable = 0;
8564 int midx, best_mode_index = -1;
8565 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
8566 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -07008567 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008568 int64_t best_intra_rd = INT64_MAX;
8569 unsigned int best_pred_sse = UINT_MAX;
8570 PREDICTION_MODE best_intra_mode = DC_PRED;
8571 int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES];
Urvang Joshi368fbc92016-10-17 16:31:34 -07008572 int64_t dist_uvs[TX_SIZES];
8573 int skip_uvs[TX_SIZES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008574 PREDICTION_MODE mode_uv[TX_SIZES];
Urvang Joshib100db72016-10-12 16:28:56 -07008575#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008576 PALETTE_MODE_INFO pmi_uv[TX_SIZES];
Urvang Joshib100db72016-10-12 16:28:56 -07008577#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008578#if CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008579 int8_t uv_angle_delta[TX_SIZES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008580 int is_directional_mode, angle_stats_ready = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008581 uint8_t directional_mode_skip_mask[INTRA_MODES];
8582#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008583#if CONFIG_FILTER_INTRA
8584 int8_t dc_skipped = 1;
8585 FILTER_INTRA_MODE_INFO filter_intra_mode_info_uv[TX_SIZES];
8586#endif // CONFIG_FILTER_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07008587 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008588 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
8589 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
8590 int best_skip2 = 0;
8591 uint8_t ref_frame_skip_mask[2] = { 0 };
8592#if CONFIG_EXT_INTER
8593 uint32_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
8594 MV_REFERENCE_FRAME best_single_inter_ref = LAST_FRAME;
8595 int64_t best_single_inter_rd = INT64_MAX;
8596#else
8597 uint16_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
8598#endif // CONFIG_EXT_INTER
8599 int mode_skip_start = sf->mode_skip_start + 1;
8600 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
8601 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
8602 int64_t mode_threshold[MAX_MODES];
8603 int *mode_map = tile_data->mode_map[bsize];
8604 const int mode_search_skip_flags = sf->mode_search_skip_flags;
8605 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
Yushin Cho77bba8d2016-11-04 16:36:56 -07008606#if CONFIG_PVQ
8607 od_rollback_buffer pre_buf;
8608#endif
8609
Urvang Joshib100db72016-10-12 16:28:56 -07008610#if CONFIG_PALETTE || CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08008611 const int rows = block_size_high[bsize];
8612 const int cols = block_size_wide[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07008613#endif // CONFIG_PALETTE || CONFIG_EXT_INTRA
8614#if CONFIG_PALETTE
8615 int palette_ctx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008616 const MODE_INFO *above_mi = xd->above_mi;
8617 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshib100db72016-10-12 16:28:56 -07008618#endif // CONFIG_PALETTE
Yue Chencb60b182016-10-13 15:18:22 -07008619#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008620#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008621 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8622 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8623#else
8624 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
8625 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07008626#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008627 DECLARE_ALIGNED(16, int32_t, weighted_src_buf[MAX_SB_SQUARE]);
8628 DECLARE_ALIGNED(16, int32_t, mask2d_buf[MAX_SB_SQUARE]);
8629 uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
8630 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8631 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8632 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8633 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8634 int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8635 int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8636
Yaowu Xuf883b422016-08-30 14:01:10 -07008637#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008638 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
8639 int len = sizeof(uint16_t);
8640 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
8641 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
8642 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_SB_SQUARE * len);
8643 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
8644 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
8645 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_SB_SQUARE * len);
8646 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07008647#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008648 dst_buf1[0] = tmp_buf1;
8649 dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
8650 dst_buf1[2] = tmp_buf1 + 2 * MAX_SB_SQUARE;
8651 dst_buf2[0] = tmp_buf2;
8652 dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
8653 dst_buf2[2] = tmp_buf2 + 2 * MAX_SB_SQUARE;
Yaowu Xuf883b422016-08-30 14:01:10 -07008654#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008655 }
Yaowu Xuf883b422016-08-30 14:01:10 -07008656#endif // CONFIG_AOM_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07008657#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008658
Yaowu Xuf883b422016-08-30 14:01:10 -07008659 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008660
Urvang Joshib100db72016-10-12 16:28:56 -07008661#if CONFIG_PALETTE
8662 av1_zero(pmi_uv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008663 if (cm->allow_screen_content_tools) {
8664 if (above_mi)
8665 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
8666 if (left_mi)
8667 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
8668 }
Urvang Joshib100db72016-10-12 16:28:56 -07008669#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008670
8671#if CONFIG_EXT_INTRA
8672 memset(directional_mode_skip_mask, 0,
8673 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
8674#endif // CONFIG_EXT_INTRA
8675
8676 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
8677 &comp_mode_p);
8678
8679 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
8680 for (i = 0; i < TX_SIZES; i++) rate_uv_intra[i] = INT_MAX;
8681 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
8682 for (i = 0; i < MB_MODE_COUNT; ++i) {
8683 for (k = 0; k < TOTAL_REFS_PER_FRAME; ++k) {
8684 single_inter_filter[i][k] = SWITCHABLE;
8685 single_skippable[i][k] = 0;
8686 }
8687 }
8688
8689 rd_cost->rate = INT_MAX;
8690#if CONFIG_SUPERTX
8691 *returnrate_nocoef = INT_MAX;
8692#endif // CONFIG_SUPERTX
8693
8694 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
8695 x->pred_mv_sad[ref_frame] = INT_MAX;
8696 x->mbmi_ext->mode_context[ref_frame] = 0;
8697#if CONFIG_REF_MV && CONFIG_EXT_INTER
8698 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
8699#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
8700 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
8701 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
8702 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
8703 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
8704 }
8705 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkere5299862016-08-16 14:57:37 -07008706#if CONFIG_GLOBAL_MOTION
8707 frame_mv[ZEROMV][ref_frame].as_int =
David Barkercdcac6d2016-12-01 17:04:16 +00008708 gm_get_motion_vector(&cm->global_motion[ref_frame],
8709 cm->allow_high_precision_mv)
8710 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07008711#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008712 frame_mv[ZEROMV][ref_frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07008713#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008714#if CONFIG_EXT_INTER
8715 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
8716 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
8717 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
8718#endif // CONFIG_EXT_INTER
8719 }
8720
8721#if CONFIG_REF_MV
8722 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
8723 MODE_INFO *const mi = xd->mi[0];
8724 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
8725 x->mbmi_ext->mode_context[ref_frame] = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07008726 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
8727 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07008728#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008729 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008730#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008731 candidates, mi_row, mi_col, NULL, NULL,
8732 mbmi_ext->mode_context);
Jingning Han731af492016-11-17 11:53:23 -08008733 if (mbmi_ext->ref_mv_count[ref_frame] < 2) {
8734 MV_REFERENCE_FRAME rf[2];
8735 av1_set_ref_frame(rf, ref_frame);
David Barkercdcac6d2016-12-01 17:04:16 +00008736 if (mbmi_ext->ref_mvs[rf[0]][0].as_int !=
8737 frame_mv[ZEROMV][rf[0]].as_int ||
8738 mbmi_ext->ref_mvs[rf[0]][1].as_int !=
8739 frame_mv[ZEROMV][rf[0]].as_int ||
8740 mbmi_ext->ref_mvs[rf[1]][0].as_int !=
8741 frame_mv[ZEROMV][rf[1]].as_int ||
8742 mbmi_ext->ref_mvs[rf[1]][1].as_int != frame_mv[ZEROMV][rf[1]].as_int)
Jingning Han731af492016-11-17 11:53:23 -08008743 mbmi_ext->mode_context[ref_frame] &= ~(1 << ALL_ZERO_FLAG_OFFSET);
8744 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008745 }
8746#endif // CONFIG_REF_MV
8747
Yue Chencb60b182016-10-13 15:18:22 -07008748#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008749 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1,
8750 dst_width1, dst_height1, dst_stride1);
8751 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2,
8752 dst_width2, dst_height2, dst_stride2);
8753 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yue Chene9638cc2016-10-10 12:37:54 -07008754 x->mask_buf = mask2d_buf;
8755 x->wsrc_buf = weighted_src_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008756 calc_target_weighted_pred(cm, x, xd, mi_row, mi_col, dst_buf1[0],
Yue Chene9638cc2016-10-10 12:37:54 -07008757 dst_stride1[0], dst_buf2[0], dst_stride2[0]);
Yue Chencb60b182016-10-13 15:18:22 -07008758#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008759
8760 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
8761 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
8762// Skip checking missing references in both single and compound reference
8763// modes. Note that a mode will be skipped iff both reference frames
8764// are masked out.
8765#if CONFIG_EXT_REFS
8766 if (ref_frame == BWDREF_FRAME || ref_frame == ALTREF_FRAME) {
8767 ref_frame_skip_mask[0] |= (1 << ref_frame);
8768 ref_frame_skip_mask[1] |= ((1 << ref_frame) | 0x01);
8769 } else {
8770#endif // CONFIG_EXT_REFS
8771 ref_frame_skip_mask[0] |= (1 << ref_frame);
8772 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8773#if CONFIG_EXT_REFS
8774 }
8775#endif // CONFIG_EXT_REFS
8776 } else {
8777 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
8778 // Skip fixed mv modes for poor references
8779 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
8780 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
8781 break;
8782 }
8783 }
8784 }
8785 // If the segment reference frame feature is enabled....
8786 // then do nothing if the current ref frame is not allowed..
8787 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
8788 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
8789 ref_frame_skip_mask[0] |= (1 << ref_frame);
8790 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8791 }
8792 }
8793
8794 // Disable this drop out case if the ref frame
8795 // segment level feature is enabled for this segment. This is to
8796 // prevent the possibility that we end up unable to pick any mode.
8797 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
8798 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
8799 // unless ARNR filtering is enabled in which case we want
8800 // an unfiltered alternative. We allow near/nearest as well
8801 // because they may result in zero-zero MVs but be cheaper.
8802 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Sarah Parkere5299862016-08-16 14:57:37 -07008803 int_mv zeromv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008804 ref_frame_skip_mask[0] = (1 << LAST_FRAME) |
8805#if CONFIG_EXT_REFS
8806 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
8807 (1 << BWDREF_FRAME) |
8808#endif // CONFIG_EXT_REFS
8809 (1 << GOLDEN_FRAME);
8810 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
8811 // TODO(zoeliu): To further explore whether following needs to be done for
8812 // BWDREF_FRAME as well.
8813 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
Sarah Parkere5299862016-08-16 14:57:37 -07008814#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +00008815 zeromv.as_int = gm_get_motion_vector(&cm->global_motion[ALTREF_FRAME],
8816 cm->allow_high_precision_mv)
8817 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07008818#else
8819 zeromv.as_int = 0;
8820#endif // CONFIG_GLOBAL_MOTION
8821 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008822 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008823 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008824 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
8825#if CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07008826 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008827 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008828 if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008829 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008830 if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008831 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008832 if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008833 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV);
8834#endif // CONFIG_EXT_INTER
8835 }
8836 }
8837
8838 if (cpi->rc.is_src_frame_alt_ref) {
8839 if (sf->alt_ref_search_fp) {
8840 assert(cpi->ref_frame_flags & flag_list[ALTREF_FRAME]);
8841 mode_skip_mask[ALTREF_FRAME] = 0;
8842 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
8843 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
8844 }
8845 }
8846
8847 if (sf->alt_ref_search_fp)
8848 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
8849 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
8850 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
8851
8852 if (sf->adaptive_mode_search) {
8853 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
8854 cpi->rc.frames_since_golden >= 3)
8855 if (x->pred_mv_sad[GOLDEN_FRAME] > (x->pred_mv_sad[LAST_FRAME] << 1))
8856 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
8857 }
8858
8859 if (bsize > sf->max_intra_bsize) {
8860 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
8861 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
8862 }
8863
8864 mode_skip_mask[INTRA_FRAME] |=
8865 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
8866
8867 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i) mode_threshold[i] = 0;
8868 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
8869 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
8870
8871 midx = sf->schedule_mode_search ? mode_skip_start : 0;
8872 while (midx > 4) {
8873 uint8_t end_pos = 0;
8874 for (i = 5; i < midx; ++i) {
8875 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
8876 uint8_t tmp = mode_map[i];
8877 mode_map[i] = mode_map[i - 1];
8878 mode_map[i - 1] = tmp;
8879 end_pos = i;
8880 }
8881 }
8882 midx = end_pos;
8883 }
8884
8885 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
8886 x->use_default_intra_tx_type = 1;
8887 else
8888 x->use_default_intra_tx_type = 0;
8889
8890 if (cpi->sf.tx_type_search.fast_inter_tx_type_search)
8891 x->use_default_inter_tx_type = 1;
8892 else
8893 x->use_default_inter_tx_type = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07008894#if CONFIG_PVQ
8895 od_encode_checkpoint(&x->daala_enc, &pre_buf);
8896#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008897#if CONFIG_EXT_INTER
8898 for (i = 0; i < MB_MODE_COUNT; ++i)
8899 for (ref_frame = 0; ref_frame < TOTAL_REFS_PER_FRAME; ++ref_frame)
8900 modelled_rd[i][ref_frame] = INT64_MAX;
8901#endif // CONFIG_EXT_INTER
8902
8903 for (midx = 0; midx < MAX_MODES; ++midx) {
8904 int mode_index;
8905 int mode_excluded = 0;
8906 int64_t this_rd = INT64_MAX;
8907 int disable_skip = 0;
8908 int compmode_cost = 0;
8909#if CONFIG_EXT_INTER
8910 int compmode_interintra_cost = 0;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008911 int compmode_interinter_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008912#endif // CONFIG_EXT_INTER
8913 int rate2 = 0, rate_y = 0, rate_uv = 0;
8914 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
8915 int skippable = 0;
8916 int this_skip2 = 0;
8917 int64_t total_sse = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008918#if CONFIG_REF_MV
8919 uint8_t ref_frame_type;
8920#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07008921#if CONFIG_PVQ
8922 od_encode_rollback(&x->daala_enc, &pre_buf);
8923#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008924 mode_index = mode_map[midx];
Yaowu Xuf883b422016-08-30 14:01:10 -07008925 this_mode = av1_mode_order[mode_index].mode;
8926 ref_frame = av1_mode_order[mode_index].ref_frame[0];
8927 second_ref_frame = av1_mode_order[mode_index].ref_frame[1];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07008928#if CONFIG_REF_MV
8929 mbmi->ref_mv_idx = 0;
8930#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008931
8932#if CONFIG_EXT_INTER
8933 if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
8934 // Mode must by compatible
8935 assert(is_interintra_allowed_mode(this_mode));
8936
David Barkerac37fa32016-12-02 12:30:21 +00008937#if !USE_RECT_INTERINTRA
8938 // Note: If the subsampling is unequal, any block size we pick
8939 // either a rectangular luma block or a rectangular chroma block.
8940 // So in this case, we can't use any interintra modes
8941 if (xd->plane[1].subsampling_x != xd->plane[1].subsampling_y ||
8942 xd->plane[2].subsampling_x != xd->plane[2].subsampling_y)
8943 continue;
8944#endif
8945
Yaowu Xuc27fc142016-08-22 16:08:15 -07008946 if (!is_interintra_allowed_bsize(bsize)) continue;
8947 }
8948
8949 if (is_inter_compound_mode(this_mode)) {
8950 frame_mv[this_mode][ref_frame].as_int =
8951 frame_mv[compound_ref0_mode(this_mode)][ref_frame].as_int;
8952 frame_mv[this_mode][second_ref_frame].as_int =
8953 frame_mv[compound_ref1_mode(this_mode)][second_ref_frame].as_int;
8954 }
8955#endif // CONFIG_EXT_INTER
8956
8957 // Look at the reference frame of the best mode so far and set the
8958 // skip mask to look at a subset of the remaining modes.
8959 if (midx == mode_skip_start && best_mode_index >= 0) {
8960 switch (best_mbmode.ref_frame[0]) {
8961 case INTRA_FRAME: break;
8962 case LAST_FRAME:
8963 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
8964 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8965 break;
8966#if CONFIG_EXT_REFS
8967 case LAST2_FRAME:
8968 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
8969 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8970 break;
8971 case LAST3_FRAME:
8972 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
8973 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8974 break;
8975#endif // CONFIG_EXT_REFS
8976 case GOLDEN_FRAME:
8977 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
8978 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8979 break;
8980#if CONFIG_EXT_REFS
8981 case BWDREF_FRAME:
8982 ref_frame_skip_mask[0] |= BWDREF_FRAME_MODE_MASK;
8983 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8984 break;
8985#endif // CONFIG_EXT_REFS
8986 case ALTREF_FRAME: ref_frame_skip_mask[0] |= ALTREF_FRAME_MODE_MASK;
8987#if CONFIG_EXT_REFS
8988 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8989#endif // CONFIG_EXT_REFS
8990 break;
8991 case NONE:
8992 case TOTAL_REFS_PER_FRAME:
8993 assert(0 && "Invalid Reference frame");
8994 break;
8995 }
8996 }
8997
8998 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -07008999 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -07009000 continue;
9001
9002 if (mode_skip_mask[ref_frame] & (1 << this_mode)) continue;
9003
9004 // Test best rd so far against threshold for trying this mode.
9005 if (best_mode_skippable && sf->schedule_mode_search)
9006 mode_threshold[mode_index] <<= 1;
9007
9008 if (best_rd < mode_threshold[mode_index]) continue;
9009
9010 comp_pred = second_ref_frame > INTRA_FRAME;
9011 if (comp_pred) {
9012 if (!cpi->allow_comp_inter_inter) continue;
9013
9014 // Skip compound inter modes if ARF is not available.
9015 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
9016
9017 // Do not allow compound prediction if the segment level reference frame
9018 // feature is in use as in this case there can only be one reference.
9019 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
9020
9021 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
9022 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
9023 continue;
9024
9025 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
9026 } else {
9027 if (ref_frame != INTRA_FRAME)
9028 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
9029 }
9030
9031 if (ref_frame == INTRA_FRAME) {
9032 if (sf->adaptive_mode_search)
9033 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
9034 continue;
9035
9036 if (this_mode != DC_PRED) {
9037 // Disable intra modes other than DC_PRED for blocks with low variance
9038 // Threshold for intra skipping based on source variance
9039 // TODO(debargha): Specialize the threshold for super block sizes
9040 const unsigned int skip_intra_var_thresh = 64;
9041 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
9042 x->source_variance < skip_intra_var_thresh)
9043 continue;
9044 // Only search the oblique modes if the best so far is
9045 // one of the neighboring directional modes
9046 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
9047 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
9048 if (best_mode_index >= 0 && best_mbmode.ref_frame[0] > INTRA_FRAME)
9049 continue;
9050 }
9051 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
9052 if (conditional_skipintra(this_mode, best_intra_mode)) continue;
9053 }
9054 }
Sarah Parkere5299862016-08-16 14:57:37 -07009055#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +00009056 } else if (cm->global_motion[ref_frame].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -07009057 (!comp_pred ||
David Barkercf3d0b02016-11-10 10:14:49 +00009058 cm->global_motion[second_ref_frame].wmtype == IDENTITY)) {
Sarah Parkere5299862016-08-16 14:57:37 -07009059#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009060 } else {
Sarah Parkere5299862016-08-16 14:57:37 -07009061#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009062 const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame };
9063 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
9064#if CONFIG_REF_MV && CONFIG_EXT_INTER
9065 mbmi_ext->compound_mode_context,
9066#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
9067 frame_mv, this_mode, ref_frames, bsize, -1))
9068 continue;
9069 }
9070
9071 mbmi->mode = this_mode;
9072 mbmi->uv_mode = DC_PRED;
9073 mbmi->ref_frame[0] = ref_frame;
9074 mbmi->ref_frame[1] = second_ref_frame;
Urvang Joshib100db72016-10-12 16:28:56 -07009075#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009076 pmi->palette_size[0] = 0;
9077 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07009078#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009079#if CONFIG_FILTER_INTRA
9080 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
9081 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
9082#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009083 // Evaluate all sub-pel filters irrespective of whether we can use
9084 // them for this frame.
9085#if CONFIG_DUAL_FILTER
9086 for (i = 0; i < 4; ++i) {
9087 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
9088 ? EIGHTTAP_REGULAR
9089 : cm->interp_filter;
9090 }
9091#else
9092 mbmi->interp_filter =
9093 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
9094#endif
9095 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chencb60b182016-10-13 15:18:22 -07009096 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009097
9098 x->skip = 0;
9099 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
9100
9101 // Select prediction reference frames.
9102 for (i = 0; i < MAX_MB_PLANE; i++) {
9103 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
9104 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
9105 }
9106
9107#if CONFIG_EXT_INTER
Debargha Mukherjeecb603792016-10-04 13:10:23 -07009108 mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009109#endif // CONFIG_EXT_INTER
9110
9111 if (ref_frame == INTRA_FRAME) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009112 RD_STATS rd_stats_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009113 TX_SIZE uv_tx;
9114 struct macroblockd_plane *const pd = &xd->plane[1];
9115#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08009116 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009117 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -08009118 int rate_dummy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009119 if (!angle_stats_ready) {
9120 const int src_stride = x->plane[0].src.stride;
9121 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuf883b422016-08-30 14:01:10 -07009122#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009123 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
9124 highbd_angle_estimation(src, src_stride, rows, cols,
9125 directional_mode_skip_mask);
9126 else
9127#endif
9128 angle_estimation(src, src_stride, rows, cols,
9129 directional_mode_skip_mask);
9130 angle_stats_ready = 1;
9131 }
9132 if (directional_mode_skip_mask[mbmi->mode]) continue;
hui su45dc5972016-12-08 17:42:50 -08009133 rd_stats_y.rate = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009134 this_rd =
hui su45dc5972016-12-08 17:42:50 -08009135 rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rd_stats_y, bsize,
9136 intra_mode_cost[mbmi->mode], best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009137 } else {
9138 mbmi->angle_delta[0] = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009139 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009140 }
9141#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009142 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -08009143#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009144 rate_y = rd_stats_y.rate;
9145 distortion_y = rd_stats_y.dist;
9146 skippable = rd_stats_y.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009147
9148 if (rate_y == INT_MAX) continue;
9149
hui su5db97432016-10-14 16:10:14 -07009150#if CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009151 if (mbmi->mode == DC_PRED) dc_skipped = 0;
hui su5db97432016-10-14 16:10:14 -07009152#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009153
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009154 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][pd->subsampling_x]
9155 [pd->subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009156 if (rate_uv_intra[uv_tx] == INT_MAX) {
9157 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -07009158 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
9159 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07009160#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009161 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009162#endif // CONFIG_PALETTE
9163
Yaowu Xuc27fc142016-08-22 16:08:15 -07009164#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009165 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
9166#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009167#if CONFIG_FILTER_INTRA
9168 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9169#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009170 }
9171
9172 rate_uv = rate_uv_tokenonly[uv_tx];
Urvang Joshi368fbc92016-10-17 16:31:34 -07009173 distortion_uv = dist_uvs[uv_tx];
9174 skippable = skippable && skip_uvs[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009175 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07009176#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009177 if (cm->allow_screen_content_tools) {
9178 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9179 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9180 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9181 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9182 }
Urvang Joshib100db72016-10-12 16:28:56 -07009183#endif // CONFIG_PALETTE
9184
Yaowu Xuc27fc142016-08-22 16:08:15 -07009185#if CONFIG_EXT_INTRA
9186 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009187#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009188#if CONFIG_FILTER_INTRA
9189 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9190 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9191 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9192 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9193 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
9194 }
9195#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009196
9197 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
9198 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07009199#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009200 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07009201 rate2 += av1_cost_bit(
9202 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07009203#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009204
Jingning Hanbf9c6b72016-12-14 14:50:45 -08009205 if (!xd->lossless[mbmi->segment_id] && bsize >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009206 // super_block_yrd above includes the cost of the tx_size in the
9207 // tokenonly rate, but for intra blocks, tx_size is always coded
9208 // (prediction granularity), so we account for it in the full rate,
9209 // not the tokenonly rate.
Jingning Hanb0a71302016-10-25 16:28:49 -07009210 rate_y -=
9211 cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
9212 [tx_size_to_depth(mbmi->tx_size)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009213 }
9214#if CONFIG_EXT_INTRA
9215 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -08009216 const int max_angle_delta = av1_get_max_angle_delta(bsize, 0);
hui sueda3d762016-12-06 16:58:23 -08009217#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07009218 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07009219 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui su45dc5972016-12-08 17:42:50 -08009220 p_angle = mode_to_angle_map[mbmi->mode] +
9221 mbmi->angle_delta[0] * av1_get_angle_step(bsize, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07009222 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07009223 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -08009224#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08009225 rate2 += write_uniform_cost(2 * max_angle_delta + 1,
9226 max_angle_delta + mbmi->angle_delta[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009227 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009228 if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
hui su45dc5972016-12-08 17:42:50 -08009229 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA_UV + 1,
9230 MAX_ANGLE_DELTA_UV + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009231 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009232#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009233#if CONFIG_FILTER_INTRA
9234 if (mbmi->mode == DC_PRED) {
9235 rate2 +=
9236 av1_cost_bit(cm->fc->filter_intra_probs[0],
9237 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
9238 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
9239 rate2 += write_uniform_cost(
9240 FILTER_INTRA_MODES,
9241 mbmi->filter_intra_mode_info.filter_intra_mode[0]);
9242 }
9243 }
9244 if (mbmi->uv_mode == DC_PRED) {
9245 rate2 +=
9246 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
9247 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
9248 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
9249 rate2 += write_uniform_cost(
9250 FILTER_INTRA_MODES,
9251 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
9252 }
9253#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009254 if (this_mode != DC_PRED && this_mode != TM_PRED)
9255 rate2 += intra_cost_penalty;
9256 distortion2 = distortion_y + distortion_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07009257#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009258 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009259 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009260 cpi, &xd->plane[0].dst, bsize, xd->bd);
9261 } else {
9262 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07009263 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009264 }
9265#else
9266 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07009267 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
9268#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009269 } else {
9270#if CONFIG_REF_MV
9271 int_mv backup_ref_mv[2];
9272
9273 backup_ref_mv[0] = mbmi_ext->ref_mvs[ref_frame][0];
9274 if (comp_pred) backup_ref_mv[1] = mbmi_ext->ref_mvs[second_ref_frame][0];
9275#endif
9276#if CONFIG_EXT_INTER
9277 if (second_ref_frame == INTRA_FRAME) {
9278 if (best_single_inter_ref != ref_frame) continue;
Debargha Mukherjeecb603792016-10-04 13:10:23 -07009279 mbmi->interintra_mode = intra_to_interintra_mode[best_intra_mode];
hui su5db97432016-10-14 16:10:14 -07009280// TODO(debargha|geza.lore):
9281// Should we use ext_intra modes for interintra?
Yaowu Xuc27fc142016-08-22 16:08:15 -07009282#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009283 mbmi->angle_delta[0] = 0;
9284 mbmi->angle_delta[1] = 0;
hui sueda3d762016-12-06 16:58:23 -08009285#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07009286 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08009287#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07009288#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009289#if CONFIG_FILTER_INTRA
9290 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
9291 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
9292#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009293 }
9294#endif // CONFIG_EXT_INTER
9295#if CONFIG_REF_MV
9296 mbmi->ref_mv_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009297 ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009298
9299 if (this_mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
9300 int ref;
9301 for (ref = 0; ref < 1 + comp_pred; ++ref) {
9302 int_mv this_mv =
9303 (ref == 0) ? mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv
9304 : mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
Jingning Hanff6ee6a2016-12-07 09:55:21 -08009305 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
9306 xd->n8_h << MI_SIZE_LOG2, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009307 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
9308 }
9309 }
9310#endif
Angie Chiang76159122016-11-09 12:13:22 -08009311 {
9312 RD_STATS rd_stats, rd_stats_y, rd_stats_uv;
9313 av1_init_rd_stats(&rd_stats);
9314 rd_stats.rate = rate2;
9315 this_rd = handle_inter_mode(
9316 cpi, x, bsize, &rd_stats, &rd_stats_y, &rd_stats_uv, &disable_skip,
9317 frame_mv, mi_row, mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07009318#if CONFIG_MOTION_VAR
Angie Chiang76159122016-11-09 12:13:22 -08009319 dst_buf1, dst_stride1, dst_buf2, dst_stride2,
Yue Chencb60b182016-10-13 15:18:22 -07009320#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009321#if CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08009322 single_newmvs, single_newmvs_rate, &compmode_interintra_cost,
Sarah Parker6fdc8532016-11-16 17:47:13 -08009323 &compmode_interinter_cost, modelled_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009324#else
Angie Chiang76159122016-11-09 12:13:22 -08009325 single_newmv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009326#endif // CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08009327 single_inter_filter, single_skippable, best_rd);
9328
9329 rate2 = rd_stats.rate;
9330 skippable = rd_stats.skip;
9331 distortion2 = rd_stats.dist;
9332 total_sse = rd_stats.sse;
9333 rate_y = rd_stats_y.rate;
9334 rate_uv = rd_stats_uv.rate;
9335 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009336
9337#if CONFIG_REF_MV
Yue Chen6e601e92016-12-05 18:19:00 -08009338// TODO(jingning): This needs some refactoring to improve code quality
9339// and reduce redundant steps.
9340#if CONFIG_EXT_INTER
9341 if (((mbmi->mode == NEARMV || mbmi->mode == NEAR_NEARMV) &&
9342 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
9343 ((mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) &&
9344 mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
9345#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009346 if ((mbmi->mode == NEARMV &&
9347 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
9348 (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
Yue Chen6e601e92016-12-05 18:19:00 -08009349#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009350 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
9351 MB_MODE_INFO backup_mbmi = *mbmi;
9352 int backup_skip = x->skip;
9353 int64_t tmp_ref_rd = this_rd;
9354 int ref_idx;
9355
Yue Chen6e601e92016-12-05 18:19:00 -08009356// TODO(jingning): This should be deprecated shortly.
9357#if CONFIG_EXT_INTER
9358 int idx_offset =
9359 (mbmi->mode == NEARMV || mbmi->mode == NEAR_NEARMV) ? 1 : 0;
9360#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009361 int idx_offset = (mbmi->mode == NEARMV) ? 1 : 0;
Yue Chen6e601e92016-12-05 18:19:00 -08009362#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009363 int ref_set =
Yaowu Xuf883b422016-08-30 14:01:10 -07009364 AOMMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 1 - idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009365
9366 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07009367 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009368 // Dummy
9369 int_mv backup_fmv[2];
9370 backup_fmv[0] = frame_mv[NEWMV][ref_frame];
9371 if (comp_pred) backup_fmv[1] = frame_mv[NEWMV][second_ref_frame];
9372
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07009373 rate2 += (rate2 < INT_MAX ? cpi->drl_mode_cost0[drl_ctx][0] : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009374
9375 if (this_rd < INT64_MAX) {
9376 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
9377 RDCOST(x->rdmult, x->rddiv, 0, total_sse))
9378 tmp_ref_rd =
9379 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -07009380 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Yaowu Xuc27fc142016-08-22 16:08:15 -07009381 distortion2);
9382 else
9383 tmp_ref_rd =
9384 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -07009385 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
Yaowu Xuc27fc142016-08-22 16:08:15 -07009386 rate_y - rate_uv,
9387 total_sse);
9388 }
9389#if CONFIG_VAR_TX
9390 for (i = 0; i < MAX_MB_PLANE; ++i)
9391 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
9392 sizeof(uint8_t) * ctx->num_4x4_blk);
9393#endif
9394
9395 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
9396 int64_t tmp_alt_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009397 int dummy_disable_skip = 0;
9398 int ref;
9399 int_mv cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -08009400 RD_STATS tmp_rd_stats, tmp_rd_stats_y, tmp_rd_stats_uv;
Yue Chen6e601e92016-12-05 18:19:00 -08009401#if CONFIG_EXT_INTER
9402 int tmp_compmode_interintra_cost = 0;
9403 int tmp_compmode_interinter_cost = 0;
9404#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009405
Yaowu Xu5bfbfdf2016-11-22 16:43:34 -08009406 av1_invalid_rd_stats(&tmp_rd_stats);
9407
Yaowu Xuc27fc142016-08-22 16:08:15 -07009408 mbmi->ref_mv_idx = 1 + ref_idx;
9409
9410 for (ref = 0; ref < 1 + comp_pred; ++ref) {
9411 int_mv this_mv =
9412 (ref == 0)
9413 ? mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
9414 .this_mv
9415 : mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
9416 .comp_mv;
Jingning Hanff6ee6a2016-12-07 09:55:21 -08009417 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
9418 xd->n8_h << MI_SIZE_LOG2, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009419 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
9420 }
9421
9422 cur_mv =
9423 mbmi_ext->ref_mv_stack[ref_frame][mbmi->ref_mv_idx + idx_offset]
9424 .this_mv;
9425 clamp_mv2(&cur_mv.as_mv, xd);
9426
9427 if (!mv_check_bounds(x, &cur_mv.as_mv)) {
clang-format67948d32016-09-07 22:40:40 -07009428 int dummy_single_skippable[MB_MODE_COUNT]
9429 [TOTAL_REFS_PER_FRAME] = { { 0 } };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009430#if CONFIG_EXT_INTER
9431 int_mv dummy_single_newmvs[2][TOTAL_REFS_PER_FRAME] = { { { 0 } },
9432 { { 0 } } };
9433 int dummy_single_newmvs_rate[2][TOTAL_REFS_PER_FRAME] = { { 0 },
9434 { 0 } };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009435#else
9436 int_mv dummy_single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
9437#endif
9438
9439 frame_mv[NEARMV][ref_frame] = cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -08009440 av1_init_rd_stats(&tmp_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009441 tmp_alt_rd = handle_inter_mode(
Angie Chiang76159122016-11-09 12:13:22 -08009442 cpi, x, bsize, &tmp_rd_stats, &tmp_rd_stats_y, &tmp_rd_stats_uv,
9443 &dummy_disable_skip, frame_mv, mi_row, mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07009444#if CONFIG_MOTION_VAR
Yue Chene9638cc2016-10-10 12:37:54 -07009445 dst_buf1, dst_stride1, dst_buf2, dst_stride2,
Yue Chencb60b182016-10-13 15:18:22 -07009446#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009447#if CONFIG_EXT_INTER
9448 dummy_single_newmvs, dummy_single_newmvs_rate,
Yue Chen6e601e92016-12-05 18:19:00 -08009449 &tmp_compmode_interintra_cost, &tmp_compmode_interinter_cost,
9450 NULL,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009451#else
9452 dummy_single_newmv,
9453#endif
Angie Chiang76159122016-11-09 12:13:22 -08009454 single_inter_filter, dummy_single_skippable, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009455 }
9456
9457 for (i = 0; i < mbmi->ref_mv_idx; ++i) {
9458 uint8_t drl1_ctx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009459 drl1_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
9460 i + idx_offset);
Angie Chiang76159122016-11-09 12:13:22 -08009461 tmp_rd_stats.rate +=
9462 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][1]
9463 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009464 }
9465
9466 if (mbmi_ext->ref_mv_count[ref_frame_type] >
9467 mbmi->ref_mv_idx + idx_offset + 1 &&
9468 ref_idx < ref_set - 1) {
9469 uint8_t drl1_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07009470 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
9471 mbmi->ref_mv_idx + idx_offset);
Yaowu Xu83ed6fe2016-11-22 11:15:29 -08009472 tmp_rd_stats.rate +=
9473 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][0]
9474 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009475 }
9476
9477 if (tmp_alt_rd < INT64_MAX) {
Yue Chen69f18e12016-09-08 14:48:15 -07009478#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08009479 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv, tmp_rd_stats.rate,
9480 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009481#else
Angie Chiang76159122016-11-09 12:13:22 -08009482 if (RDCOST(x->rdmult, x->rddiv,
9483 tmp_rd_stats_y.rate + tmp_rd_stats_uv.rate,
9484 tmp_rd_stats.dist) <
9485 RDCOST(x->rdmult, x->rddiv, 0, tmp_rd_stats.sse))
Yaowu Xuf883b422016-08-30 14:01:10 -07009486 tmp_alt_rd =
9487 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08009488 tmp_rd_stats.rate +
9489 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
9490 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009491 else
Yaowu Xuf883b422016-08-30 14:01:10 -07009492 tmp_alt_rd =
9493 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08009494 tmp_rd_stats.rate +
9495 av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
9496 tmp_rd_stats_y.rate - tmp_rd_stats_uv.rate,
9497 tmp_rd_stats.sse);
Yue Chen69f18e12016-09-08 14:48:15 -07009498#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009499 }
9500
9501 if (tmp_ref_rd > tmp_alt_rd) {
Angie Chiang76159122016-11-09 12:13:22 -08009502 rate2 = tmp_rd_stats.rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009503 disable_skip = dummy_disable_skip;
Angie Chiang76159122016-11-09 12:13:22 -08009504 distortion2 = tmp_rd_stats.dist;
9505 skippable = tmp_rd_stats.skip;
9506 rate_y = tmp_rd_stats_y.rate;
9507 rate_uv = tmp_rd_stats_uv.rate;
9508 total_sse = tmp_rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009509 this_rd = tmp_alt_rd;
9510 tmp_ref_rd = tmp_alt_rd;
9511 backup_mbmi = *mbmi;
9512 backup_skip = x->skip;
9513#if CONFIG_VAR_TX
9514 for (i = 0; i < MAX_MB_PLANE; ++i)
9515 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
9516 sizeof(uint8_t) * ctx->num_4x4_blk);
9517#endif
Yue Chen6e601e92016-12-05 18:19:00 -08009518#if CONFIG_EXT_INTER
9519 compmode_interintra_cost = tmp_compmode_interintra_cost;
9520 compmode_interinter_cost = tmp_compmode_interinter_cost;
9521#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009522 } else {
9523 *mbmi = backup_mbmi;
9524 x->skip = backup_skip;
9525 }
9526 }
9527
9528 frame_mv[NEARMV][ref_frame] = backup_mv;
9529 frame_mv[NEWMV][ref_frame] = backup_fmv[0];
9530 if (comp_pred) frame_mv[NEWMV][second_ref_frame] = backup_fmv[1];
9531#if CONFIG_VAR_TX
9532 for (i = 0; i < MAX_MB_PLANE; ++i)
9533 memcpy(x->blk_skip[i], x->blk_skip_drl[i],
9534 sizeof(uint8_t) * ctx->num_4x4_blk);
9535#endif
9536 }
9537 mbmi_ext->ref_mvs[ref_frame][0] = backup_ref_mv[0];
9538 if (comp_pred) mbmi_ext->ref_mvs[second_ref_frame][0] = backup_ref_mv[1];
9539#endif // CONFIG_REF_MV
9540
9541 if (this_rd == INT64_MAX) continue;
9542
Yaowu Xuf883b422016-08-30 14:01:10 -07009543 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009544
9545 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
9546 }
9547
9548#if CONFIG_EXT_INTER
9549 rate2 += compmode_interintra_cost;
9550 if (cm->reference_mode != SINGLE_REFERENCE && comp_pred)
Yue Chencb60b182016-10-13 15:18:22 -07009551#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
9552 if (mbmi->motion_mode == SIMPLE_TRANSLATION)
9553#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parker6fdc8532016-11-16 17:47:13 -08009554 rate2 += compmode_interinter_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009555#endif // CONFIG_EXT_INTER
9556
9557 // Estimate the reference frame signaling cost and add it
9558 // to the rolling cost variable.
9559 if (comp_pred) {
9560 rate2 += ref_costs_comp[ref_frame];
9561#if CONFIG_EXT_REFS
9562 rate2 += ref_costs_comp[second_ref_frame];
9563#endif // CONFIG_EXT_REFS
9564 } else {
9565 rate2 += ref_costs_single[ref_frame];
9566 }
9567
Yue Chen69f18e12016-09-08 14:48:15 -07009568#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009569 if (ref_frame == INTRA_FRAME) {
9570#else
9571 if (!disable_skip) {
Yue Chen69f18e12016-09-08 14:48:15 -07009572#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009573 if (skippable) {
9574 // Back out the coefficient coding costs
9575 rate2 -= (rate_y + rate_uv);
9576 rate_y = 0;
9577 rate_uv = 0;
9578 // Cost the skip mb case
Yaowu Xuf883b422016-08-30 14:01:10 -07009579 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009580 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009581#if CONFIG_REF_MV
9582 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv + rate_skip0,
9583 distortion2) <
9584 RDCOST(x->rdmult, x->rddiv, rate_skip1, total_sse)) {
9585#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009586 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
9587 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009588#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009589 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -07009590 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009591 } else {
9592 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -07009593 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009594 distortion2 = total_sse;
9595 assert(total_sse >= 0);
9596 rate2 -= (rate_y + rate_uv);
9597 this_skip2 = 1;
9598 rate_y = 0;
9599 rate_uv = 0;
9600 }
9601 } else {
9602 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -07009603 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009604 }
9605
9606 // Calculate the final RD estimate for this mode.
9607 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yue Chen69f18e12016-09-08 14:48:15 -07009608#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009609 } else {
9610 this_skip2 = mbmi->skip;
9611 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
9612 if (this_skip2) {
9613 rate_y = 0;
9614 rate_uv = 0;
9615 }
Yue Chen69f18e12016-09-08 14:48:15 -07009616#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009617 }
9618
Yaowu Xuc27fc142016-08-22 16:08:15 -07009619 if (ref_frame == INTRA_FRAME) {
9620 // Keep record of best intra rd
9621 if (this_rd < best_intra_rd) {
9622 best_intra_rd = this_rd;
9623 best_intra_mode = mbmi->mode;
9624 }
9625#if CONFIG_EXT_INTER
9626 } else if (second_ref_frame == NONE) {
9627 if (this_rd < best_single_inter_rd) {
9628 best_single_inter_rd = this_rd;
9629 best_single_inter_ref = mbmi->ref_frame[0];
9630 }
9631#endif // CONFIG_EXT_INTER
9632 }
9633
9634 if (!disable_skip && ref_frame == INTRA_FRAME) {
9635 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009636 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009637 }
9638
9639 // Did this mode help.. i.e. is it the new best mode
9640 if (this_rd < best_rd || x->skip) {
9641 if (!mode_excluded) {
9642 // Note index of best mode so far
9643 best_mode_index = mode_index;
9644
9645 if (ref_frame == INTRA_FRAME) {
9646 /* required for left and above block mv */
9647 mbmi->mv[0].as_int = 0;
9648 } else {
9649 best_pred_sse = x->pred_sse[ref_frame];
9650 }
9651
9652 rd_cost->rate = rate2;
9653#if CONFIG_SUPERTX
9654 if (x->skip)
9655 *returnrate_nocoef = rate2;
9656 else
9657 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07009658 *returnrate_nocoef -= av1_cost_bit(
9659 av1_get_skip_prob(cm, xd), disable_skip || skippable || this_skip2);
9660 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
9661 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chencb60b182016-10-13 15:18:22 -07009662#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yue Chen69f18e12016-09-08 14:48:15 -07009663#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
9664 if (motion_mode_allowed(mbmi) == WARPED_CAUSAL)
9665#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07009666 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Yue Chen69f18e12016-09-08 14:48:15 -07009667#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
9668 else if (motion_mode_allowed(mbmi) == OBMC_CAUSAL)
9669 *returnrate_nocoef -=
9670 cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
9671#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07009672#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009673#endif // CONFIG_SUPERTX
9674 rd_cost->dist = distortion2;
9675 rd_cost->rdcost = this_rd;
9676 best_rd = this_rd;
9677 best_mbmode = *mbmi;
9678 best_skip2 = this_skip2;
9679 best_mode_skippable = skippable;
Yaowu Xuf883b422016-08-30 14:01:10 -07009680 best_rate_y = rate_y + av1_cost_bit(av1_get_skip_prob(cm, xd),
9681 this_skip2 || skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009682 best_rate_uv = rate_uv;
9683
9684#if CONFIG_VAR_TX
9685 for (i = 0; i < MAX_MB_PLANE; ++i)
9686 memcpy(ctx->blk_skip[i], x->blk_skip[i],
9687 sizeof(uint8_t) * ctx->num_4x4_blk);
9688#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009689 }
9690 }
9691
9692 /* keep record of best compound/single-only prediction */
9693 if (!disable_skip && ref_frame != INTRA_FRAME) {
9694 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
9695
9696 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
9697 single_rate = rate2 - compmode_cost;
9698 hybrid_rate = rate2;
9699 } else {
9700 single_rate = rate2;
9701 hybrid_rate = rate2 + compmode_cost;
9702 }
9703
9704 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
9705 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
9706
9707 if (!comp_pred) {
9708 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
9709 best_pred_rd[SINGLE_REFERENCE] = single_rd;
9710 } else {
9711 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
9712 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
9713 }
9714 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
9715 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
9716 }
9717
Yaowu Xuc27fc142016-08-22 16:08:15 -07009718 if (x->skip && !comp_pred) break;
9719 }
9720
9721 if (xd->lossless[mbmi->segment_id] == 0 && best_mode_index >= 0 &&
9722 ((sf->tx_type_search.fast_inter_tx_type_search == 1 &&
9723 is_inter_mode(best_mbmode.mode)) ||
9724 (sf->tx_type_search.fast_intra_tx_type_search == 1 &&
9725 !is_inter_mode(best_mbmode.mode)))) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009726 int skip_blk = 0;
9727 RD_STATS rd_stats_y, rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009728
9729 x->use_default_inter_tx_type = 0;
9730 x->use_default_intra_tx_type = 0;
9731
9732 *mbmi = best_mbmode;
9733
9734 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
9735
9736 // Select prediction reference frames.
9737 for (i = 0; i < MAX_MB_PLANE; i++) {
9738 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
9739 if (has_second_ref(mbmi))
9740 xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
9741 }
9742
9743 if (is_inter_mode(mbmi->mode)) {
Yue Chen69f18e12016-09-08 14:48:15 -07009744#if CONFIG_WARPED_MOTION
9745 if (mbmi->motion_mode == WARPED_CAUSAL) {
9746 int plane;
9747#if CONFIG_AOM_HIGHBITDEPTH
9748 int use_hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
9749#endif // CONFIG_AOM_HIGHBITDEPTH
9750 assert(!has_second_ref(mbmi));
9751
9752 for (plane = 0; plane < 3; ++plane) {
9753 const struct macroblockd_plane *pd = &xd->plane[plane];
9754
9755 av1_warp_plane(&mbmi->wm_params[0],
9756#if CONFIG_AOM_HIGHBITDEPTH
9757 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
9758#endif // CONFIG_AOM_HIGHBITDEPTH
9759 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
9760 pd->pre[0].stride, pd->dst.buf,
9761 ((mi_col * MI_SIZE) >> pd->subsampling_x),
9762 ((mi_row * MI_SIZE) >> pd->subsampling_y),
Jingning Hanff6ee6a2016-12-07 09:55:21 -08009763 xd->n8_w * (MI_SIZE >> pd->subsampling_x),
9764 xd->n8_h * (MI_SIZE >> pd->subsampling_y),
9765 pd->dst.stride, pd->subsampling_x, pd->subsampling_y,
9766 16, 16, 0);
Yue Chen69f18e12016-09-08 14:48:15 -07009767 }
9768 } else {
9769#endif // CONFIG_WARPED_MOTION
David Barkerac37fa32016-12-02 12:30:21 +00009770 av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, bsize);
Yue Chen69f18e12016-09-08 14:48:15 -07009771#if CONFIG_WARPED_MOTION
9772 }
9773#endif // CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07009774#if CONFIG_MOTION_VAR
9775 if (mbmi->motion_mode == OBMC_CAUSAL)
Yaowu Xuf883b422016-08-30 14:01:10 -07009776 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1,
9777 dst_stride1, dst_buf2, dst_stride2);
Yue Chencb60b182016-10-13 15:18:22 -07009778#endif // CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009779 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009780#if CONFIG_VAR_TX
9781 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
Angie Chiangb5dda482016-11-02 16:19:58 -07009782 select_tx_type_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009783 } else {
9784 int idx, idy;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009785 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009786 for (idy = 0; idy < xd->n8_h; ++idy)
9787 for (idx = 0; idx < xd->n8_w; ++idx)
9788 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009789 memset(x->blk_skip[0], rd_stats_y.skip,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009790 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
9791 }
9792
Angie Chiangb5dda482016-11-02 16:19:58 -07009793 inter_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009794#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009795 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -08009796 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009797#endif // CONFIG_VAR_TX
9798 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009799 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -08009800 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009801 }
9802
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009803 if (RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
9804 (rd_stats_y.dist + rd_stats_uv.dist)) >
9805 RDCOST(x->rdmult, x->rddiv, 0, (rd_stats_y.sse + rd_stats_uv.sse))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009806 skip_blk = 1;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009807 rd_stats_y.rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
9808 rd_stats_uv.rate = 0;
9809 rd_stats_y.dist = rd_stats_y.sse;
9810 rd_stats_uv.dist = rd_stats_uv.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009811 } else {
9812 skip_blk = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009813 rd_stats_y.rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009814 }
9815
9816 if (RDCOST(x->rdmult, x->rddiv, best_rate_y + best_rate_uv, rd_cost->dist) >
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009817 RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
9818 (rd_stats_y.dist + rd_stats_uv.dist))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009819#if CONFIG_VAR_TX
9820 int idx, idy;
9821#endif
9822 best_mbmode.tx_type = mbmi->tx_type;
9823 best_mbmode.tx_size = mbmi->tx_size;
9824#if CONFIG_VAR_TX
9825 for (idy = 0; idy < xd->n8_h; ++idy)
9826 for (idx = 0; idx < xd->n8_w; ++idx)
9827 best_mbmode.inter_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
9828
9829 for (i = 0; i < MAX_MB_PLANE; ++i)
9830 memcpy(ctx->blk_skip[i], x->blk_skip[i],
9831 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -07009832
9833 best_mbmode.min_tx_size = mbmi->min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009834#endif
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009835 rd_cost->rate +=
9836 (rd_stats_y.rate + rd_stats_uv.rate - best_rate_y - best_rate_uv);
9837 rd_cost->dist = rd_stats_y.dist + rd_stats_uv.dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009838 rd_cost->rdcost =
9839 RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
9840 best_skip2 = skip_blk;
9841 }
9842 }
9843
Urvang Joshib100db72016-10-12 16:28:56 -07009844#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009845 // Only try palette mode when the best mode so far is an intra mode.
9846 if (cm->allow_screen_content_tools && !is_inter_mode(best_mbmode.mode)) {
9847 PREDICTION_MODE mode_selected;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009848 int rate2 = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009849#if CONFIG_SUPERTX
9850 int best_rate_nocoef;
9851#endif
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009852 int64_t distortion2 = 0, dummy_rd = best_rd, this_rd;
Urvang Joshi626591d2016-10-24 14:13:55 -07009853 int skippable = 0, rate_overhead_palette = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009854 RD_STATS rd_stats_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009855 TX_SIZE best_tx_size, uv_tx;
9856 TX_TYPE best_tx_type;
9857 PALETTE_MODE_INFO palette_mode_info;
9858 uint8_t *const best_palette_color_map =
9859 x->palette_buffer->best_palette_color_map;
9860 uint8_t *const color_map = xd->plane[0].color_index_map;
9861
9862 mbmi->mode = DC_PRED;
9863 mbmi->uv_mode = DC_PRED;
9864 mbmi->ref_frame[0] = INTRA_FRAME;
9865 mbmi->ref_frame[1] = NONE;
9866 palette_mode_info.palette_size[0] = 0;
Urvang Joshi626591d2016-10-24 14:13:55 -07009867 rate_overhead_palette = rd_pick_palette_intra_sby(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009868 cpi, x, bsize, palette_ctx, intra_mode_cost[DC_PRED],
9869 &palette_mode_info, best_palette_color_map, &best_tx_size,
9870 &best_tx_type, &mode_selected, &dummy_rd);
9871 if (palette_mode_info.palette_size[0] == 0) goto PALETTE_EXIT;
9872
9873 pmi->palette_size[0] = palette_mode_info.palette_size[0];
9874 if (palette_mode_info.palette_size[0] > 0) {
9875 memcpy(pmi->palette_colors, palette_mode_info.palette_colors,
9876 PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
9877 memcpy(color_map, best_palette_color_map,
9878 rows * cols * sizeof(best_palette_color_map[0]));
9879 }
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009880 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
9881 if (rd_stats_y.rate == INT_MAX) goto PALETTE_EXIT;
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009882 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
9883 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009884 if (rate_uv_intra[uv_tx] == INT_MAX) {
9885 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -07009886 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
9887 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009888 pmi_uv[uv_tx] = *pmi;
9889#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009890 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
9891#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009892#if CONFIG_FILTER_INTRA
9893 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9894#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009895 }
9896 mbmi->uv_mode = mode_uv[uv_tx];
9897 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9898 if (pmi->palette_size[1] > 0)
9899 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9900 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9901 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9902#if CONFIG_EXT_INTRA
9903 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009904#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009905#if CONFIG_FILTER_INTRA
9906 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9907 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9908 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9909 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9910 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
9911 }
9912#endif // CONFIG_FILTER_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009913 skippable = rd_stats_y.skip && skip_uvs[uv_tx];
9914 distortion2 = rd_stats_y.dist + dist_uvs[uv_tx];
9915 rate2 = rd_stats_y.rate + rate_overhead_palette + rate_uv_intra[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009916 rate2 += ref_costs_single[INTRA_FRAME];
9917
9918 if (skippable) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009919 rate2 -= (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009920#if CONFIG_SUPERTX
9921 best_rate_nocoef = rate2;
9922#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07009923 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009924 } else {
9925#if CONFIG_SUPERTX
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009926 best_rate_nocoef = rate2 - (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009927#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07009928 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009929 }
9930 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
9931 if (this_rd < best_rd) {
9932 best_mode_index = 3;
9933 mbmi->mv[0].as_int = 0;
9934 rd_cost->rate = rate2;
9935#if CONFIG_SUPERTX
9936 *returnrate_nocoef = best_rate_nocoef;
9937#endif
9938 rd_cost->dist = distortion2;
9939 rd_cost->rdcost = this_rd;
9940 best_rd = this_rd;
9941 best_mbmode = *mbmi;
9942 best_skip2 = 0;
9943 best_mode_skippable = skippable;
9944 }
9945 }
9946PALETTE_EXIT:
Urvang Joshib100db72016-10-12 16:28:56 -07009947#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009948
hui su5db97432016-10-14 16:10:14 -07009949#if CONFIG_FILTER_INTRA
9950 // TODO(huisu): filter-intra is turned off in lossless mode for now to
Yaowu Xuc27fc142016-08-22 16:08:15 -07009951 // avoid a unit test failure
hui su5db97432016-10-14 16:10:14 -07009952 if (!xd->lossless[mbmi->segment_id] &&
Urvang Joshib100db72016-10-12 16:28:56 -07009953#if CONFIG_PALETTE
9954 mbmi->palette_mode_info.palette_size[0] == 0 &&
9955#endif // CONFIG_PALETTE
9956 !dc_skipped && best_mode_index >= 0 &&
9957 best_intra_rd < (best_rd + (best_rd >> 3))) {
hui su5db97432016-10-14 16:10:14 -07009958 pick_filter_intra_interframe(
Urvang Joshi368fbc92016-10-17 16:31:34 -07009959 cpi, x, ctx, bsize, rate_uv_intra, rate_uv_tokenonly, dist_uvs,
hui su5db97432016-10-14 16:10:14 -07009960 skip_uvs, mode_uv, filter_intra_mode_info_uv,
9961#if CONFIG_EXT_INTRA
9962 uv_angle_delta,
9963#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07009964#if CONFIG_PALETTE
9965 pmi_uv, palette_ctx,
9966#endif // CONFIG_PALETTE
9967 0, ref_costs_single, &best_rd, &best_intra_rd, &best_intra_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009968 &best_mode_index, &best_skip2, &best_mode_skippable,
9969#if CONFIG_SUPERTX
9970 returnrate_nocoef,
9971#endif // CONFIG_SUPERTX
9972 best_pred_rd, &best_mbmode, rd_cost);
9973 }
hui su5db97432016-10-14 16:10:14 -07009974#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009975
9976 // The inter modes' rate costs are not calculated precisely in some cases.
9977 // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
9978 // ZEROMV. Here, checks are added for those cases, and the mode decisions
9979 // are corrected.
9980 if (best_mbmode.mode == NEWMV
9981#if CONFIG_EXT_INTER
9982 || best_mbmode.mode == NEWFROMNEARMV || best_mbmode.mode == NEW_NEWMV
9983#endif // CONFIG_EXT_INTER
9984 ) {
9985 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
9986 best_mbmode.ref_frame[1] };
9987 int comp_pred_mode = refs[1] > INTRA_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -07009988 int_mv zeromv[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009989#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07009990 const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame);
Sarah Parkere5299862016-08-16 14:57:37 -07009991#endif // CONFIG_REF_MV
9992#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +00009993 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
9994 cm->allow_high_precision_mv)
9995 .as_int;
9996 zeromv[1].as_int = comp_pred_mode
9997 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
9998 cm->allow_high_precision_mv)
9999 .as_int
10000 : 0;
Sarah Parkere5299862016-08-16 14:57:37 -070010001#else
10002 zeromv[0].as_int = 0;
10003 zeromv[1].as_int = 0;
10004#endif // CONFIG_GLOBAL_MOTION
10005#if CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -070010006 if (!comp_pred_mode) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010007 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070010008 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010009 : INT_MAX;
10010
10011 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
10012 int_mv cur_mv = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
10013 if (cur_mv.as_int == best_mbmode.mv[0].as_int) {
10014 best_mbmode.mode = NEARMV;
10015 best_mbmode.ref_mv_idx = i;
10016 }
10017 }
10018
10019 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
10020 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -070010021 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010022 best_mbmode.mode = ZEROMV;
10023 } else {
10024 int_mv nearestmv[2];
10025 int_mv nearmv[2];
10026
10027#if CONFIG_EXT_INTER
10028 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
10029 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][1].this_mv;
10030 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][1].comp_mv;
10031 } else {
10032 nearmv[0] = frame_mv[NEARMV][refs[0]];
10033 nearmv[1] = frame_mv[NEARMV][refs[1]];
10034 }
10035#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010036 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070010037 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010038 : INT_MAX;
10039
10040 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
10041 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
10042 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
10043
10044 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
10045 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
10046 best_mbmode.mode = NEARMV;
10047 best_mbmode.ref_mv_idx = i;
10048 }
10049 }
10050#endif
10051 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
10052 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
10053 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
10054 } else {
10055 nearestmv[0] = frame_mv[NEARESTMV][refs[0]];
10056 nearestmv[1] = frame_mv[NEARESTMV][refs[1]];
10057 }
10058
10059 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
10060 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
10061#if CONFIG_EXT_INTER
10062 best_mbmode.mode = NEAREST_NEARESTMV;
10063 else if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
10064 nearmv[1].as_int == best_mbmode.mv[1].as_int)
10065 best_mbmode.mode = NEAREST_NEARMV;
10066 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
10067 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
10068 best_mbmode.mode = NEAR_NEARESTMV;
10069 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
10070 nearmv[1].as_int == best_mbmode.mv[1].as_int)
10071 best_mbmode.mode = NEAR_NEARMV;
10072 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
10073 best_mbmode.mode = ZERO_ZEROMV;
10074#else
10075 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -070010076 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
10077 best_mbmode.mv[1].as_int == zeromv[1].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010078 best_mbmode.mode = ZEROMV;
10079#endif // CONFIG_EXT_INTER
10080 }
10081#else
10082#if CONFIG_EXT_INTER
10083 if (!comp_pred_mode) {
10084#endif // CONFIG_EXT_INTER
10085 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
10086 ((comp_pred_mode &&
10087 frame_mv[NEARESTMV][refs[1]].as_int == best_mbmode.mv[1].as_int) ||
10088 !comp_pred_mode))
10089 best_mbmode.mode = NEARESTMV;
10090 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
10091 ((comp_pred_mode &&
10092 frame_mv[NEARMV][refs[1]].as_int ==
10093 best_mbmode.mv[1].as_int) ||
10094 !comp_pred_mode))
10095 best_mbmode.mode = NEARMV;
Sarah Parkere5299862016-08-16 14:57:37 -070010096 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
10097 ((comp_pred_mode &&
10098 best_mbmode.mv[1].as_int == zeromv[1].as_int) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -070010099 !comp_pred_mode))
10100 best_mbmode.mode = ZEROMV;
10101#if CONFIG_EXT_INTER
10102 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010103 if (frame_mv[NEAREST_NEARESTMV][refs[0]].as_int ==
10104 best_mbmode.mv[0].as_int &&
10105 frame_mv[NEAREST_NEARESTMV][refs[1]].as_int ==
10106 best_mbmode.mv[1].as_int)
10107 best_mbmode.mode = NEAREST_NEARESTMV;
10108 else if (frame_mv[NEAREST_NEARMV][refs[0]].as_int ==
10109 best_mbmode.mv[0].as_int &&
10110 frame_mv[NEAREST_NEARMV][refs[1]].as_int ==
10111 best_mbmode.mv[1].as_int)
10112 best_mbmode.mode = NEAREST_NEARMV;
10113 else if (frame_mv[NEAR_NEARESTMV][refs[0]].as_int ==
10114 best_mbmode.mv[0].as_int &&
10115 frame_mv[NEAR_NEARESTMV][refs[1]].as_int ==
10116 best_mbmode.mv[1].as_int)
10117 best_mbmode.mode = NEAR_NEARESTMV;
10118 else if (frame_mv[NEAR_NEARMV][refs[0]].as_int ==
10119 best_mbmode.mv[0].as_int &&
10120 frame_mv[NEAR_NEARMV][refs[1]].as_int ==
10121 best_mbmode.mv[1].as_int)
10122 best_mbmode.mode = NEAR_NEARMV;
10123 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
10124 best_mbmode.mode = ZERO_ZEROMV;
10125 }
10126#endif // CONFIG_EXT_INTER
10127#endif
10128 }
10129
10130#if CONFIG_REF_MV
David Barkercdcac6d2016-12-01 17:04:16 +000010131 {
Jingning Han731af492016-11-17 11:53:23 -080010132 int8_t ref_frame_type = av1_ref_frame_type(best_mbmode.ref_frame);
10133 int16_t mode_ctx = mbmi_ext->mode_context[ref_frame_type];
David Barker68e6e862016-11-24 15:10:15 +000010134 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) {
David Barkercdcac6d2016-12-01 17:04:16 +000010135 int_mv zeromv[2];
David Barker68e6e862016-11-24 15:10:15 +000010136#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +000010137 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
10138 best_mbmode.ref_frame[1] };
10139 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
10140 cm->allow_high_precision_mv)
10141 .as_int;
10142 zeromv[1].as_int = gm_get_motion_vector(&cm->global_motion[refs[1]],
10143 cm->allow_high_precision_mv)
10144 .as_int;
10145 lower_mv_precision(&zeromv[0].as_mv, cm->allow_high_precision_mv);
10146 lower_mv_precision(&zeromv[1].as_mv, cm->allow_high_precision_mv);
10147#else
10148 zeromv[0].as_int = zeromv[1].as_int = 0;
10149#endif // CONFIG_GLOBAL_MOTION
10150 if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
10151 best_mbmode.mv[0].as_int == zeromv[0].as_int &&
10152#if CONFIG_EXT_INTER
10153 (best_mbmode.ref_frame[1] <= INTRA_FRAME)
10154#else
10155 (best_mbmode.ref_frame[1] == NONE ||
10156 best_mbmode.mv[1].as_int == zeromv[1].as_int)
10157#endif // CONFIG_EXT_INTER
10158 ) {
10159 best_mbmode.mode = ZEROMV;
10160 }
David Barker68e6e862016-11-24 15:10:15 +000010161 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010162 }
10163#endif
10164
10165 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
10166 rd_cost->rate = INT_MAX;
10167 rd_cost->rdcost = INT64_MAX;
10168 return;
10169 }
10170
Yaowu Xuc27fc142016-08-22 16:08:15 -070010171#if CONFIG_DUAL_FILTER
10172 assert((cm->interp_filter == SWITCHABLE) ||
10173 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
10174 !is_inter_block(&best_mbmode));
10175 assert((cm->interp_filter == SWITCHABLE) ||
10176 (cm->interp_filter == best_mbmode.interp_filter[1]) ||
10177 !is_inter_block(&best_mbmode));
10178 if (best_mbmode.ref_frame[1] > INTRA_FRAME) {
10179 assert((cm->interp_filter == SWITCHABLE) ||
10180 (cm->interp_filter == best_mbmode.interp_filter[2]) ||
10181 !is_inter_block(&best_mbmode));
10182 assert((cm->interp_filter == SWITCHABLE) ||
10183 (cm->interp_filter == best_mbmode.interp_filter[3]) ||
10184 !is_inter_block(&best_mbmode));
10185 }
10186#else
10187 assert((cm->interp_filter == SWITCHABLE) ||
10188 (cm->interp_filter == best_mbmode.interp_filter) ||
10189 !is_inter_block(&best_mbmode));
10190#endif
10191
10192 if (!cpi->rc.is_src_frame_alt_ref)
Yaowu Xuf883b422016-08-30 14:01:10 -070010193 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
10194 sf->adaptive_rd_thresh, bsize, best_mode_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010195
10196 // macroblock modes
10197 *mbmi = best_mbmode;
10198 x->skip |= best_skip2;
10199
10200#if CONFIG_REF_MV
10201 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
10202 if (mbmi->mode != NEWMV)
10203 mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
10204 else
10205 mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
10206 }
10207#endif
10208
10209 for (i = 0; i < REFERENCE_MODES; ++i) {
10210 if (best_pred_rd[i] == INT64_MAX)
10211 best_pred_diff[i] = INT_MIN;
10212 else
10213 best_pred_diff[i] = best_rd - best_pred_rd[i];
10214 }
10215
10216 x->skip |= best_mode_skippable;
10217
10218 assert(best_mode_index >= 0);
10219
10220 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
10221 best_mode_skippable);
10222
Urvang Joshib100db72016-10-12 16:28:56 -070010223#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010224 if (cm->allow_screen_content_tools && pmi->palette_size[1] > 0) {
10225 restore_uv_color_map(cpi, x);
10226 }
Urvang Joshib100db72016-10-12 16:28:56 -070010227#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010228}
10229
Urvang Joshi52648442016-10-13 17:27:51 -070010230void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
10231 TileDataEnc *tile_data, MACROBLOCK *x,
10232 RD_COST *rd_cost, BLOCK_SIZE bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -070010233 PICK_MODE_CONTEXT *ctx,
10234 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070010235 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010236 MACROBLOCKD *const xd = &x->e_mbd;
10237 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
10238 unsigned char segment_id = mbmi->segment_id;
10239 const int comp_pred = 0;
10240 int i;
10241 int64_t best_pred_diff[REFERENCE_MODES];
10242 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
10243 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070010244 aom_prob comp_mode_p;
James Zern7b9407a2016-05-18 23:48:05 -070010245 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010246 int64_t this_rd = INT64_MAX;
10247 int rate2 = 0;
10248 const int64_t distortion2 = 0;
10249
10250 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
10251 &comp_mode_p);
10252
10253 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
10254 for (i = LAST_FRAME; i < TOTAL_REFS_PER_FRAME; ++i)
10255 x->pred_mv_sad[i] = INT_MAX;
10256
10257 rd_cost->rate = INT_MAX;
10258
10259 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
10260
Urvang Joshib100db72016-10-12 16:28:56 -070010261#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010262 mbmi->palette_mode_info.palette_size[0] = 0;
10263 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070010264#endif // CONFIG_PALETTE
10265
hui su5db97432016-10-14 16:10:14 -070010266#if CONFIG_FILTER_INTRA
10267 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10268 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10269#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010270 mbmi->mode = ZEROMV;
Yue Chencb60b182016-10-13 15:18:22 -070010271 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010272 mbmi->uv_mode = DC_PRED;
10273 mbmi->ref_frame[0] = LAST_FRAME;
10274 mbmi->ref_frame[1] = NONE;
Sarah Parkere5299862016-08-16 14:57:37 -070010275#if CONFIG_GLOBAL_MOTION
10276 mbmi->mv[0].as_int =
David Barkercdcac6d2016-12-01 17:04:16 +000010277 gm_get_motion_vector(&cm->global_motion[mbmi->ref_frame[0]],
10278 cm->allow_high_precision_mv)
10279 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -070010280#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010281 mbmi->mv[0].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -070010282#endif // CONFIG_GLOBAL_MOTION
Jingning Han64088952016-07-11 11:24:24 -070010283 mbmi->tx_size = max_txsize_lookup[bsize];
Yaowu Xuee775b12016-10-18 10:00:21 -070010284 x->skip = 1;
Sarah Parkere5299862016-08-16 14:57:37 -070010285
Yaowu Xuc27fc142016-08-22 16:08:15 -070010286#if CONFIG_REF_MV
10287 mbmi->ref_mv_idx = 0;
10288 mbmi->pred_mv[0].as_int = 0;
10289#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010290
10291 if (cm->interp_filter != BILINEAR) {
10292 best_filter = EIGHTTAP_REGULAR;
10293 if (cm->interp_filter == SWITCHABLE &&
10294#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -070010295 av1_is_interp_needed(xd) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010296#endif // CONFIG_EXT_INTERP
10297 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
10298 int rs;
10299 int best_rs = INT_MAX;
10300 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
10301#if CONFIG_DUAL_FILTER
10302 int k;
10303 for (k = 0; k < 4; ++k) mbmi->interp_filter[k] = i;
10304#else
10305 mbmi->interp_filter = i;
10306#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070010307 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010308 if (rs < best_rs) {
10309 best_rs = rs;
10310#if CONFIG_DUAL_FILTER
10311 best_filter = mbmi->interp_filter[0];
10312#else
10313 best_filter = mbmi->interp_filter;
10314#endif
10315 }
10316 }
10317 }
10318 }
10319 // Set the appropriate filter
10320 if (cm->interp_filter == SWITCHABLE) {
10321#if CONFIG_DUAL_FILTER
10322 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = best_filter;
10323#else
10324 mbmi->interp_filter = best_filter;
10325#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070010326 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010327 } else {
10328#if CONFIG_DUAL_FILTER
10329 for (i = 0; i < 4; ++i) mbmi->interp_filter[0] = cm->interp_filter;
10330#else
10331 mbmi->interp_filter = cm->interp_filter;
10332#endif
10333 }
10334
10335 if (cm->reference_mode == REFERENCE_MODE_SELECT)
Yaowu Xuf883b422016-08-30 14:01:10 -070010336 rate2 += av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010337
10338 // Estimate the reference frame signaling cost and add it
10339 // to the rolling cost variable.
10340 rate2 += ref_costs_single[LAST_FRAME];
10341 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10342
10343 rd_cost->rate = rate2;
10344 rd_cost->dist = distortion2;
10345 rd_cost->rdcost = this_rd;
10346
10347 if (this_rd >= best_rd_so_far) {
10348 rd_cost->rate = INT_MAX;
10349 rd_cost->rdcost = INT64_MAX;
10350 return;
10351 }
10352
10353#if CONFIG_DUAL_FILTER
10354 assert((cm->interp_filter == SWITCHABLE) ||
10355 (cm->interp_filter == mbmi->interp_filter[0]));
10356#else
10357 assert((cm->interp_filter == SWITCHABLE) ||
10358 (cm->interp_filter == mbmi->interp_filter));
10359#endif
10360
Yaowu Xuf883b422016-08-30 14:01:10 -070010361 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
10362 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010363
Yaowu Xuf883b422016-08-30 14:01:10 -070010364 av1_zero(best_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010365
10366 store_coding_context(x, ctx, THR_ZEROMV, best_pred_diff, 0);
10367}
10368
Urvang Joshi52648442016-10-13 17:27:51 -070010369void av1_rd_pick_inter_mode_sub8x8(const struct AV1_COMP *cpi,
10370 TileDataEnc *tile_data, struct macroblock *x,
10371 int mi_row, int mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -070010372 struct RD_COST *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010373#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010374 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010375#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010376 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
10377 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070010378 const AV1_COMMON *const cm = &cpi->common;
10379 const RD_OPT *const rd_opt = &cpi->rd;
10380 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010381 MACROBLOCKD *const xd = &x->e_mbd;
10382 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
10383 const struct segmentation *const seg = &cm->seg;
10384 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
10385 unsigned char segment_id = mbmi->segment_id;
10386 int comp_pred, i;
10387 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
10388 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
10389 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
10390 0,
Yaowu Xuf883b422016-08-30 14:01:10 -070010391 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010392#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070010393 AOM_LAST2_FLAG,
10394 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010395#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070010396 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010397#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070010398 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010399#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070010400 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -070010401 };
10402 int64_t best_rd = best_rd_so_far;
10403 int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
10404 int64_t best_pred_diff[REFERENCE_MODES];
10405 int64_t best_pred_rd[REFERENCE_MODES];
10406 MB_MODE_INFO best_mbmode;
10407 int ref_index, best_ref_index = 0;
10408 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
10409 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070010410 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010411#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -070010412 InterpFilter tmp_best_filter[4] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -070010413#else
James Zern7b9407a2016-05-18 23:48:05 -070010414 InterpFilter tmp_best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010415#endif
Jingning Han3f167252016-06-07 16:11:42 -070010416 int rate_uv_intra, rate_uv_tokenonly = INT_MAX;
10417 int64_t dist_uv = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010418 int skip_uv;
10419 PREDICTION_MODE mode_uv = DC_PRED;
Yaowu Xuf883b422016-08-30 14:01:10 -070010420 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -070010421 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
10422#if CONFIG_EXT_INTER
10423 int_mv seg_mvs[4][2][TOTAL_REFS_PER_FRAME];
10424#else
10425 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME];
10426#endif // CONFIG_EXT_INTER
10427 b_mode_info best_bmodes[4];
10428 int best_skip2 = 0;
10429 int ref_frame_skip_mask[2] = { 0 };
10430 int internal_active_edge =
Yaowu Xuf883b422016-08-30 14:01:10 -070010431 av1_active_edge_sb(cpi, mi_row, mi_col) && av1_internal_image_edge(cpi);
Yushin Cho77bba8d2016-11-04 16:36:56 -070010432#if CONFIG_PVQ
10433 od_rollback_buffer pre_buf;
10434
10435 od_encode_checkpoint(&x->daala_enc, &pre_buf);
10436#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010437
10438#if CONFIG_SUPERTX
10439 best_rd_so_far = INT64_MAX;
10440 best_rd = best_rd_so_far;
10441 best_yrd = best_rd_so_far;
10442#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010443 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010444
hui su5db97432016-10-14 16:10:14 -070010445#if CONFIG_FILTER_INTRA
10446 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10447 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10448#endif // CONFIG_FILTER_INTRA
Yue Chencb60b182016-10-13 15:18:22 -070010449 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010450#if CONFIG_EXT_INTER
Sarah Parker6fdc8532016-11-16 17:47:13 -080010451 mbmi->interinter_compound_data.type = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010452 mbmi->use_wedge_interintra = 0;
10453#endif // CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -070010454#if CONFIG_WARPED_MOTION
10455 mbmi->num_proj_ref[0] = 0;
10456 mbmi->num_proj_ref[1] = 0;
10457#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010458
10459 for (i = 0; i < 4; i++) {
10460 int j;
10461#if CONFIG_EXT_INTER
10462 int k;
10463
10464 for (k = 0; k < 2; k++)
10465 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
10466 seg_mvs[i][k][j].as_int = INVALID_MV;
10467#else
10468 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
10469 seg_mvs[i][j].as_int = INVALID_MV;
10470#endif // CONFIG_EXT_INTER
10471 }
10472
10473 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
10474 &comp_mode_p);
10475
10476 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
10477 rate_uv_intra = INT_MAX;
10478
10479 rd_cost->rate = INT_MAX;
10480#if CONFIG_SUPERTX
10481 *returnrate_nocoef = INT_MAX;
10482#endif
10483
10484 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
10485 x->mbmi_ext->mode_context[ref_frame] = 0;
10486#if CONFIG_REF_MV && CONFIG_EXT_INTER
10487 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
10488#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
10489 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
10490 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
10491 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
10492 } else {
10493 ref_frame_skip_mask[0] |= (1 << ref_frame);
10494 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10495 }
10496 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
10497#if CONFIG_EXT_INTER
10498 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
10499#endif // CONFIG_EXT_INTER
10500 frame_mv[ZEROMV][ref_frame].as_int = 0;
10501 }
10502
Urvang Joshib100db72016-10-12 16:28:56 -070010503#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010504 mbmi->palette_mode_info.palette_size[0] = 0;
10505 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070010506#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010507
10508 for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
10509 int mode_excluded = 0;
10510 int64_t this_rd = INT64_MAX;
10511 int disable_skip = 0;
10512 int compmode_cost = 0;
10513 int rate2 = 0, rate_y = 0, rate_uv = 0;
10514 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
10515 int skippable = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010516 int this_skip2 = 0;
10517 int64_t total_sse = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010518
Yushin Cho77bba8d2016-11-04 16:36:56 -070010519#if CONFIG_PVQ
10520 od_encode_rollback(&x->daala_enc, &pre_buf);
10521#endif
10522
Yaowu Xuf883b422016-08-30 14:01:10 -070010523 ref_frame = av1_ref_order[ref_index].ref_frame[0];
10524 second_ref_frame = av1_ref_order[ref_index].ref_frame[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010525
Yaowu Xu4306b6e2016-09-27 12:55:32 -070010526#if CONFIG_REF_MV
10527 mbmi->ref_mv_idx = 0;
10528#endif
10529
Yaowu Xuc27fc142016-08-22 16:08:15 -070010530 // Look at the reference frame of the best mode so far and set the
10531 // skip mask to look at a subset of the remaining modes.
10532 if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
10533 if (ref_index == 3) {
10534 switch (best_mbmode.ref_frame[0]) {
10535 case INTRA_FRAME: break;
10536 case LAST_FRAME:
10537 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
10538#if CONFIG_EXT_REFS
10539 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
10540 (1 << BWDREF_FRAME) |
10541#endif // CONFIG_EXT_REFS
10542 (1 << ALTREF_FRAME);
10543 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10544 break;
10545#if CONFIG_EXT_REFS
10546 case LAST2_FRAME:
10547 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST3_FRAME) |
10548 (1 << GOLDEN_FRAME) |
10549 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
10550 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10551 break;
10552 case LAST3_FRAME:
10553 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
10554 (1 << GOLDEN_FRAME) |
10555 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
10556 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10557 break;
10558#endif // CONFIG_EXT_REFS
10559 case GOLDEN_FRAME:
10560 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
10561#if CONFIG_EXT_REFS
10562 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
10563 (1 << BWDREF_FRAME) |
10564#endif // CONFIG_EXT_REFS
10565 (1 << ALTREF_FRAME);
10566 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10567 break;
10568#if CONFIG_EXT_REFS
10569 case BWDREF_FRAME:
10570 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
10571 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) |
10572 (1 << ALTREF_FRAME);
10573 ref_frame_skip_mask[1] |= (1 << ALTREF_FRAME) | 0x01;
10574 break;
10575#endif // CONFIG_EXT_REFS
10576 case ALTREF_FRAME:
10577 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
10578#if CONFIG_EXT_REFS
10579 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
10580 (1 << BWDREF_FRAME) |
10581#endif // CONFIG_EXT_REFS
10582 (1 << GOLDEN_FRAME);
10583#if CONFIG_EXT_REFS
10584 ref_frame_skip_mask[1] |= (1 << BWDREF_FRAME) | 0x01;
10585#endif // CONFIG_EXT_REFS
10586 break;
10587 case NONE:
10588 case TOTAL_REFS_PER_FRAME:
10589 assert(0 && "Invalid Reference frame");
10590 break;
10591 }
10592 }
10593 }
10594
10595 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010596 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010597 continue;
10598
10599 // Test best rd so far against threshold for trying this mode.
10600 if (!internal_active_edge &&
10601 rd_less_than_thresh(best_rd,
10602 rd_opt->threshes[segment_id][bsize][ref_index],
10603 tile_data->thresh_freq_fact[bsize][ref_index]))
10604 continue;
10605
10606 comp_pred = second_ref_frame > INTRA_FRAME;
10607 if (comp_pred) {
10608 if (!cpi->allow_comp_inter_inter) continue;
10609 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
10610 // Do not allow compound prediction if the segment level reference frame
10611 // feature is in use as in this case there can only be one reference.
10612 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
10613
10614 if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
10615 best_mbmode.ref_frame[0] == INTRA_FRAME)
10616 continue;
10617 }
10618
10619 // TODO(jingning, jkoleszar): scaling reference frame not supported for
10620 // sub8x8 blocks.
10621 if (ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010622 av1_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010623 continue;
10624
10625 if (second_ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010626 av1_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010627 continue;
10628
10629 if (comp_pred)
10630 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
10631 else if (ref_frame != INTRA_FRAME)
10632 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
10633
10634 // If the segment reference frame feature is enabled....
10635 // then do nothing if the current ref frame is not allowed..
10636 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
10637 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
10638 continue;
10639 // Disable this drop out case if the ref frame
10640 // segment level feature is enabled for this segment. This is to
10641 // prevent the possibility that we end up unable to pick any mode.
10642 } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
10643 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
10644 // unless ARNR filtering is enabled in which case we want
10645 // an unfiltered alternative. We allow near/nearest as well
10646 // because they may result in zero-zero MVs but be cheaper.
10647 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
10648 continue;
10649 }
10650
10651 mbmi->tx_size = TX_4X4;
10652 mbmi->uv_mode = DC_PRED;
10653 mbmi->ref_frame[0] = ref_frame;
10654 mbmi->ref_frame[1] = second_ref_frame;
10655// Evaluate all sub-pel filters irrespective of whether we can use
10656// them for this frame.
10657#if CONFIG_DUAL_FILTER
10658 for (i = 0; i < 4; ++i)
10659 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
10660 ? EIGHTTAP_REGULAR
10661 : cm->interp_filter;
10662#else
10663 mbmi->interp_filter =
10664 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
10665#endif
10666 x->skip = 0;
10667 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
10668
10669 // Select prediction reference frames.
10670 for (i = 0; i < MAX_MB_PLANE; i++) {
10671 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
10672 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
10673 }
10674
10675#if CONFIG_VAR_TX
10676 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -070010677 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010678#endif
10679
10680 if (ref_frame == INTRA_FRAME) {
10681 int rate;
10682 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y, &distortion_y,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -070010683 NULL, best_rd) >= best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010684 continue;
10685 rate2 += rate;
10686 rate2 += intra_cost_penalty;
10687 distortion2 += distortion_y;
10688
10689 if (rate_uv_intra == INT_MAX) {
10690 choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4, &rate_uv_intra,
10691 &rate_uv_tokenonly, &dist_uv, &skip_uv, &mode_uv);
10692 }
10693 rate2 += rate_uv_intra;
10694 rate_uv = rate_uv_tokenonly;
10695 distortion2 += dist_uv;
10696 distortion_uv = dist_uv;
10697 mbmi->uv_mode = mode_uv;
10698 } else {
10699 int rate;
10700 int64_t distortion;
10701 int64_t this_rd_thresh;
10702 int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
10703 int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
10704 int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
10705 int tmp_best_skippable = 0;
10706 int switchable_filter_index;
10707 int_mv *second_ref =
10708 comp_pred ? &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL;
10709 b_mode_info tmp_best_bmodes[16]; // Should this be 4 ?
10710 MB_MODE_INFO tmp_best_mbmode;
10711#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080010712 BEST_SEG_INFO bsi[DUAL_FILTER_SET_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010713#else
10714 BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
10715#endif
10716 int pred_exists = 0;
10717 int uv_skippable;
10718#if CONFIG_EXT_INTER
10719 int_mv compound_seg_newmvs[4][2];
10720 for (i = 0; i < 4; i++) {
10721 compound_seg_newmvs[i][0].as_int = INVALID_MV;
10722 compound_seg_newmvs[i][1].as_int = INVALID_MV;
10723 }
10724#endif // CONFIG_EXT_INTER
10725
10726 this_rd_thresh = (ref_frame == LAST_FRAME)
10727 ? rd_opt->threshes[segment_id][bsize][THR_LAST]
10728 : rd_opt->threshes[segment_id][bsize][THR_ALTR];
10729#if CONFIG_EXT_REFS
10730 this_rd_thresh = (ref_frame == LAST2_FRAME)
10731 ? rd_opt->threshes[segment_id][bsize][THR_LAST2]
10732 : this_rd_thresh;
10733 this_rd_thresh = (ref_frame == LAST3_FRAME)
10734 ? rd_opt->threshes[segment_id][bsize][THR_LAST3]
10735 : this_rd_thresh;
Zoe Liua6a6dd52016-10-18 13:03:12 -070010736 this_rd_thresh = (ref_frame == BWDREF_FRAME)
10737 ? rd_opt->threshes[segment_id][bsize][THR_BWDR]
10738 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010739#endif // CONFIG_EXT_REFS
10740 this_rd_thresh = (ref_frame == GOLDEN_FRAME)
10741 ? rd_opt->threshes[segment_id][bsize][THR_GOLD]
10742 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010743
10744 // TODO(any): Add search of the tx_type to improve rd performance at the
10745 // expense of speed.
10746 mbmi->tx_type = DCT_DCT;
10747
10748 if (cm->interp_filter != BILINEAR) {
10749#if CONFIG_DUAL_FILTER
10750 tmp_best_filter[0] = EIGHTTAP_REGULAR;
10751 tmp_best_filter[1] = EIGHTTAP_REGULAR;
10752 tmp_best_filter[2] = EIGHTTAP_REGULAR;
10753 tmp_best_filter[3] = EIGHTTAP_REGULAR;
10754#else
10755 tmp_best_filter = EIGHTTAP_REGULAR;
10756#endif
10757 if (x->source_variance < sf->disable_filter_search_var_thresh) {
10758#if CONFIG_DUAL_FILTER
10759 tmp_best_filter[0] = EIGHTTAP_REGULAR;
10760#else
10761 tmp_best_filter = EIGHTTAP_REGULAR;
10762#endif
10763 } else if (sf->adaptive_pred_interp_filter == 1 &&
10764 ctx->pred_interp_filter < SWITCHABLE) {
10765#if CONFIG_DUAL_FILTER
10766 tmp_best_filter[0] = ctx->pred_interp_filter;
10767#else
10768 tmp_best_filter = ctx->pred_interp_filter;
10769#endif
10770 } else if (sf->adaptive_pred_interp_filter == 2) {
10771#if CONFIG_DUAL_FILTER
10772 tmp_best_filter[0] = ctx->pred_interp_filter < SWITCHABLE
10773 ? ctx->pred_interp_filter
10774 : 0;
10775#else
10776 tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE
10777 ? ctx->pred_interp_filter
10778 : 0;
10779#endif
10780 } else {
10781#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080010782 const int filter_set_size = DUAL_FILTER_SET_SIZE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010783#else
Angie Chiang5678ad92016-11-21 09:38:40 -080010784 const int filter_set_size = SWITCHABLE_FILTERS;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010785#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010786 for (switchable_filter_index = 0;
Angie Chiang5678ad92016-11-21 09:38:40 -080010787 switchable_filter_index < filter_set_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010788 ++switchable_filter_index) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010789 int newbest, rs;
10790 int64_t rs_rd;
10791 MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
10792#if CONFIG_DUAL_FILTER
10793 mbmi->interp_filter[0] = filter_sets[switchable_filter_index][0];
10794 mbmi->interp_filter[1] = filter_sets[switchable_filter_index][1];
10795 mbmi->interp_filter[2] = filter_sets[switchable_filter_index][0];
10796 mbmi->interp_filter[3] = filter_sets[switchable_filter_index][1];
10797#else
10798 mbmi->interp_filter = switchable_filter_index;
10799#endif
10800 tmp_rd = rd_pick_best_sub8x8_mode(
10801 cpi, x, &mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
10802 &rate, &rate_y, &distortion, &skippable, &total_sse,
10803 (int)this_rd_thresh, seg_mvs,
10804#if CONFIG_EXT_INTER
10805 compound_seg_newmvs,
10806#endif // CONFIG_EXT_INTER
10807 bsi, switchable_filter_index, mi_row, mi_col);
10808#if CONFIG_EXT_INTERP
10809#if CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070010810 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010811 (mbmi->interp_filter[0] != EIGHTTAP_REGULAR ||
10812 mbmi->interp_filter[1] != EIGHTTAP_REGULAR)) // invalid config
10813 continue;
10814#else
Yaowu Xuf883b422016-08-30 14:01:10 -070010815 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010816 mbmi->interp_filter != EIGHTTAP_REGULAR) // invalid config
10817 continue;
10818#endif
10819#endif // CONFIG_EXT_INTERP
10820 if (tmp_rd == INT64_MAX) continue;
Yaowu Xuf883b422016-08-30 14:01:10 -070010821 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010822 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
10823 if (cm->interp_filter == SWITCHABLE) tmp_rd += rs_rd;
10824
10825 newbest = (tmp_rd < tmp_best_rd);
10826 if (newbest) {
10827#if CONFIG_DUAL_FILTER
10828 tmp_best_filter[0] = mbmi->interp_filter[0];
10829 tmp_best_filter[1] = mbmi->interp_filter[1];
10830 tmp_best_filter[2] = mbmi->interp_filter[2];
10831 tmp_best_filter[3] = mbmi->interp_filter[3];
10832#else
10833 tmp_best_filter = mbmi->interp_filter;
10834#endif
10835 tmp_best_rd = tmp_rd;
10836 }
10837 if ((newbest && cm->interp_filter == SWITCHABLE) ||
10838 (
10839#if CONFIG_DUAL_FILTER
10840 mbmi->interp_filter[0] == cm->interp_filter
10841#else
10842 mbmi->interp_filter == cm->interp_filter
10843#endif
10844 && cm->interp_filter != SWITCHABLE)) {
10845 tmp_best_rdu = tmp_rd;
10846 tmp_best_rate = rate;
10847 tmp_best_ratey = rate_y;
10848 tmp_best_distortion = distortion;
10849 tmp_best_sse = total_sse;
10850 tmp_best_skippable = skippable;
10851 tmp_best_mbmode = *mbmi;
10852 for (i = 0; i < 4; i++) {
10853 tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
10854 }
10855 pred_exists = 1;
10856 }
10857 } // switchable_filter_index loop
10858 }
10859 }
10860
10861 if (tmp_best_rdu == INT64_MAX && pred_exists) continue;
10862
10863#if CONFIG_DUAL_FILTER
10864 mbmi->interp_filter[0] =
10865 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[0]
10866 : cm->interp_filter);
10867 mbmi->interp_filter[1] =
10868 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[1]
10869 : cm->interp_filter);
10870 mbmi->interp_filter[2] =
10871 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[2]
10872 : cm->interp_filter);
10873 mbmi->interp_filter[3] =
10874 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[3]
10875 : cm->interp_filter);
10876#else
10877 mbmi->interp_filter =
10878 (cm->interp_filter == SWITCHABLE ? tmp_best_filter
10879 : cm->interp_filter);
10880#endif
10881
10882 if (!pred_exists) {
10883 // Handles the special case when a filter that is not in the
10884 // switchable list (bilinear) is indicated at the frame level
10885 tmp_rd = rd_pick_best_sub8x8_mode(
10886 cpi, x, &x->mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
10887 &rate, &rate_y, &distortion, &skippable, &total_sse,
10888 (int)this_rd_thresh, seg_mvs,
10889#if CONFIG_EXT_INTER
10890 compound_seg_newmvs,
10891#endif // CONFIG_EXT_INTER
10892 bsi, 0, mi_row, mi_col);
10893#if CONFIG_EXT_INTERP
10894#if CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070010895 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010896 (mbmi->interp_filter[0] != EIGHTTAP_REGULAR ||
10897 mbmi->interp_filter[1] != EIGHTTAP_REGULAR)) {
10898 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
10899 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
10900 }
10901#else
Yaowu Xuf883b422016-08-30 14:01:10 -070010902 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010903 mbmi->interp_filter != EIGHTTAP_REGULAR)
10904 mbmi->interp_filter = EIGHTTAP_REGULAR;
10905#endif // CONFIG_DUAL_FILTER
10906#endif // CONFIG_EXT_INTERP
10907 if (tmp_rd == INT64_MAX) continue;
10908 } else {
10909 total_sse = tmp_best_sse;
10910 rate = tmp_best_rate;
10911 rate_y = tmp_best_ratey;
10912 distortion = tmp_best_distortion;
10913 skippable = tmp_best_skippable;
10914 *mbmi = tmp_best_mbmode;
10915 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
10916 }
10917 // Add in the cost of the transform type
10918 if (!xd->lossless[mbmi->segment_id]) {
10919 int rate_tx_type = 0;
10920#if CONFIG_EXT_TX
10921 if (get_ext_tx_types(mbmi->tx_size, bsize, 1) > 1) {
10922 const int eset = get_ext_tx_set(mbmi->tx_size, bsize, 1);
10923 rate_tx_type =
10924 cpi->inter_tx_type_costs[eset][mbmi->tx_size][mbmi->tx_type];
10925 }
10926#else
10927 if (mbmi->tx_size < TX_32X32) {
10928 rate_tx_type = cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
10929 }
10930#endif
10931 rate += rate_tx_type;
10932 rate_y += rate_tx_type;
10933 }
10934
10935 rate2 += rate;
10936 distortion2 += distortion;
10937
10938 if (cm->interp_filter == SWITCHABLE)
Yaowu Xuf883b422016-08-30 14:01:10 -070010939 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010940
10941 if (!mode_excluded)
10942 mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
10943 : cm->reference_mode == COMPOUND_REFERENCE;
10944
Yaowu Xuf883b422016-08-30 14:01:10 -070010945 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010946
10947 tmp_best_rdu =
Yaowu Xuf883b422016-08-30 14:01:10 -070010948 best_rd - AOMMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
Yaowu Xuc27fc142016-08-22 16:08:15 -070010949 RDCOST(x->rdmult, x->rddiv, 0, total_sse));
10950
10951 if (tmp_best_rdu > 0) {
10952 // If even the 'Y' rd value of split is higher than best so far
10953 // then dont bother looking at UV
Angie Chiangb5dda482016-11-02 16:19:58 -070010954 int is_cost_valid_uv;
Angie Chiangb5dda482016-11-02 16:19:58 -070010955 RD_STATS rd_stats_uv;
David Barkerac37fa32016-12-02 12:30:21 +000010956 av1_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col, NULL,
10957 BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010958#if CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -070010959 is_cost_valid_uv =
10960 inter_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
Angie Chiang284d7772016-11-08 11:06:45 -080010961#else
10962 is_cost_valid_uv =
10963 super_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
10964#endif
Angie Chiangb5dda482016-11-02 16:19:58 -070010965 rate_uv = rd_stats_uv.rate;
10966 distortion_uv = rd_stats_uv.dist;
10967 uv_skippable = rd_stats_uv.skip;
10968 uv_sse = rd_stats_uv.sse;
Angie Chiang284d7772016-11-08 11:06:45 -080010969
Angie Chiangb5dda482016-11-02 16:19:58 -070010970 if (!is_cost_valid_uv) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010971 rate2 += rate_uv;
10972 distortion2 += distortion_uv;
10973 skippable = skippable && uv_skippable;
10974 total_sse += uv_sse;
10975 } else {
10976 continue;
10977 }
10978 }
10979
10980 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
10981
10982 // Estimate the reference frame signaling cost and add it
10983 // to the rolling cost variable.
10984 if (second_ref_frame > INTRA_FRAME) {
10985 rate2 += ref_costs_comp[ref_frame];
10986#if CONFIG_EXT_REFS
10987 rate2 += ref_costs_comp[second_ref_frame];
10988#endif // CONFIG_EXT_REFS
10989 } else {
10990 rate2 += ref_costs_single[ref_frame];
10991 }
10992
10993 if (!disable_skip) {
10994 // Skip is never coded at the segment level for sub8x8 blocks and instead
10995 // always coded in the bitstream at the mode info level.
10996
10997 if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
10998 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
10999 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
11000 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070011001 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011002 } else {
11003 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070011004 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011005 distortion2 = total_sse;
11006 assert(total_sse >= 0);
11007 rate2 -= (rate_y + rate_uv);
11008 rate_y = 0;
11009 rate_uv = 0;
11010 this_skip2 = 1;
11011 }
11012 } else {
11013 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070011014 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011015 }
11016
11017 // Calculate the final RD estimate for this mode.
11018 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
11019 }
11020
11021 if (!disable_skip && ref_frame == INTRA_FRAME) {
11022 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070011023 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011024 }
11025
11026 // Did this mode help.. i.e. is it the new best mode
11027 if (this_rd < best_rd || x->skip) {
11028 if (!mode_excluded) {
11029 // Note index of best mode so far
11030 best_ref_index = ref_index;
11031
11032 if (ref_frame == INTRA_FRAME) {
11033 /* required for left and above block mv */
11034 mbmi->mv[0].as_int = 0;
11035 }
11036
11037 rd_cost->rate = rate2;
11038#if CONFIG_SUPERTX
11039 *returnrate_nocoef = rate2 - rate_y - rate_uv;
11040 if (!disable_skip)
11041 *returnrate_nocoef -=
Yaowu Xuf883b422016-08-30 14:01:10 -070011042 av1_cost_bit(av1_get_skip_prob(cm, xd), this_skip2);
11043 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
11044 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011045 assert(*returnrate_nocoef > 0);
11046#endif // CONFIG_SUPERTX
11047 rd_cost->dist = distortion2;
11048 rd_cost->rdcost = this_rd;
11049 best_rd = this_rd;
11050 best_yrd =
11051 best_rd - RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
11052 best_mbmode = *mbmi;
11053 best_skip2 = this_skip2;
11054
11055#if CONFIG_VAR_TX
11056 for (i = 0; i < MAX_MB_PLANE; ++i)
11057 memset(ctx->blk_skip[i], 0, sizeof(uint8_t) * ctx->num_4x4_blk);
11058#endif
11059
11060 for (i = 0; i < 4; i++) best_bmodes[i] = xd->mi[0]->bmi[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011061 }
11062 }
11063
11064 /* keep record of best compound/single-only prediction */
11065 if (!disable_skip && ref_frame != INTRA_FRAME) {
11066 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
11067
11068 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
11069 single_rate = rate2 - compmode_cost;
11070 hybrid_rate = rate2;
11071 } else {
11072 single_rate = rate2;
11073 hybrid_rate = rate2 + compmode_cost;
11074 }
11075
11076 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
11077 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
11078
11079 if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE])
11080 best_pred_rd[SINGLE_REFERENCE] = single_rd;
11081 else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE])
11082 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
11083
11084 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
11085 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
11086 }
11087
Yaowu Xuc27fc142016-08-22 16:08:15 -070011088 if (x->skip && !comp_pred) break;
11089 }
11090
11091 if (best_rd >= best_rd_so_far) {
11092 rd_cost->rate = INT_MAX;
11093 rd_cost->rdcost = INT64_MAX;
11094#if CONFIG_SUPERTX
11095 *returnrate_nocoef = INT_MAX;
11096#endif // CONFIG_SUPERTX
11097 return;
11098 }
11099
Yaowu Xuc27fc142016-08-22 16:08:15 -070011100 if (best_rd == INT64_MAX) {
11101 rd_cost->rate = INT_MAX;
11102 rd_cost->dist = INT64_MAX;
11103 rd_cost->rdcost = INT64_MAX;
11104#if CONFIG_SUPERTX
11105 *returnrate_nocoef = INT_MAX;
11106#endif // CONFIG_SUPERTX
11107 return;
11108 }
11109
11110#if CONFIG_DUAL_FILTER
11111 assert((cm->interp_filter == SWITCHABLE) ||
11112 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
11113 !is_inter_block(&best_mbmode));
11114#else
11115 assert((cm->interp_filter == SWITCHABLE) ||
11116 (cm->interp_filter == best_mbmode.interp_filter) ||
11117 !is_inter_block(&best_mbmode));
11118#endif
11119
Yaowu Xuf883b422016-08-30 14:01:10 -070011120 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
11121 sf->adaptive_rd_thresh, bsize, best_ref_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011122
11123 // macroblock modes
11124 *mbmi = best_mbmode;
Jingning Hanfe45b212016-11-22 10:30:23 -080011125#if CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011126 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
Jingning Hanfe45b212016-11-22 10:30:23 -080011127#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070011128
11129 x->skip |= best_skip2;
11130 if (!is_inter_block(&best_mbmode)) {
11131 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
11132 } else {
11133 for (i = 0; i < 4; ++i)
11134 memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
11135
Yaowu Xuc27fc142016-08-22 16:08:15 -070011136#if CONFIG_REF_MV
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -070011137 mbmi->pred_mv[0].as_int = xd->mi[0]->bmi[3].pred_mv[0].as_int;
11138 mbmi->pred_mv[1].as_int = xd->mi[0]->bmi[3].pred_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011139#endif
Yaowu Xu4306b6e2016-09-27 12:55:32 -070011140 mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
11141 mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011142 }
11143
11144 for (i = 0; i < REFERENCE_MODES; ++i) {
11145 if (best_pred_rd[i] == INT64_MAX)
11146 best_pred_diff[i] = INT_MIN;
11147 else
11148 best_pred_diff[i] = best_rd - best_pred_rd[i];
11149 }
11150
11151 store_coding_context(x, ctx, best_ref_index, best_pred_diff, 0);
11152}
11153
Yue Chencb60b182016-10-13 15:18:22 -070011154#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070011155// This function has a structure similar to av1_build_obmc_inter_prediction
Yaowu Xuc27fc142016-08-22 16:08:15 -070011156//
11157// The OBMC predictor is computed as:
11158//
11159// PObmc(x,y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070011160// AOM_BLEND_A64(Mh(x),
11161// AOM_BLEND_A64(Mv(y), P(x,y), PAbove(x,y)),
Yaowu Xuc27fc142016-08-22 16:08:15 -070011162// PLeft(x, y))
11163//
Yaowu Xuf883b422016-08-30 14:01:10 -070011164// Scaling up by AOM_BLEND_A64_MAX_ALPHA ** 2 and omitting the intermediate
Yaowu Xuc27fc142016-08-22 16:08:15 -070011165// rounding, this can be written as:
11166//
Yaowu Xuf883b422016-08-30 14:01:10 -070011167// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * Pobmc(x,y) =
Yaowu Xuc27fc142016-08-22 16:08:15 -070011168// Mh(x) * Mv(y) * P(x,y) +
11169// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070011170// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011171//
11172// Where :
11173//
Yaowu Xuf883b422016-08-30 14:01:10 -070011174// Cv(y) = AOM_BLEND_A64_MAX_ALPHA - Mv(y)
11175// Ch(y) = AOM_BLEND_A64_MAX_ALPHA - Mh(y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011176//
11177// This function computes 'wsrc' and 'mask' as:
11178//
11179// wsrc(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070011180// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * src(x, y) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070011181// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070011182// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011183//
11184// mask(x, y) = Mh(x) * Mv(y)
11185//
11186// These can then be used to efficiently approximate the error for any
11187// predictor P in the context of the provided neighbouring predictors by
11188// computing:
11189//
11190// error(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070011191// wsrc(x, y) - mask(x, y) * P(x, y) / (AOM_BLEND_A64_MAX_ALPHA ** 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011192//
Yaowu Xuf883b422016-08-30 14:01:10 -070011193static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011194 const MACROBLOCKD *xd, int mi_row,
11195 int mi_col, const uint8_t *above,
11196 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -070011197 int left_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011198 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
11199 int row, col, i;
Jingning Hanff6ee6a2016-12-07 09:55:21 -080011200 const int bw = xd->n8_w << MI_SIZE_LOG2;
11201 const int bh = xd->n8_h << MI_SIZE_LOG2;
Yue Chene9638cc2016-10-10 12:37:54 -070011202 int32_t *mask_buf = x->mask_buf;
11203 int32_t *wsrc_buf = x->wsrc_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011204 const int wsrc_stride = bw;
11205 const int mask_stride = bw;
Yaowu Xuf883b422016-08-30 14:01:10 -070011206 const int src_scale = AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA;
11207#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011208 const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
11209#else
11210 const int is_hbd = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070011211#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011212
11213 // plane 0 should not be subsampled
11214 assert(xd->plane[0].subsampling_x == 0);
11215 assert(xd->plane[0].subsampling_y == 0);
11216
Yaowu Xuf883b422016-08-30 14:01:10 -070011217 av1_zero_array(wsrc_buf, bw * bh);
11218 for (i = 0; i < bw * bh; ++i) mask_buf[i] = AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011219
11220 // handle above row
11221 if (xd->up_available) {
11222 const int overlap = num_4x4_blocks_high_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070011223 const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011224 const int mi_row_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070011225 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011226
11227 assert(miw > 0);
11228
11229 i = 0;
11230 do { // for each mi in the above row
11231 const int mi_col_offset = i;
11232 const MB_MODE_INFO *const above_mbmi =
11233 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
11234 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -070011235 AOMMIN(xd->n8_w, num_8x8_blocks_wide_lookup[above_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011236 const int neighbor_bw = mi_step * MI_SIZE;
11237
11238 if (is_neighbor_overlappable(above_mbmi)) {
11239 const int tmp_stride = above_stride;
11240 int32_t *wsrc = wsrc_buf + (i * MI_SIZE);
11241 int32_t *mask = mask_buf + (i * MI_SIZE);
11242
11243 if (!is_hbd) {
11244 const uint8_t *tmp = above;
11245
11246 for (row = 0; row < overlap; ++row) {
11247 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070011248 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011249 for (col = 0; col < neighbor_bw; ++col) {
11250 wsrc[col] = m1 * tmp[col];
11251 mask[col] = m0;
11252 }
11253 wsrc += wsrc_stride;
11254 mask += mask_stride;
11255 tmp += tmp_stride;
11256 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011257#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011258 } else {
11259 const uint16_t *tmp = CONVERT_TO_SHORTPTR(above);
11260
11261 for (row = 0; row < overlap; ++row) {
11262 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070011263 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011264 for (col = 0; col < neighbor_bw; ++col) {
11265 wsrc[col] = m1 * tmp[col];
11266 mask[col] = m0;
11267 }
11268 wsrc += wsrc_stride;
11269 mask += mask_stride;
11270 tmp += tmp_stride;
11271 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011272#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011273 }
11274 }
11275
11276 above += neighbor_bw;
11277 i += mi_step;
11278 } while (i < miw);
11279 }
11280
11281 for (i = 0; i < bw * bh; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -070011282 wsrc_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
11283 mask_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011284 }
11285
11286 // handle left column
11287 if (xd->left_available) {
11288 const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070011289 const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011290 const int mi_col_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070011291 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011292
11293 assert(mih > 0);
11294
11295 i = 0;
11296 do { // for each mi in the left column
11297 const int mi_row_offset = i;
11298 const MB_MODE_INFO *const left_mbmi =
11299 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
11300 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -070011301 AOMMIN(xd->n8_h, num_8x8_blocks_high_lookup[left_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011302 const int neighbor_bh = mi_step * MI_SIZE;
11303
11304 if (is_neighbor_overlappable(left_mbmi)) {
11305 const int tmp_stride = left_stride;
11306 int32_t *wsrc = wsrc_buf + (i * MI_SIZE * wsrc_stride);
11307 int32_t *mask = mask_buf + (i * MI_SIZE * mask_stride);
11308
11309 if (!is_hbd) {
11310 const uint8_t *tmp = left;
11311
11312 for (row = 0; row < neighbor_bh; ++row) {
11313 for (col = 0; col < overlap; ++col) {
11314 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070011315 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
11316 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
11317 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
11318 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011319 }
11320 wsrc += wsrc_stride;
11321 mask += mask_stride;
11322 tmp += tmp_stride;
11323 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011324#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011325 } else {
11326 const uint16_t *tmp = CONVERT_TO_SHORTPTR(left);
11327
11328 for (row = 0; row < neighbor_bh; ++row) {
11329 for (col = 0; col < overlap; ++col) {
11330 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070011331 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
11332 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
11333 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
11334 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011335 }
11336 wsrc += wsrc_stride;
11337 mask += mask_stride;
11338 tmp += tmp_stride;
11339 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011340#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011341 }
11342 }
11343
11344 left += neighbor_bh * left_stride;
11345 i += mi_step;
11346 } while (i < mih);
11347 }
11348
11349 if (!is_hbd) {
11350 const uint8_t *src = x->plane[0].src.buf;
11351
11352 for (row = 0; row < bh; ++row) {
11353 for (col = 0; col < bw; ++col) {
11354 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
11355 }
11356 wsrc_buf += wsrc_stride;
11357 src += x->plane[0].src.stride;
11358 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011359#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011360 } else {
11361 const uint16_t *src = CONVERT_TO_SHORTPTR(x->plane[0].src.buf);
11362
11363 for (row = 0; row < bh; ++row) {
11364 for (col = 0; col < bw; ++col) {
11365 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
11366 }
11367 wsrc_buf += wsrc_stride;
11368 src += x->plane[0].src.stride;
11369 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011370#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011371 }
11372}
Yue Chencb60b182016-10-13 15:18:22 -070011373#endif // CONFIG_MOTION_VAR