blob: 7b24b32c5fdfbc47756a669bc84eedcab86c7040 [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
116#define ANGLE_FAST_SEARCH 1
117#define ANGLE_SKIP_THRESH 10
118#define FILTER_FAST_SEARCH 1
119#endif // CONFIG_EXT_INTRA
120
121const double ADST_FLIP_SVM[8] = { -6.6623, -2.8062, -3.2531, 3.1671, // vert
122 -7.7051, -3.2234, -3.6193, 3.4533 }; // horz
123
124typedef struct {
125 PREDICTION_MODE mode;
126 MV_REFERENCE_FRAME ref_frame[2];
127} MODE_DEFINITION;
128
129typedef struct { MV_REFERENCE_FRAME ref_frame[2]; } REF_DEFINITION;
130
131struct rdcost_block_args {
Yaowu Xuf883b422016-08-30 14:01:10 -0700132 const AV1_COMP *cpi;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700133 MACROBLOCK *x;
134 ENTROPY_CONTEXT t_above[2 * MAX_MIB_SIZE];
135 ENTROPY_CONTEXT t_left[2 * MAX_MIB_SIZE];
Angie Chiang7c2b7f22016-11-07 16:00:00 -0800136 RD_STATS rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700137 int64_t this_rd;
138 int64_t best_rd;
139 int exit_early;
140 int use_fast_coef_costing;
Urvang Joshi03f6fdc2016-10-14 15:53:39 -0700141 const SCAN_ORDER *scan_order;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700142};
143
144#define LAST_NEW_MV_INDEX 6
Yaowu Xuf883b422016-08-30 14:01:10 -0700145static const MODE_DEFINITION av1_mode_order[MAX_MODES] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700146 { NEARESTMV, { LAST_FRAME, NONE } },
147#if CONFIG_EXT_REFS
148 { NEARESTMV, { LAST2_FRAME, NONE } },
149 { NEARESTMV, { LAST3_FRAME, NONE } },
150 { NEARESTMV, { BWDREF_FRAME, NONE } },
151#endif // CONFIG_EXT_REFS
152 { NEARESTMV, { ALTREF_FRAME, NONE } },
153 { NEARESTMV, { GOLDEN_FRAME, NONE } },
154
155 { DC_PRED, { INTRA_FRAME, NONE } },
156
157 { NEWMV, { LAST_FRAME, NONE } },
158#if CONFIG_EXT_REFS
159 { NEWMV, { LAST2_FRAME, NONE } },
160 { NEWMV, { LAST3_FRAME, NONE } },
161 { NEWMV, { BWDREF_FRAME, NONE } },
162#endif // CONFIG_EXT_REFS
163 { NEWMV, { ALTREF_FRAME, NONE } },
164 { NEWMV, { GOLDEN_FRAME, NONE } },
165
166 { NEARMV, { LAST_FRAME, NONE } },
167#if CONFIG_EXT_REFS
168 { NEARMV, { LAST2_FRAME, NONE } },
169 { NEARMV, { LAST3_FRAME, NONE } },
170 { NEARMV, { BWDREF_FRAME, NONE } },
171#endif // CONFIG_EXT_REFS
172 { NEARMV, { ALTREF_FRAME, NONE } },
173 { NEARMV, { GOLDEN_FRAME, NONE } },
174
175#if CONFIG_EXT_INTER
176 { NEWFROMNEARMV, { LAST_FRAME, NONE } },
177#if CONFIG_EXT_REFS
178 { NEWFROMNEARMV, { LAST2_FRAME, NONE } },
179 { NEWFROMNEARMV, { LAST3_FRAME, NONE } },
180 { NEWFROMNEARMV, { BWDREF_FRAME, NONE } },
181#endif // CONFIG_EXT_REFS
182 { NEWFROMNEARMV, { ALTREF_FRAME, NONE } },
183 { NEWFROMNEARMV, { GOLDEN_FRAME, NONE } },
184#endif // CONFIG_EXT_INTER
185
186 { ZEROMV, { LAST_FRAME, NONE } },
187#if CONFIG_EXT_REFS
188 { ZEROMV, { LAST2_FRAME, NONE } },
189 { ZEROMV, { LAST3_FRAME, NONE } },
190 { ZEROMV, { BWDREF_FRAME, NONE } },
191#endif // CONFIG_EXT_REFS
192 { ZEROMV, { GOLDEN_FRAME, NONE } },
193 { ZEROMV, { ALTREF_FRAME, NONE } },
194
195// TODO(zoeliu): May need to reconsider the order on the modes to check
196
197#if CONFIG_EXT_INTER
198 { NEAREST_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
199#if CONFIG_EXT_REFS
200 { NEAREST_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
201 { NEAREST_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
202#endif // CONFIG_EXT_REFS
203 { NEAREST_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
204#if CONFIG_EXT_REFS
205 { NEAREST_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
206 { NEAREST_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
207 { NEAREST_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
208 { NEAREST_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
209#endif // CONFIG_EXT_REFS
210
211#else // CONFIG_EXT_INTER
212
213 { NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
214#if CONFIG_EXT_REFS
215 { NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
216 { NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
217#endif // CONFIG_EXT_REFS
218 { NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
219#if CONFIG_EXT_REFS
220 { NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
221 { NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
222 { NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
223 { NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
224#endif // CONFIG_EXT_REFS
225#endif // CONFIG_EXT_INTER
226
227 { TM_PRED, { INTRA_FRAME, NONE } },
228
Urvang Joshi6be4a542016-11-03 15:24:05 -0700229#if CONFIG_ALT_INTRA
230 { SMOOTH_PRED, { INTRA_FRAME, NONE } },
231#endif // CONFIG_ALT_INTRA
232
Yaowu Xuc27fc142016-08-22 16:08:15 -0700233#if CONFIG_EXT_INTER
234 { NEAR_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
235 { NEAREST_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
236 { NEAR_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
237 { NEW_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
238 { NEAREST_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
239 { NEW_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
240 { NEAR_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
241 { NEW_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
242 { ZERO_ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
243
244#if CONFIG_EXT_REFS
245 { NEAR_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
246 { NEAREST_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
247 { NEAR_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
248 { NEW_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
249 { NEAREST_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
250 { NEW_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
251 { NEAR_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
252 { NEW_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
253 { ZERO_ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
254
255 { NEAR_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
256 { NEAREST_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
257 { NEAR_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
258 { NEW_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
259 { NEAREST_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
260 { NEW_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
261 { NEAR_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
262 { NEW_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
263 { ZERO_ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
264#endif // CONFIG_EXT_REFS
265
266 { NEAR_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
267 { NEAREST_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
268 { NEAR_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
269 { NEW_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
270 { NEAREST_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
271 { NEW_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
272 { NEAR_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
273 { NEW_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
274 { ZERO_ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
275
276#if CONFIG_EXT_REFS
277 { NEAR_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
278 { NEAREST_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
279 { NEAR_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
280 { NEW_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
281 { NEAREST_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
282 { NEW_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
283 { NEAR_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
284 { NEW_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
285 { ZERO_ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
286
287 { NEAR_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
288 { NEAREST_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
289 { NEAR_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
290 { NEW_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
291 { NEAREST_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
292 { NEW_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
293 { NEAR_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
294 { NEW_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
295 { ZERO_ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
296
297 { NEAR_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
298 { NEAREST_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
299 { NEAR_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
300 { NEW_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
301 { NEAREST_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
302 { NEW_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
303 { NEAR_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
304 { NEW_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
305 { ZERO_ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
306
307 { NEAR_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
308 { NEAREST_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
309 { NEAR_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
310 { NEW_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
311 { NEAREST_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
312 { NEW_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
313 { NEAR_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
314 { NEW_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
315 { ZERO_ZEROMV, { GOLDEN_FRAME, BWDREF_FRAME } },
316#endif // CONFIG_EXT_REFS
317
318#else // CONFIG_EXT_INTER
319
320 { NEARMV, { LAST_FRAME, ALTREF_FRAME } },
321 { NEWMV, { LAST_FRAME, ALTREF_FRAME } },
322#if CONFIG_EXT_REFS
323 { NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
324 { NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
325 { NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
326 { NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
327#endif // CONFIG_EXT_REFS
328 { NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
329 { NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
330
331#if CONFIG_EXT_REFS
332 { NEARMV, { LAST_FRAME, BWDREF_FRAME } },
333 { NEWMV, { LAST_FRAME, BWDREF_FRAME } },
334 { NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
335 { NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
336 { NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
337 { NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
338 { NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
339 { NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
340#endif // CONFIG_EXT_REFS
341
342 { ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
343#if CONFIG_EXT_REFS
344 { ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
345 { ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
346#endif // CONFIG_EXT_REFS
347 { ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
348
349#if CONFIG_EXT_REFS
350 { ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
351 { ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
352 { ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
353 { ZEROMV, { GOLDEN_FRAME, BWDREF_FRAME } },
354#endif // CONFIG_EXT_REFS
355
356#endif // CONFIG_EXT_INTER
357
358 { H_PRED, { INTRA_FRAME, NONE } },
359 { V_PRED, { INTRA_FRAME, NONE } },
360 { D135_PRED, { INTRA_FRAME, NONE } },
361 { D207_PRED, { INTRA_FRAME, NONE } },
362 { D153_PRED, { INTRA_FRAME, NONE } },
363 { D63_PRED, { INTRA_FRAME, NONE } },
364 { D117_PRED, { INTRA_FRAME, NONE } },
365 { D45_PRED, { INTRA_FRAME, NONE } },
366
367#if CONFIG_EXT_INTER
368 { ZEROMV, { LAST_FRAME, INTRA_FRAME } },
369 { NEARESTMV, { LAST_FRAME, INTRA_FRAME } },
370 { NEARMV, { LAST_FRAME, INTRA_FRAME } },
371 { NEWMV, { LAST_FRAME, INTRA_FRAME } },
372
373#if CONFIG_EXT_REFS
374 { ZEROMV, { LAST2_FRAME, INTRA_FRAME } },
375 { NEARESTMV, { LAST2_FRAME, INTRA_FRAME } },
376 { NEARMV, { LAST2_FRAME, INTRA_FRAME } },
377 { NEWMV, { LAST2_FRAME, INTRA_FRAME } },
378
379 { ZEROMV, { LAST3_FRAME, INTRA_FRAME } },
380 { NEARESTMV, { LAST3_FRAME, INTRA_FRAME } },
381 { NEARMV, { LAST3_FRAME, INTRA_FRAME } },
382 { NEWMV, { LAST3_FRAME, INTRA_FRAME } },
383#endif // CONFIG_EXT_REFS
384
385 { ZEROMV, { GOLDEN_FRAME, INTRA_FRAME } },
386 { NEARESTMV, { GOLDEN_FRAME, INTRA_FRAME } },
387 { NEARMV, { GOLDEN_FRAME, INTRA_FRAME } },
388 { NEWMV, { GOLDEN_FRAME, INTRA_FRAME } },
389
390#if CONFIG_EXT_REFS
391 { ZEROMV, { BWDREF_FRAME, INTRA_FRAME } },
392 { NEARESTMV, { BWDREF_FRAME, INTRA_FRAME } },
393 { NEARMV, { BWDREF_FRAME, INTRA_FRAME } },
394 { NEWMV, { BWDREF_FRAME, INTRA_FRAME } },
395#endif // CONFIG_EXT_REFS
396
397 { ZEROMV, { ALTREF_FRAME, INTRA_FRAME } },
398 { NEARESTMV, { ALTREF_FRAME, INTRA_FRAME } },
399 { NEARMV, { ALTREF_FRAME, INTRA_FRAME } },
400 { NEWMV, { ALTREF_FRAME, INTRA_FRAME } },
401#endif // CONFIG_EXT_INTER
402};
403
Yaowu Xuf883b422016-08-30 14:01:10 -0700404static const REF_DEFINITION av1_ref_order[MAX_REFS] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700405 { { LAST_FRAME, NONE } },
406#if CONFIG_EXT_REFS
407 { { LAST2_FRAME, NONE } }, { { LAST3_FRAME, NONE } },
408 { { BWDREF_FRAME, NONE } },
409#endif // CONFIG_EXT_REFS
410 { { GOLDEN_FRAME, NONE } }, { { ALTREF_FRAME, NONE } },
411
412 { { LAST_FRAME, ALTREF_FRAME } },
413#if CONFIG_EXT_REFS
414 { { LAST2_FRAME, ALTREF_FRAME } }, { { LAST3_FRAME, ALTREF_FRAME } },
415#endif // CONFIG_EXT_REFS
416 { { GOLDEN_FRAME, ALTREF_FRAME } },
417
418#if CONFIG_EXT_REFS
419 { { LAST_FRAME, BWDREF_FRAME } }, { { LAST2_FRAME, BWDREF_FRAME } },
420 { { LAST3_FRAME, BWDREF_FRAME } }, { { GOLDEN_FRAME, BWDREF_FRAME } },
421#endif // CONFIG_EXT_REFS
422
423 { { INTRA_FRAME, NONE } },
424};
425
hui su5db97432016-10-14 16:10:14 -0700426#if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700427static INLINE int write_uniform_cost(int n, int v) {
428 int l = get_unsigned_bits(n), m = (1 << l) - n;
429 if (l == 0) return 0;
430 if (v < m)
Yaowu Xuf883b422016-08-30 14:01:10 -0700431 return (l - 1) * av1_cost_bit(128, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700432 else
Yaowu Xuf883b422016-08-30 14:01:10 -0700433 return l * av1_cost_bit(128, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700434}
hui su5db97432016-10-14 16:10:14 -0700435#endif // CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700436
437// constants for prune 1 and prune 2 decision boundaries
438#define FAST_EXT_TX_CORR_MID 0.0
439#define FAST_EXT_TX_EDST_MID 0.1
440#define FAST_EXT_TX_CORR_MARGIN 0.5
441#define FAST_EXT_TX_EDST_MARGIN 0.3
442
443static const TX_TYPE_1D vtx_tab[TX_TYPES] = {
444 DCT_1D, ADST_1D, DCT_1D, ADST_1D,
445#if CONFIG_EXT_TX
446 FLIPADST_1D, DCT_1D, FLIPADST_1D, ADST_1D, FLIPADST_1D, IDTX_1D,
447 DCT_1D, IDTX_1D, ADST_1D, IDTX_1D, FLIPADST_1D, IDTX_1D,
448#endif // CONFIG_EXT_TX
449};
450
451static const TX_TYPE_1D htx_tab[TX_TYPES] = {
452 DCT_1D, DCT_1D, ADST_1D, ADST_1D,
453#if CONFIG_EXT_TX
454 DCT_1D, FLIPADST_1D, FLIPADST_1D, FLIPADST_1D, ADST_1D, IDTX_1D,
455 IDTX_1D, DCT_1D, IDTX_1D, ADST_1D, IDTX_1D, FLIPADST_1D,
456#endif // CONFIG_EXT_TX
457};
458
Yaowu Xuf883b422016-08-30 14:01:10 -0700459static void get_energy_distribution_fine(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700460 uint8_t *src, int src_stride,
461 uint8_t *dst, int dst_stride,
462 double *hordist, double *verdist) {
Jingning Han73db4ac2016-11-30 11:23:27 -0800463 int bw = block_size_wide[bsize];
464 int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700465 unsigned int esq[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
466 unsigned int var[16];
467 double total = 0;
468
469 const int f_index = bsize - BLOCK_16X16;
470 if (f_index < 0) {
471 int i, j, index;
472 int w_shift = bw == 8 ? 1 : 2;
473 int h_shift = bh == 8 ? 1 : 2;
Yaowu Xuf883b422016-08-30 14:01:10 -0700474#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700475 if (cpi->common.use_highbitdepth) {
476 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
477 uint16_t *dst16 = CONVERT_TO_SHORTPTR(dst);
478 for (i = 0; i < bh; ++i)
479 for (j = 0; j < bw; ++j) {
480 index = (j >> w_shift) + ((i >> h_shift) << 2);
481 esq[index] +=
482 (src16[j + i * src_stride] - dst16[j + i * dst_stride]) *
483 (src16[j + i * src_stride] - dst16[j + i * dst_stride]);
484 }
485 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700486#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700487
488 for (i = 0; i < bh; ++i)
489 for (j = 0; j < bw; ++j) {
490 index = (j >> w_shift) + ((i >> h_shift) << 2);
491 esq[index] += (src[j + i * src_stride] - dst[j + i * dst_stride]) *
492 (src[j + i * src_stride] - dst[j + i * dst_stride]);
493 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700494#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700495 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700496#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700497 } else {
498 var[0] = cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[0]);
499 var[1] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
500 dst_stride, &esq[1]);
501 var[2] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
502 dst_stride, &esq[2]);
503 var[3] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
504 dst + 3 * bw / 4, dst_stride, &esq[3]);
505 src += bh / 4 * src_stride;
506 dst += bh / 4 * dst_stride;
507
508 var[4] = cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[4]);
509 var[5] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
510 dst_stride, &esq[5]);
511 var[6] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
512 dst_stride, &esq[6]);
513 var[7] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
514 dst + 3 * bw / 4, dst_stride, &esq[7]);
515 src += bh / 4 * src_stride;
516 dst += bh / 4 * dst_stride;
517
518 var[8] = cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[8]);
519 var[9] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
520 dst_stride, &esq[9]);
521 var[10] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
522 dst_stride, &esq[10]);
523 var[11] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
524 dst + 3 * bw / 4, dst_stride, &esq[11]);
525 src += bh / 4 * src_stride;
526 dst += bh / 4 * dst_stride;
527
528 var[12] =
529 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[12]);
530 var[13] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
531 dst_stride, &esq[13]);
532 var[14] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
533 dst_stride, &esq[14]);
534 var[15] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
535 dst + 3 * bw / 4, dst_stride, &esq[15]);
536 }
537
538 total = esq[0] + esq[1] + esq[2] + esq[3] + esq[4] + esq[5] + esq[6] +
539 esq[7] + esq[8] + esq[9] + esq[10] + esq[11] + esq[12] + esq[13] +
540 esq[14] + esq[15];
541 if (total > 0) {
542 const double e_recip = 1.0 / total;
543 hordist[0] =
544 ((double)esq[0] + (double)esq[4] + (double)esq[8] + (double)esq[12]) *
545 e_recip;
546 hordist[1] =
547 ((double)esq[1] + (double)esq[5] + (double)esq[9] + (double)esq[13]) *
548 e_recip;
549 hordist[2] =
550 ((double)esq[2] + (double)esq[6] + (double)esq[10] + (double)esq[14]) *
551 e_recip;
552 verdist[0] =
553 ((double)esq[0] + (double)esq[1] + (double)esq[2] + (double)esq[3]) *
554 e_recip;
555 verdist[1] =
556 ((double)esq[4] + (double)esq[5] + (double)esq[6] + (double)esq[7]) *
557 e_recip;
558 verdist[2] =
559 ((double)esq[8] + (double)esq[9] + (double)esq[10] + (double)esq[11]) *
560 e_recip;
561 } else {
562 hordist[0] = verdist[0] = 0.25;
563 hordist[1] = verdist[1] = 0.25;
564 hordist[2] = verdist[2] = 0.25;
565 }
566 (void)var[0];
567 (void)var[1];
568 (void)var[2];
569 (void)var[3];
570 (void)var[4];
571 (void)var[5];
572 (void)var[6];
573 (void)var[7];
574 (void)var[8];
575 (void)var[9];
576 (void)var[10];
577 (void)var[11];
578 (void)var[12];
579 (void)var[13];
580 (void)var[14];
581 (void)var[15];
582}
583
Yaowu Xuf883b422016-08-30 14:01:10 -0700584static int adst_vs_flipadst(const AV1_COMP *cpi, BLOCK_SIZE bsize, uint8_t *src,
585 int src_stride, uint8_t *dst, int dst_stride,
586 double *hdist, double *vdist) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700587 int prune_bitmask = 0;
588 double svm_proj_h = 0, svm_proj_v = 0;
589 get_energy_distribution_fine(cpi, bsize, src, src_stride, dst, dst_stride,
590 hdist, vdist);
591
592 svm_proj_v = vdist[0] * ADST_FLIP_SVM[0] + vdist[1] * ADST_FLIP_SVM[1] +
593 vdist[2] * ADST_FLIP_SVM[2] + ADST_FLIP_SVM[3];
594 svm_proj_h = hdist[0] * ADST_FLIP_SVM[4] + hdist[1] * ADST_FLIP_SVM[5] +
595 hdist[2] * ADST_FLIP_SVM[6] + ADST_FLIP_SVM[7];
596 if (svm_proj_v > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
597 prune_bitmask |= 1 << FLIPADST_1D;
598 else if (svm_proj_v < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
599 prune_bitmask |= 1 << ADST_1D;
600
601 if (svm_proj_h > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
602 prune_bitmask |= 1 << (FLIPADST_1D + 8);
603 else if (svm_proj_h < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
604 prune_bitmask |= 1 << (ADST_1D + 8);
605
606 return prune_bitmask;
607}
608
609#if CONFIG_EXT_TX
610static void get_horver_correlation(int16_t *diff, int stride, int w, int h,
611 double *hcorr, double *vcorr) {
612 // Returns hor/ver correlation coefficient
613 const int num = (h - 1) * (w - 1);
614 double num_r;
615 int i, j;
616 int64_t xy_sum = 0, xz_sum = 0;
617 int64_t x_sum = 0, y_sum = 0, z_sum = 0;
618 int64_t x2_sum = 0, y2_sum = 0, z2_sum = 0;
619 double x_var_n, y_var_n, z_var_n, xy_var_n, xz_var_n;
620 *hcorr = *vcorr = 1;
621
622 assert(num > 0);
623 num_r = 1.0 / num;
624 for (i = 1; i < h; ++i) {
625 for (j = 1; j < w; ++j) {
626 const int16_t x = diff[i * stride + j];
627 const int16_t y = diff[i * stride + j - 1];
628 const int16_t z = diff[(i - 1) * stride + j];
629 xy_sum += x * y;
630 xz_sum += x * z;
631 x_sum += x;
632 y_sum += y;
633 z_sum += z;
634 x2_sum += x * x;
635 y2_sum += y * y;
636 z2_sum += z * z;
637 }
638 }
639 x_var_n = x2_sum - (x_sum * x_sum) * num_r;
640 y_var_n = y2_sum - (y_sum * y_sum) * num_r;
641 z_var_n = z2_sum - (z_sum * z_sum) * num_r;
642 xy_var_n = xy_sum - (x_sum * y_sum) * num_r;
643 xz_var_n = xz_sum - (x_sum * z_sum) * num_r;
644 if (x_var_n > 0 && y_var_n > 0) {
645 *hcorr = xy_var_n / sqrt(x_var_n * y_var_n);
646 *hcorr = *hcorr < 0 ? 0 : *hcorr;
647 }
648 if (x_var_n > 0 && z_var_n > 0) {
649 *vcorr = xz_var_n / sqrt(x_var_n * z_var_n);
650 *vcorr = *vcorr < 0 ? 0 : *vcorr;
651 }
652}
653
654int dct_vs_idtx(int16_t *diff, int stride, int w, int h, double *hcorr,
655 double *vcorr) {
656 int prune_bitmask = 0;
657 get_horver_correlation(diff, stride, w, h, hcorr, vcorr);
658
659 if (*vcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
660 prune_bitmask |= 1 << IDTX_1D;
661 else if (*vcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
662 prune_bitmask |= 1 << DCT_1D;
663
664 if (*hcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
665 prune_bitmask |= 1 << (IDTX_1D + 8);
666 else if (*hcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
667 prune_bitmask |= 1 << (DCT_1D + 8);
668 return prune_bitmask;
669}
670
671// Performance drop: 0.5%, Speed improvement: 24%
Yaowu Xuf883b422016-08-30 14:01:10 -0700672static int prune_two_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700673 MACROBLOCK *x, MACROBLOCKD *xd, int adst_flipadst,
674 int dct_idtx) {
675 struct macroblock_plane *const p = &x->plane[0];
676 struct macroblockd_plane *const pd = &xd->plane[0];
677 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
678 const int bw = 4 << (b_width_log2_lookup[bs]);
679 const int bh = 4 << (b_height_log2_lookup[bs]);
680 double hdist[3] = { 0, 0, 0 }, vdist[3] = { 0, 0, 0 };
681 double hcorr, vcorr;
682 int prune = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700683 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700684
685 if (adst_flipadst)
686 prune |= adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride,
687 pd->dst.buf, pd->dst.stride, hdist, vdist);
688 if (dct_idtx) prune |= dct_vs_idtx(p->src_diff, bw, bw, bh, &hcorr, &vcorr);
689
690 return prune;
691}
692#endif // CONFIG_EXT_TX
693
694// Performance drop: 0.3%, Speed improvement: 5%
Yaowu Xuf883b422016-08-30 14:01:10 -0700695static int prune_one_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700696 MACROBLOCK *x, MACROBLOCKD *xd) {
697 struct macroblock_plane *const p = &x->plane[0];
698 struct macroblockd_plane *const pd = &xd->plane[0];
699 double hdist[3] = { 0, 0, 0 }, vdist[3] = { 0, 0, 0 };
Yaowu Xuf883b422016-08-30 14:01:10 -0700700 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700701 return adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride, pd->dst.buf,
702 pd->dst.stride, hdist, vdist);
703}
704
Yaowu Xuf883b422016-08-30 14:01:10 -0700705static int prune_tx_types(const AV1_COMP *cpi, BLOCK_SIZE bsize, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700706 MACROBLOCKD *xd, int tx_set) {
707#if CONFIG_EXT_TX
708 const int *tx_set_1D = ext_tx_used_inter_1D[tx_set];
709#else
710 const int tx_set_1D[TX_TYPES_1D] = { 0 };
711#endif
712
713 switch (cpi->sf.tx_type_search.prune_mode) {
714 case NO_PRUNE: return 0; break;
715 case PRUNE_ONE:
Sarah Parker68a26b62016-10-28 13:19:33 -0700716 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700717 return 0;
718 return prune_one_for_sby(cpi, bsize, x, xd);
719 break;
720#if CONFIG_EXT_TX
721 case PRUNE_TWO:
Sarah Parker68a26b62016-10-28 13:19:33 -0700722 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D])) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700723 if (!(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D])) return 0;
724 return prune_two_for_sby(cpi, bsize, x, xd, 0, 1);
725 }
Sarah Parker68a26b62016-10-28 13:19:33 -0700726 if ((tx_set >= 0) && !(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700727 return prune_two_for_sby(cpi, bsize, x, xd, 1, 0);
728 return prune_two_for_sby(cpi, bsize, x, xd, 1, 1);
729 break;
730#endif
731 }
732 assert(0);
733 return 0;
734}
735
736static int do_tx_type_search(TX_TYPE tx_type, int prune) {
737// TODO(sarahparker) implement for non ext tx
738#if CONFIG_EXT_TX
739 return !(((prune >> vtx_tab[tx_type]) & 1) |
740 ((prune >> (htx_tab[tx_type] + 8)) & 1));
741#else
742 // temporary to avoid compiler warnings
743 (void)vtx_tab;
744 (void)htx_tab;
745 (void)tx_type;
746 (void)prune;
747 return 1;
748#endif
749}
750
Yaowu Xuf883b422016-08-30 14:01:10 -0700751static void model_rd_from_sse(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700752 const MACROBLOCKD *const xd, BLOCK_SIZE bsize,
753 int plane, int64_t sse, int *rate,
754 int64_t *dist) {
755 const struct macroblockd_plane *const pd = &xd->plane[plane];
756 const int dequant_shift =
Yaowu Xuf883b422016-08-30 14:01:10 -0700757#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700758 (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd - 5 :
Yaowu Xuf883b422016-08-30 14:01:10 -0700759#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700760 3;
761
762 // Fast approximate the modelling function.
763 if (cpi->sf.simple_model_rd_from_var) {
764 const int64_t square_error = sse;
765 int quantizer = (pd->dequant[1] >> dequant_shift);
766
767 if (quantizer < 120)
768 *rate = (int)((square_error * (280 - quantizer)) >>
Yaowu Xuf883b422016-08-30 14:01:10 -0700769 (16 - AV1_PROB_COST_SHIFT));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700770 else
771 *rate = 0;
772 *dist = (square_error * quantizer) >> 8;
773 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700774 av1_model_rd_from_var_lapndz(sse, num_pels_log2_lookup[bsize],
775 pd->dequant[1] >> dequant_shift, rate, dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700776 }
777
778 *dist <<= 4;
779}
780
Yaowu Xuf883b422016-08-30 14:01:10 -0700781static void model_rd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700782 MACROBLOCK *x, MACROBLOCKD *xd, int plane_from,
783 int plane_to, int *out_rate_sum,
784 int64_t *out_dist_sum, int *skip_txfm_sb,
785 int64_t *skip_sse_sb) {
786 // Note our transform coeffs are 8 times an orthogonal transform.
787 // Hence quantizer step is also 8 times. To get effective quantizer
788 // we need to divide by 8 before sending to modeling function.
789 int plane;
790 const int ref = xd->mi[0]->mbmi.ref_frame[0];
791
792 int64_t rate_sum = 0;
793 int64_t dist_sum = 0;
794 int64_t total_sse = 0;
795
796 x->pred_sse[ref] = 0;
797
798 for (plane = plane_from; plane <= plane_to; ++plane) {
799 struct macroblock_plane *const p = &x->plane[plane];
800 struct macroblockd_plane *const pd = &xd->plane[plane];
801 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
802
803 unsigned int sse;
804 int rate;
805 int64_t dist;
806
807 // TODO(geza): Write direct sse functions that do not compute
808 // variance as well.
809 cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride, pd->dst.buf, pd->dst.stride,
810 &sse);
811
812 if (plane == 0) x->pred_sse[ref] = sse;
813
814 total_sse += sse;
815
816 model_rd_from_sse(cpi, xd, bs, plane, sse, &rate, &dist);
817
818 rate_sum += rate;
819 dist_sum += dist;
820 }
821
822 *skip_txfm_sb = total_sse == 0;
823 *skip_sse_sb = total_sse << 4;
824 *out_rate_sum = (int)rate_sum;
825 *out_dist_sum = dist_sum;
826}
827
Yushin Cho77bba8d2016-11-04 16:36:56 -0700828#if CONFIG_PVQ
829// Without PVQ, av1_block_error_c() return two kind of errors,
830// 1) reconstruction (i.e. decoded) error and
831// 2) Squared sum of transformed residue (i.e. 'coeff')
832// However, if PVQ is enabled, coeff does not keep the transformed residue
833// but instead a transformed original is kept.
834// Hence, new parameter ref vector (i.e. transformed predicted signal)
835// is required to derive the residue signal,
836// i.e. coeff - ref = residue (all transformed).
837
838// TODO(yushin) : Since 4x4 case does not need ssz, better to refactor into
839// a separate function that does not do the extra computations for ssz.
840int64_t av1_block_error2_c(const tran_low_t *coeff, const tran_low_t *dqcoeff,
841 const tran_low_t *ref, intptr_t block_size,
842 int64_t *ssz) {
843 int64_t error;
844
845 // Use the existing sse codes for calculating distortion of decoded signal:
846 // i.e. (orig - decoded)^2
847 error = av1_block_error_fp(coeff, dqcoeff, block_size);
848 // prediction residue^2 = (orig - ref)^2
849 *ssz = av1_block_error_fp(coeff, ref, block_size);
850
851 return error;
852}
853#endif
854
Yaowu Xuf883b422016-08-30 14:01:10 -0700855int64_t av1_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff,
856 intptr_t block_size, int64_t *ssz) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700857 int i;
858 int64_t error = 0, sqcoeff = 0;
859
860 for (i = 0; i < block_size; i++) {
861 const int diff = coeff[i] - dqcoeff[i];
862 error += diff * diff;
863 sqcoeff += coeff[i] * coeff[i];
864 }
865
866 *ssz = sqcoeff;
867 return error;
868}
869
Yaowu Xuf883b422016-08-30 14:01:10 -0700870int64_t av1_block_error_fp_c(const int16_t *coeff, const int16_t *dqcoeff,
871 int block_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700872 int i;
873 int64_t error = 0;
874
875 for (i = 0; i < block_size; i++) {
876 const int diff = coeff[i] - dqcoeff[i];
877 error += diff * diff;
878 }
879
880 return error;
881}
882
Yaowu Xuf883b422016-08-30 14:01:10 -0700883#if CONFIG_AOM_HIGHBITDEPTH
884int64_t av1_highbd_block_error_c(const tran_low_t *coeff,
885 const tran_low_t *dqcoeff, intptr_t block_size,
886 int64_t *ssz, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700887 int i;
888 int64_t error = 0, sqcoeff = 0;
889 int shift = 2 * (bd - 8);
890 int rounding = shift > 0 ? 1 << (shift - 1) : 0;
891
892 for (i = 0; i < block_size; i++) {
893 const int64_t diff = coeff[i] - dqcoeff[i];
894 error += diff * diff;
895 sqcoeff += (int64_t)coeff[i] * (int64_t)coeff[i];
896 }
897 assert(error >= 0 && sqcoeff >= 0);
898 error = (error + rounding) >> shift;
899 sqcoeff = (sqcoeff + rounding) >> shift;
900
901 *ssz = sqcoeff;
902 return error;
903}
Yaowu Xuf883b422016-08-30 14:01:10 -0700904#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700905
Yushin Cho77bba8d2016-11-04 16:36:56 -0700906#if !CONFIG_PVQ
Debargha Mukherjeeceebb702016-10-11 05:26:50 -0700907/* The trailing '0' is a terminator which is used inside av1_cost_coeffs() to
Yaowu Xuc27fc142016-08-22 16:08:15 -0700908 * decide whether to include cost of a trailing EOB node or not (i.e. we
909 * can skip this if the last coefficient in this transform block, e.g. the
910 * 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block,
911 * were non-zero). */
Angie Chiang22ba7512016-10-20 17:10:33 -0700912int av1_cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
913 int block, int coeff_ctx, TX_SIZE tx_size,
914 const int16_t *scan, const int16_t *nb,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -0700915 int use_fast_coef_costing) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700916 MACROBLOCKD *const xd = &x->e_mbd;
917 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
918 const struct macroblock_plane *p = &x->plane[plane];
919 const struct macroblockd_plane *pd = &xd->plane[plane];
920 const PLANE_TYPE type = pd->plane_type;
921 const uint16_t *band_count = &band_count_table[tx_size][1];
922 const int eob = p->eobs[block];
923 const tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
924 const int tx_size_ctx = txsize_sqr_map[tx_size];
925 unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
926 x->token_costs[tx_size_ctx][type][is_inter_block(mbmi)];
927 uint8_t token_cache[MAX_TX_SQUARE];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700928 int pt = coeff_ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700929 int c, cost;
Yaowu Xuf883b422016-08-30 14:01:10 -0700930#if CONFIG_AOM_HIGHBITDEPTH
931 const int *cat6_high_cost = av1_get_high_cost_table(xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700932#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700933 const int *cat6_high_cost = av1_get_high_cost_table(8);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700934#endif
935
936#if !CONFIG_VAR_TX && !CONFIG_SUPERTX
937 // Check for consistency of tx_size with mode info
938 assert(type == PLANE_TYPE_Y ? mbmi->tx_size == tx_size
939 : get_uv_tx_size(mbmi, pd) == tx_size);
940#endif // !CONFIG_VAR_TX && !CONFIG_SUPERTX
Angie Chiang22ba7512016-10-20 17:10:33 -0700941 (void)cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700942
943 if (eob == 0) {
944 // single eob token
945 cost = token_costs[0][0][pt][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700946 } else {
947 if (use_fast_coef_costing) {
948 int band_left = *band_count++;
949
950 // dc token
951 int v = qcoeff[0];
952 int16_t prev_t;
Yaowu Xuf883b422016-08-30 14:01:10 -0700953 cost = av1_get_token_cost(v, &prev_t, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700954 cost += (*token_costs)[0][pt][prev_t];
955
Yaowu Xuf883b422016-08-30 14:01:10 -0700956 token_cache[0] = av1_pt_energy_class[prev_t];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700957 ++token_costs;
958
959 // ac tokens
960 for (c = 1; c < eob; c++) {
961 const int rc = scan[c];
962 int16_t t;
963
964 v = qcoeff[rc];
Yaowu Xuf883b422016-08-30 14:01:10 -0700965 cost += av1_get_token_cost(v, &t, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700966 cost += (*token_costs)[!prev_t][!prev_t][t];
967 prev_t = t;
968 if (!--band_left) {
969 band_left = *band_count++;
970 ++token_costs;
971 }
972 }
973
974 // eob token
975 if (band_left) cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
976
977 } else { // !use_fast_coef_costing
978 int band_left = *band_count++;
979
980 // dc token
981 int v = qcoeff[0];
982 int16_t tok;
983 unsigned int(*tok_cost_ptr)[COEFF_CONTEXTS][ENTROPY_TOKENS];
Yaowu Xuf883b422016-08-30 14:01:10 -0700984 cost = av1_get_token_cost(v, &tok, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700985 cost += (*token_costs)[0][pt][tok];
986
Yaowu Xuf883b422016-08-30 14:01:10 -0700987 token_cache[0] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700988 ++token_costs;
989
990 tok_cost_ptr = &((*token_costs)[!tok]);
991
992 // ac tokens
993 for (c = 1; c < eob; c++) {
994 const int rc = scan[c];
995
996 v = qcoeff[rc];
Yaowu Xuf883b422016-08-30 14:01:10 -0700997 cost += av1_get_token_cost(v, &tok, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700998 pt = get_coef_context(nb, token_cache, c);
999 cost += (*tok_cost_ptr)[pt][tok];
Yaowu Xuf883b422016-08-30 14:01:10 -07001000 token_cache[rc] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001001 if (!--band_left) {
1002 band_left = *band_count++;
1003 ++token_costs;
1004 }
1005 tok_cost_ptr = &((*token_costs)[!tok]);
1006 }
1007
1008 // eob token
1009 if (band_left) {
1010 pt = get_coef_context(nb, token_cache, c);
1011 cost += (*token_costs)[0][pt][EOB_TOKEN];
1012 }
1013 }
1014 }
1015
Yaowu Xuc27fc142016-08-22 16:08:15 -07001016 return cost;
1017}
Yushin Cho77bba8d2016-11-04 16:36:56 -07001018#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001019
Yaowu Xuf883b422016-08-30 14:01:10 -07001020static void dist_block(const AV1_COMP *cpi, MACROBLOCK *x, int plane, int block,
1021 int blk_row, int blk_col, TX_SIZE tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001022 int64_t *out_dist, int64_t *out_sse) {
1023 MACROBLOCKD *const xd = &x->e_mbd;
1024 const struct macroblock_plane *const p = &x->plane[plane];
1025 const struct macroblockd_plane *const pd = &xd->plane[plane];
1026 if (cpi->sf.use_transform_domain_distortion) {
1027 // Transform domain distortion computation is more accurate as it does
1028 // not involve an inverse transform, but it is less accurate.
Jingning Hanb9c57272016-10-25 10:15:39 -07001029 const int buffer_length = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001030 int64_t this_sse;
Debargha Mukherjee0e119122016-11-04 12:10:23 -07001031 int shift = (MAX_TX_SCALE - get_tx_scale(tx_size)) * 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001032 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
1033 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001034#if CONFIG_PVQ
Yaowu Xud6ea71c2016-11-07 10:24:14 -08001035 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001036#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001037#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001038 const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
Jingning Hanb9c57272016-10-25 10:15:39 -07001039 *out_dist =
1040 av1_highbd_block_error(coeff, dqcoeff, buffer_length, &this_sse, bd) >>
1041 shift;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001042#elif CONFIG_PVQ
1043 *out_dist = av1_block_error2_c(coeff, dqcoeff, ref_coeff, buffer_length,
1044 &this_sse) >>
1045 shift;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001046#else
1047 *out_dist =
Jingning Hanb9c57272016-10-25 10:15:39 -07001048 av1_block_error(coeff, dqcoeff, buffer_length, &this_sse) >> shift;
Yaowu Xuf883b422016-08-30 14:01:10 -07001049#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001050 *out_sse = this_sse >> shift;
1051 } else {
1052 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Jingning Hanb9c57272016-10-25 10:15:39 -07001053 const int bsw = block_size_wide[tx_bsize];
1054 const int bsh = block_size_high[tx_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001055 const int src_stride = x->plane[plane].src.stride;
1056 const int dst_stride = xd->plane[plane].dst.stride;
Jingning Hanb9c57272016-10-25 10:15:39 -07001057 // Scale the transform block index to pixel unit.
1058 const int src_idx = (blk_row * src_stride + blk_col)
1059 << tx_size_wide_log2[0];
1060 const int dst_idx = (blk_row * dst_stride + blk_col)
1061 << tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001062 const uint8_t *src = &x->plane[plane].src.buf[src_idx];
1063 const uint8_t *dst = &xd->plane[plane].dst.buf[dst_idx];
1064 const tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1065 const uint16_t eob = p->eobs[block];
1066
1067 unsigned int tmp;
1068
1069 assert(cpi != NULL);
Jingning Hanb9c57272016-10-25 10:15:39 -07001070 assert(tx_size_wide_log2[0] == tx_size_high_log2[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001071
1072 cpi->fn_ptr[tx_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
1073 *out_sse = (int64_t)tmp * 16;
1074
1075 if (eob) {
1076 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Yaowu Xuf883b422016-08-30 14:01:10 -07001077#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001078 DECLARE_ALIGNED(16, uint16_t, recon16[MAX_TX_SQUARE]);
1079 uint8_t *recon = (uint8_t *)recon16;
1080#else
1081 DECLARE_ALIGNED(16, uint8_t, recon[MAX_TX_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07001082#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001083
1084 const PLANE_TYPE plane_type = plane == 0 ? PLANE_TYPE_Y : PLANE_TYPE_UV;
1085
1086 INV_TXFM_PARAM inv_txfm_param;
1087
1088 inv_txfm_param.tx_type = get_tx_type(plane_type, xd, block, tx_size);
1089 inv_txfm_param.tx_size = tx_size;
1090 inv_txfm_param.eob = eob;
1091 inv_txfm_param.lossless = xd->lossless[mbmi->segment_id];
1092
Yaowu Xuf883b422016-08-30 14:01:10 -07001093#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001094 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1095 recon = CONVERT_TO_BYTEPTR(recon);
1096 inv_txfm_param.bd = xd->bd;
Yaowu Xuf883b422016-08-30 14:01:10 -07001097 aom_highbd_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001098 NULL, 0, bsw, bsh, xd->bd);
1099 highbd_inv_txfm_add(dqcoeff, recon, MAX_TX_SIZE, &inv_txfm_param);
1100 } else
Yaowu Xuf883b422016-08-30 14:01:10 -07001101#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001102 {
Yushin Cho721868c2016-11-14 16:04:33 +09001103#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -07001104 aom_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001105 bsw, bsh);
Yushin Cho721868c2016-11-14 16:04:33 +09001106#else
1107 int i, j;
1108
1109 for (j = 0; j < bsh; j++)
1110 for (i = 0; i < bsw; i++) recon[j * MAX_TX_SIZE + i] = 0;
1111#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001112 inv_txfm_add(dqcoeff, recon, MAX_TX_SIZE, &inv_txfm_param);
1113 }
1114
1115 cpi->fn_ptr[tx_bsize].vf(src, src_stride, recon, MAX_TX_SIZE, &tmp);
1116 }
1117
1118 *out_dist = (int64_t)tmp * 16;
1119 }
1120}
1121
Yushin Cho77bba8d2016-11-04 16:36:56 -07001122#if !CONFIG_PVQ
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001123static int rate_block(int plane, int block, int coeff_ctx, TX_SIZE tx_size,
Debargha Mukherjee29630542016-09-06 13:15:31 -07001124 struct rdcost_block_args *args) {
Angie Chiang22ba7512016-10-20 17:10:33 -07001125 return av1_cost_coeffs(&args->cpi->common, args->x, plane, block, coeff_ctx,
1126 tx_size, args->scan_order->scan,
1127 args->scan_order->neighbors,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001128 args->use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001129}
Yushin Cho77bba8d2016-11-04 16:36:56 -07001130#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001131
1132static uint64_t sum_squares_2d(const int16_t *diff, int diff_stride,
1133 TX_SIZE tx_size) {
1134 uint64_t sse;
1135 switch (tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001136 case TX_4X8:
Yaowu Xuf883b422016-08-30 14:01:10 -07001137 sse = aom_sum_squares_2d_i16(diff, diff_stride, 4) +
1138 aom_sum_squares_2d_i16(diff + 4 * diff_stride, diff_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001139 break;
1140 case TX_8X4:
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, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001143 break;
1144 case TX_8X16:
Yaowu Xuf883b422016-08-30 14:01:10 -07001145 sse = aom_sum_squares_2d_i16(diff, diff_stride, 8) +
1146 aom_sum_squares_2d_i16(diff + 8 * diff_stride, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001147 break;
1148 case TX_16X8:
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, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001151 break;
1152 case TX_16X32:
Yaowu Xuf883b422016-08-30 14:01:10 -07001153 sse = aom_sum_squares_2d_i16(diff, diff_stride, 16) +
1154 aom_sum_squares_2d_i16(diff + 16 * diff_stride, diff_stride, 16);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001155 break;
1156 case TX_32X16:
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, 16);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001159 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001160 default:
1161 assert(tx_size < TX_SIZES);
Jingning Hanc598cf82016-10-25 10:37:34 -07001162 sse = aom_sum_squares_2d_i16(diff, diff_stride, tx_size_wide[tx_size]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001163 break;
1164 }
1165 return sse;
1166}
1167
1168static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
1169 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
1170 struct rdcost_block_args *args = arg;
1171 MACROBLOCK *const x = args->x;
1172 MACROBLOCKD *const xd = &x->e_mbd;
1173 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -07001174 const AV1_COMMON *cm = &args->cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001175 int64_t rd1, rd2, rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001176 int coeff_ctx = combine_entropy_contexts(*(args->t_above + blk_col),
1177 *(args->t_left + blk_row));
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001178 RD_STATS this_rd_stats;
1179 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001180
1181 if (args->exit_early) return;
1182
1183 if (!is_inter_block(mbmi)) {
Urvang Joshi454280d2016-10-14 16:51:44 -07001184 struct encode_b_args b_args = {
Angie Chiangff6d8902016-10-21 11:02:09 -07001185 (AV1_COMMON *)cm, x, NULL, &mbmi->skip, args->t_above, args->t_left, 1
Yaowu Xuc27fc142016-08-22 16:08:15 -07001186 };
Yaowu Xuf883b422016-08-30 14:01:10 -07001187 av1_encode_block_intra(plane, block, blk_row, blk_col, plane_bsize, tx_size,
Urvang Joshi454280d2016-10-14 16:51:44 -07001188 &b_args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001189
1190 if (args->cpi->sf.use_transform_domain_distortion) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001191 dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size,
1192 &this_rd_stats.dist, &this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001193 } else {
1194 // Note that the encode block_intra call above already calls
1195 // inv_txfm_add, so we can't just call dist_block here.
1196 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Yaowu Xuf883b422016-08-30 14:01:10 -07001197 const aom_variance_fn_t variance = args->cpi->fn_ptr[tx_bsize].vf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001198
1199 const struct macroblock_plane *const p = &x->plane[plane];
1200 const struct macroblockd_plane *const pd = &xd->plane[plane];
1201
1202 const int src_stride = p->src.stride;
1203 const int dst_stride = pd->dst.stride;
Jingning Hanc598cf82016-10-25 10:37:34 -07001204 const int diff_stride = block_size_wide[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001205
1206 const uint8_t *src = &p->src.buf[4 * (blk_row * src_stride + blk_col)];
1207 const uint8_t *dst = &pd->dst.buf[4 * (blk_row * dst_stride + blk_col)];
1208 const int16_t *diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
1209
1210 unsigned int tmp;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001211 this_rd_stats.sse = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001212
Yaowu Xuf883b422016-08-30 14:01:10 -07001213#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001214 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001215 this_rd_stats.sse =
1216 ROUND_POWER_OF_TWO(this_rd_stats.sse, (xd->bd - 8) * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07001217#endif // CONFIG_AOM_HIGHBITDEPTH
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001218 this_rd_stats.sse = this_rd_stats.sse * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001219
1220 variance(src, src_stride, dst, dst_stride, &tmp);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001221 this_rd_stats.dist = (int64_t)tmp * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001222 }
1223 } else {
1224// full forward transform and quantization
1225#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001226 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1227 coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001228#else
Angie Chiangff6d8902016-10-21 11:02:09 -07001229 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001230 coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001231#endif // CONFIG_NEW_QUANT
Yushin Cho721868c2016-11-14 16:04:33 +09001232#if !CONFIG_PVQ
Jingning Handb4c9ba2016-11-30 10:00:25 -08001233 if (x->plane[plane].eobs[block] && !xd->lossless[mbmi->segment_id])
Angie Chiangff6d8902016-10-21 11:02:09 -07001234 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Yushin Cho721868c2016-11-14 16:04:33 +09001235#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001236 dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size,
1237 &this_rd_stats.dist, &this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001238 }
1239
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001240 rd = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001241 if (args->this_rd + rd > args->best_rd) {
1242 args->exit_early = 1;
1243 return;
1244 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001245#if !CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001246 this_rd_stats.rate = rate_block(plane, block, coeff_ctx, tx_size, args);
Angie Chiang3963d632016-11-10 18:41:40 -08001247#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08001248 av1_update_txb_coeff_cost(&this_rd_stats, plane, tx_size, blk_row, blk_col,
1249 this_rd_stats.rate);
1250#endif
Angie Chiang3963d632016-11-10 18:41:40 -08001251
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001252 args->t_above[blk_col] = (x->plane[plane].eobs[block] > 0);
1253 args->t_left[blk_row] = (x->plane[plane].eobs[block] > 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001254#else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001255 this_rd_stats.rate = x->rate;
Yushin Cho721868c2016-11-14 16:04:33 +09001256 args->t_above[blk_col] = !x->pvq_skip[plane];
1257 args->t_left[blk_row] = !x->pvq_skip[plane];
Yushin Cho77bba8d2016-11-04 16:36:56 -07001258#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001259 rd1 = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate, this_rd_stats.dist);
1260 rd2 = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001261
1262 // TODO(jingning): temporarily enabled only for luma component
Yaowu Xuf883b422016-08-30 14:01:10 -07001263 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001264
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001265#if !CONFIG_PVQ
1266 this_rd_stats.skip &= !x->plane[plane].eobs[block];
1267#else
1268 this_rd_stats.skip &= x->pvq_skip[plane];
1269#endif
1270 av1_merge_rd_stats(&args->rd_stats, &this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001271 args->this_rd += rd;
1272
1273 if (args->this_rd > args->best_rd) {
1274 args->exit_early = 1;
1275 return;
1276 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001277}
1278
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001279static void txfm_rd_in_plane(MACROBLOCK *x, const AV1_COMP *cpi,
1280 RD_STATS *rd_stats, int64_t ref_best_rd, int plane,
1281 BLOCK_SIZE bsize, TX_SIZE tx_size,
1282 int use_fast_coef_casting) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001283 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001284 MACROBLOCKD *const xd = &x->e_mbd;
1285 const struct macroblockd_plane *const pd = &xd->plane[plane];
1286 TX_TYPE tx_type;
1287 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001288 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001289 args.x = x;
1290 args.cpi = cpi;
1291 args.best_rd = ref_best_rd;
1292 args.use_fast_coef_costing = use_fast_coef_casting;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001293 av1_init_rd_stats(&args.rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001294
1295 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1296
Yaowu Xuf883b422016-08-30 14:01:10 -07001297 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001298
1299 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001300 args.scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07001301 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001302
Yaowu Xuf883b422016-08-30 14:01:10 -07001303 av1_foreach_transformed_block_in_plane(xd, bsize, plane, block_rd_txfm,
1304 &args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001305 if (args.exit_early) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001306 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001307 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001308 *rd_stats = args.rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001309 }
1310}
1311
1312#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001313void av1_txfm_rd_in_plane_supertx(MACROBLOCK *x, const AV1_COMP *cpi, int *rate,
1314 int64_t *distortion, int *skippable,
1315 int64_t *sse, int64_t ref_best_rd, int plane,
1316 BLOCK_SIZE bsize, TX_SIZE tx_size,
1317 int use_fast_coef_casting) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001318 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001319 MACROBLOCKD *const xd = &x->e_mbd;
1320 const struct macroblockd_plane *const pd = &xd->plane[plane];
1321 struct rdcost_block_args args;
1322 TX_TYPE tx_type;
1323
Yaowu Xuf883b422016-08-30 14:01:10 -07001324 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001325 args.cpi = cpi;
1326 args.x = x;
1327 args.best_rd = ref_best_rd;
1328 args.use_fast_coef_costing = use_fast_coef_casting;
1329
1330#if CONFIG_EXT_TX
1331 assert(tx_size < TX_SIZES);
1332#endif // CONFIG_EXT_TX
1333
1334 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1335
Yaowu Xuf883b422016-08-30 14:01:10 -07001336 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001337
1338 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001339 args.scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07001340 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001341
1342 block_rd_txfm(plane, 0, 0, 0, get_plane_block_size(bsize, pd), tx_size,
1343 &args);
1344
1345 if (args.exit_early) {
1346 *rate = INT_MAX;
1347 *distortion = INT64_MAX;
1348 *sse = INT64_MAX;
1349 *skippable = 0;
1350 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001351 *distortion = args.rd_stats.dist;
1352 *rate = args.rd_stats.rate;
1353 *sse = args.rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001354 *skippable = !x->plane[plane].eobs[0];
1355 }
1356}
1357#endif // CONFIG_SUPERTX
1358
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001359static int64_t txfm_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
1360 RD_STATS *rd_stats, int64_t ref_best_rd, BLOCK_SIZE bs,
1361 TX_TYPE tx_type, int tx_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07001362 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001363 MACROBLOCKD *const xd = &x->e_mbd;
1364 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1365 int64_t rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001366 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001367 int s0, s1;
1368 const int is_inter = is_inter_block(mbmi);
1369 const int tx_size_ctx = get_tx_size_context(xd);
1370 const int tx_size_cat =
1371 is_inter ? inter_tx_size_cat_lookup[bs] : intra_tx_size_cat_lookup[bs];
1372 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
Jingning Hanb0a71302016-10-25 16:28:49 -07001373 const int depth = tx_size_to_depth(coded_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001374 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
Jingning Hanb0a71302016-10-25 16:28:49 -07001375 const int r_tx_size = cpi->tx_size_cost[tx_size_cat][tx_size_ctx][depth];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001376
1377 assert(skip_prob > 0);
1378#if CONFIG_EXT_TX && CONFIG_RECT_TX
1379 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed_bsize(bs)));
1380#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1381
Yaowu Xuf883b422016-08-30 14:01:10 -07001382 s0 = av1_cost_bit(skip_prob, 0);
1383 s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001384
1385 mbmi->tx_type = tx_type;
1386 mbmi->tx_size = tx_size;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001387 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001388 cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001389 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001390#if CONFIG_EXT_TX
1391 if (get_ext_tx_types(tx_size, bs, is_inter) > 1 &&
1392 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
1393 const int ext_tx_set = get_ext_tx_set(tx_size, bs, is_inter);
1394 if (is_inter) {
1395 if (ext_tx_set > 0)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001396 rd_stats->rate +=
clang-format67948d32016-09-07 22:40:40 -07001397 cpi->inter_tx_type_costs[ext_tx_set][txsize_sqr_map[mbmi->tx_size]]
1398 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001399 } else {
1400 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001401 rd_stats->rate += cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size]
1402 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001403 }
1404 }
1405#else
1406 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1407 !FIXED_TX_TYPE) {
1408 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001409 rd_stats->rate += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001410 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001411 rd_stats->rate +=
1412 cpi->intra_tx_type_costs[mbmi->tx_size]
1413 [intra_mode_to_tx_type_context[mbmi->mode]]
1414 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001415 }
1416 }
1417#endif // CONFIG_EXT_TX
1418
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001419 if (rd_stats->skip) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001420 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001421 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001422 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001423 rd = RDCOST(x->rdmult, x->rddiv, s1 + r_tx_size * tx_select,
1424 rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001425 }
1426 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001427 rd = RDCOST(x->rdmult, x->rddiv,
1428 rd_stats->rate + s0 + r_tx_size * tx_select, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001429 }
1430
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001431 if (tx_select) rd_stats->rate += r_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001432
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001433 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1434 !(rd_stats->skip))
1435 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001436
1437 return rd;
1438}
1439
Urvang Joshi52648442016-10-13 17:27:51 -07001440static int64_t choose_tx_size_fix_type(const AV1_COMP *const cpi, BLOCK_SIZE bs,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001441 MACROBLOCK *x, RD_STATS *rd_stats,
1442 int64_t ref_best_rd, TX_TYPE tx_type,
Yushin Cho55711e62016-11-10 18:49:24 -08001443#if CONFIG_PVQ
1444 od_rollback_buffer buf,
1445#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001446 int prune) {
Urvang Joshi52648442016-10-13 17:27:51 -07001447 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001448 MACROBLOCKD *const xd = &x->e_mbd;
1449 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001450 int64_t rd = INT64_MAX;
1451 int n;
1452 int start_tx, end_tx;
1453 int64_t best_rd = INT64_MAX, last_rd = INT64_MAX;
1454 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
1455 TX_SIZE best_tx_size = max_tx_size;
1456 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
1457 const int is_inter = is_inter_block(mbmi);
1458#if CONFIG_EXT_TX
1459#if CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001460 int evaluate_rect_tx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001461#endif // CONFIG_RECT_TX
1462 int ext_tx_set;
1463#endif // CONFIG_EXT_TX
1464
1465 if (tx_select) {
1466#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001467 evaluate_rect_tx = is_rect_tx_allowed(xd, mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001468#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1469 start_tx = max_tx_size;
Debargha Mukherjee153e1f82016-11-17 09:59:14 -08001470 end_tx = (max_tx_size >= TX_32X32) ? TX_8X8 : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001471 } else {
1472 const TX_SIZE chosen_tx_size =
1473 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
1474#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001475 evaluate_rect_tx = is_rect_tx(chosen_tx_size);
1476 assert(IMPLIES(evaluate_rect_tx, is_rect_tx_allowed(xd, mbmi)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001477#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1478 start_tx = chosen_tx_size;
1479 end_tx = chosen_tx_size;
1480 }
1481
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001482 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001483
1484 mbmi->tx_type = tx_type;
1485
1486#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001487 if (evaluate_rect_tx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001488 const TX_SIZE rect_tx_size = max_txsize_rect_lookup[bs];
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001489 RD_STATS this_rd_stats;
Urvang Joshi368fbc92016-10-17 16:31:34 -07001490 ext_tx_set = get_ext_tx_set(rect_tx_size, bs, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001491 if (ext_tx_used_inter[ext_tx_set][tx_type]) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001492 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001493 rect_tx_size);
1494 best_tx_size = rect_tx_size;
1495 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001496 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001497 }
1498 }
1499#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1500
1501 last_rd = INT64_MAX;
1502 for (n = start_tx; n >= end_tx; --n) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001503 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001504#if CONFIG_EXT_TX && CONFIG_RECT_TX
1505 if (is_rect_tx(n)) break;
1506#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1507 if (FIXED_TX_TYPE && tx_type != get_default_tx_type(0, xd, 0, n)) continue;
1508 if (!is_inter && x->use_default_intra_tx_type &&
1509 tx_type != get_default_tx_type(0, xd, 0, n))
1510 continue;
1511 if (is_inter && x->use_default_inter_tx_type &&
1512 tx_type != get_default_tx_type(0, xd, 0, n))
1513 continue;
Debargha Mukherjee153e1f82016-11-17 09:59:14 -08001514 if (max_tx_size >= TX_32X32 && n == TX_4X4) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001515#if CONFIG_EXT_TX
1516 ext_tx_set = get_ext_tx_set(n, bs, is_inter);
1517 if (is_inter) {
1518 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
1519 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1520 if (!do_tx_type_search(tx_type, prune)) continue;
1521 }
1522 } else {
1523 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1524 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
1525 }
1526 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
1527 }
1528#else // CONFIG_EXT_TX
1529 if (n >= TX_32X32 && tx_type != DCT_DCT) continue;
1530 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
1531 !do_tx_type_search(tx_type, prune))
1532 continue;
1533#endif // CONFIG_EXT_TX
1534
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001535 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type, n);
Yushin Cho55711e62016-11-10 18:49:24 -08001536#if CONFIG_PVQ
1537 od_encode_rollback(&x->daala_enc, &buf);
1538#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001539 // Early termination in transform size search.
1540 if (cpi->sf.tx_size_search_breakout &&
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001541 (rd == INT64_MAX ||
1542 (this_rd_stats.skip == 1 && tx_type != DCT_DCT && n < start_tx) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07001543 (n < (int)max_tx_size && rd > last_rd)))
1544 break;
1545
1546 last_rd = rd;
1547 if (rd < best_rd) {
1548 best_tx_size = n;
1549 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001550 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001551 }
1552 }
1553 mbmi->tx_size = best_tx_size;
1554
1555 return best_rd;
1556}
1557
1558#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07001559static int64_t estimate_yrd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bs,
1560 MACROBLOCK *x, int *r, int64_t *d, int *s,
1561 int64_t *sse, int64_t ref_best_rd) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001562 RD_STATS rd_stats;
1563 int64_t rd = txfm_yrd(cpi, x, &rd_stats, ref_best_rd, bs, DCT_DCT,
1564 max_txsize_lookup[bs]);
1565 *r = rd_stats.rate;
1566 *d = rd_stats.dist;
1567 *s = rd_stats.skip;
1568 *sse = rd_stats.sse;
1569 return rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001570}
1571#endif // CONFIG_EXT_INTER
1572
Urvang Joshi52648442016-10-13 17:27:51 -07001573static void choose_largest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001574 RD_STATS *rd_stats, int64_t ref_best_rd,
Urvang Joshi52648442016-10-13 17:27:51 -07001575 BLOCK_SIZE bs) {
1576 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001577 MACROBLOCKD *const xd = &x->e_mbd;
1578 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1579 TX_TYPE tx_type, best_tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001580 int64_t this_rd, best_rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001581 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
1582 int s0 = av1_cost_bit(skip_prob, 0);
1583 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001584 const int is_inter = is_inter_block(mbmi);
1585 int prune = 0;
1586#if CONFIG_EXT_TX
1587 int ext_tx_set;
1588#endif // CONFIG_EXT_TX
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001589 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001590
1591 mbmi->tx_size = tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
Jingning Hane67b38a2016-11-04 10:30:00 -07001592#if CONFIG_VAR_TX
1593 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
1594#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001595#if CONFIG_EXT_TX
1596 ext_tx_set = get_ext_tx_set(mbmi->tx_size, bs, is_inter);
1597#endif // CONFIG_EXT_TX
1598
1599 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
1600#if CONFIG_EXT_TX
1601 prune = prune_tx_types(cpi, bs, x, xd, ext_tx_set);
1602#else
1603 prune = prune_tx_types(cpi, bs, x, xd, 0);
1604#endif
1605#if CONFIG_EXT_TX
1606 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1 &&
1607 !xd->lossless[mbmi->segment_id]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07001608#if CONFIG_PVQ
1609 od_rollback_buffer pre_buf, post_buf;
1610
1611 od_encode_checkpoint(&x->daala_enc, &pre_buf);
1612 od_encode_checkpoint(&x->daala_enc, &post_buf);
1613#endif
1614
1615 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001616 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001617 if (is_inter) {
1618 if (x->use_default_inter_tx_type &&
1619 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1620 continue;
1621 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
1622 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1623 if (!do_tx_type_search(tx_type, prune)) continue;
1624 }
1625 } else {
1626 if (x->use_default_intra_tx_type &&
1627 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1628 continue;
1629 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1630 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
1631 }
1632 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
1633 }
1634
1635 mbmi->tx_type = tx_type;
1636
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001637 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001638 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001639#if CONFIG_PVQ
1640 od_encode_rollback(&x->daala_enc, &pre_buf);
1641#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001642 if (this_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001643 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1) {
1644 if (is_inter) {
1645 if (ext_tx_set > 0)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001646 this_rd_stats.rate +=
1647 cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size]
1648 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001649 } else {
1650 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001651 this_rd_stats.rate +=
1652 cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->mode]
1653 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001654 }
1655 }
1656
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001657 if (this_rd_stats.skip)
1658 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001659 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001660 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
1661 this_rd_stats.dist);
1662 if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] &&
1663 !this_rd_stats.skip)
1664 this_rd =
1665 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001666
1667 if (this_rd < best_rd) {
1668 best_rd = this_rd;
1669 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001670 *rd_stats = this_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001671#if CONFIG_PVQ
1672 od_encode_checkpoint(&x->daala_enc, &post_buf);
1673#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001674 }
1675 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001676#if CONFIG_PVQ
1677 od_encode_rollback(&x->daala_enc, &post_buf);
1678#endif
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001679 } else {
1680 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001681 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
1682 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001683 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001684#else // CONFIG_EXT_TX
1685 if (mbmi->tx_size < TX_32X32 && !xd->lossless[mbmi->segment_id]) {
1686 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001687 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001688 if (!is_inter && x->use_default_intra_tx_type &&
1689 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1690 continue;
1691 if (is_inter && x->use_default_inter_tx_type &&
1692 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1693 continue;
1694 mbmi->tx_type = tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001695 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001696 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001697 if (this_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001698 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001699 this_rd_stats.rate +=
1700 cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001701 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
1702 !do_tx_type_search(tx_type, prune))
1703 continue;
1704 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001705 this_rd_stats.rate +=
1706 cpi->intra_tx_type_costs[mbmi->tx_size]
1707 [intra_mode_to_tx_type_context[mbmi->mode]]
1708 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001709 }
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001710 if (this_rd_stats.skip)
1711 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001712 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001713 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
1714 this_rd_stats.dist);
1715 if (is_inter && !xd->lossless[mbmi->segment_id] && !this_rd_stats.skip)
1716 this_rd =
1717 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001718
1719 if (this_rd < best_rd) {
1720 best_rd = this_rd;
1721 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001722 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001723 }
1724 }
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001725 } else {
1726 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001727 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
1728 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001729 }
1730#endif // CONFIG_EXT_TX
1731 mbmi->tx_type = best_tx_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001732}
1733
Urvang Joshi52648442016-10-13 17:27:51 -07001734static void choose_smallest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001735 RD_STATS *rd_stats, int64_t ref_best_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001736 BLOCK_SIZE bs) {
1737 MACROBLOCKD *const xd = &x->e_mbd;
1738 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1739
1740 mbmi->tx_size = TX_4X4;
1741 mbmi->tx_type = DCT_DCT;
Jingning Hane67b38a2016-11-04 10:30:00 -07001742#if CONFIG_VAR_TX
1743 mbmi->min_tx_size = get_min_tx_size(TX_4X4);
1744#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001745
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001746 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
1747 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001748}
1749
Urvang Joshi52648442016-10-13 17:27:51 -07001750static void choose_tx_size_type_from_rd(const AV1_COMP *const cpi,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001751 MACROBLOCK *x, RD_STATS *rd_stats,
1752 int64_t ref_best_rd, BLOCK_SIZE bs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001753 MACROBLOCKD *const xd = &x->e_mbd;
1754 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001755 int64_t rd = INT64_MAX;
1756 int64_t best_rd = INT64_MAX;
1757 TX_SIZE best_tx = max_txsize_lookup[bs];
1758 const int is_inter = is_inter_block(mbmi);
1759 TX_TYPE tx_type, best_tx_type = DCT_DCT;
1760 int prune = 0;
1761
Yushin Cho77bba8d2016-11-04 16:36:56 -07001762#if CONFIG_PVQ
1763 od_rollback_buffer buf;
1764#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001765 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
1766 // passing -1 in for tx_type indicates that all 1D
1767 // transforms should be considered for pruning
1768 prune = prune_tx_types(cpi, bs, x, xd, -1);
1769
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001770 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001771
Yushin Cho77bba8d2016-11-04 16:36:56 -07001772#if CONFIG_PVQ
1773 od_encode_checkpoint(&x->daala_enc, &buf);
1774#endif
1775
Yaowu Xuc27fc142016-08-22 16:08:15 -07001776 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001777 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001778#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07001779 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001780#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001781 rd = choose_tx_size_fix_type(cpi, bs, x, &this_rd_stats, ref_best_rd,
Yushin Cho55711e62016-11-10 18:49:24 -08001782 tx_type,
1783#if CONFIG_PVQ
1784 buf,
1785#endif
1786 prune);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001787 if (rd < best_rd) {
1788 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001789 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001790 best_tx_type = tx_type;
1791 best_tx = mbmi->tx_size;
1792 }
1793 }
1794
1795 mbmi->tx_size = best_tx;
1796 mbmi->tx_type = best_tx_type;
1797
Jingning Hane67b38a2016-11-04 10:30:00 -07001798#if CONFIG_VAR_TX
1799 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
1800#endif
1801
Yaowu Xuc27fc142016-08-22 16:08:15 -07001802#if !CONFIG_EXT_TX
1803 if (mbmi->tx_size >= TX_32X32) assert(mbmi->tx_type == DCT_DCT);
1804#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07001805#if CONFIG_PVQ
Yushin Cho403618e2016-11-09 10:45:32 -08001806 if (best_rd != INT64_MAX) {
1807 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, best_tx,
Yushin Cho77bba8d2016-11-04 16:36:56 -07001808 cpi->sf.use_fast_coef_costing);
Yushin Cho05f540a2016-11-08 22:12:51 -08001809 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001810#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001811}
1812
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001813static void super_block_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
1814 RD_STATS *rd_stats, BLOCK_SIZE bs,
1815 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001816 MACROBLOCKD *xd = &x->e_mbd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001817 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001818
1819 assert(bs == xd->mi[0]->mbmi.sb_type);
1820
1821 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001822 choose_smallest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001823 } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001824 choose_largest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001825 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001826 choose_tx_size_type_from_rd(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001827 }
1828}
1829
1830static int conditional_skipintra(PREDICTION_MODE mode,
1831 PREDICTION_MODE best_intra_mode) {
1832 if (mode == D117_PRED && best_intra_mode != V_PRED &&
1833 best_intra_mode != D135_PRED)
1834 return 1;
1835 if (mode == D63_PRED && best_intra_mode != V_PRED &&
1836 best_intra_mode != D45_PRED)
1837 return 1;
1838 if (mode == D207_PRED && best_intra_mode != H_PRED &&
1839 best_intra_mode != D45_PRED)
1840 return 1;
1841 if (mode == D153_PRED && best_intra_mode != H_PRED &&
1842 best_intra_mode != D135_PRED)
1843 return 1;
1844 return 0;
1845}
1846
Urvang Joshib100db72016-10-12 16:28:56 -07001847#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001848static int rd_pick_palette_intra_sby(
Urvang Joshi52648442016-10-13 17:27:51 -07001849 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int palette_ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001850 int dc_mode_cost, PALETTE_MODE_INFO *palette_mode_info,
1851 uint8_t *best_palette_color_map, TX_SIZE *best_tx, TX_TYPE *best_tx_type,
1852 PREDICTION_MODE *mode_selected, int64_t *best_rd) {
1853 int rate_overhead = 0;
1854 MACROBLOCKD *const xd = &x->e_mbd;
1855 MODE_INFO *const mic = xd->mi[0];
Jingning Hanae5cfde2016-11-30 12:01:44 -08001856 const int rows = block_size_high[bsize];
1857 const int cols = block_size_wide[bsize];
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001858 int this_rate, colors, n;
1859 RD_STATS tokenonly_rd_stats;
1860 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001861 const int src_stride = x->plane[0].src.stride;
1862 const uint8_t *const src = x->plane[0].src.buf;
1863
1864 assert(cpi->common.allow_screen_content_tools);
1865
Yaowu Xuf883b422016-08-30 14:01:10 -07001866#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001867 if (cpi->common.use_highbitdepth)
Yaowu Xuf883b422016-08-30 14:01:10 -07001868 colors = av1_count_colors_highbd(src, src_stride, rows, cols,
1869 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001870 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001871#endif // CONFIG_AOM_HIGHBITDEPTH
1872 colors = av1_count_colors(src, src_stride, rows, cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001873 palette_mode_info->palette_size[0] = 0;
hui su5db97432016-10-14 16:10:14 -07001874#if CONFIG_FILTER_INTRA
1875 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0;
1876#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07001877
1878 if (colors > 1 && colors <= 64) {
1879 int r, c, i, j, k;
1880 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07001881 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001882 float *const data = x->palette_buffer->kmeans_data_buf;
1883 float centroids[PALETTE_MAX_SIZE];
1884 uint8_t *const color_map = xd->plane[0].color_index_map;
1885 float lb, ub, val;
1886 MB_MODE_INFO *const mbmi = &mic->mbmi;
1887 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuf883b422016-08-30 14:01:10 -07001888#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001889 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
1890 if (cpi->common.use_highbitdepth)
1891 lb = ub = src16[0];
1892 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001893#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001894 lb = ub = src[0];
1895
Yaowu Xuf883b422016-08-30 14:01:10 -07001896#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001897 if (cpi->common.use_highbitdepth) {
1898 for (r = 0; r < rows; ++r) {
1899 for (c = 0; c < cols; ++c) {
1900 val = src16[r * src_stride + c];
1901 data[r * cols + c] = val;
1902 if (val < lb)
1903 lb = val;
1904 else if (val > ub)
1905 ub = val;
1906 }
1907 }
1908 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001909#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001910 for (r = 0; r < rows; ++r) {
1911 for (c = 0; c < cols; ++c) {
1912 val = src[r * src_stride + c];
1913 data[r * cols + c] = val;
1914 if (val < lb)
1915 lb = val;
1916 else if (val > ub)
1917 ub = val;
1918 }
1919 }
Yaowu Xuf883b422016-08-30 14:01:10 -07001920#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001921 }
Yaowu Xuf883b422016-08-30 14:01:10 -07001922#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001923
1924 mbmi->mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07001925#if CONFIG_FILTER_INTRA
1926 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
1927#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07001928
1929 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return 0;
1930
1931 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
1932 --n) {
1933 for (i = 0; i < n; ++i)
1934 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
Yaowu Xuf883b422016-08-30 14:01:10 -07001935 av1_k_means(data, centroids, color_map, rows * cols, n, 1, max_itr);
1936 k = av1_remove_duplicates(centroids, n);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001937
Yaowu Xuf883b422016-08-30 14:01:10 -07001938#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001939 if (cpi->common.use_highbitdepth)
1940 for (i = 0; i < k; ++i)
1941 pmi->palette_colors[i] =
1942 clip_pixel_highbd((int)centroids[i], cpi->common.bit_depth);
1943 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001944#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001945 for (i = 0; i < k; ++i)
1946 pmi->palette_colors[i] = clip_pixel((int)centroids[i]);
1947 pmi->palette_size[0] = k;
1948
Yaowu Xuf883b422016-08-30 14:01:10 -07001949 av1_calc_indices(data, centroids, color_map, rows * cols, k, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001950
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001951 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
1952 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001953
1954 this_rate =
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001955 tokenonly_rd_stats.rate + dc_mode_cost +
Yaowu Xuf883b422016-08-30 14:01:10 -07001956 cpi->common.bit_depth * k * av1_cost_bit(128, 0) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07001957 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - 2] +
1958 write_uniform_cost(k, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07001959 av1_cost_bit(
1960 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07001961 1);
1962 for (i = 0; i < rows; ++i) {
1963 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07001964 int color_idx;
1965 const int color_ctx = av1_get_palette_color_context(
1966 color_map, cols, i, j, k, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001967 assert(color_idx >= 0 && color_idx < k);
1968 this_rate += cpi->palette_y_color_cost[k - 2][color_ctx][color_idx];
1969 }
1970 }
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001971 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001972
1973 if (this_rd < *best_rd) {
1974 *best_rd = this_rd;
1975 *palette_mode_info = *pmi;
1976 memcpy(best_palette_color_map, color_map,
1977 rows * cols * sizeof(color_map[0]));
1978 *mode_selected = DC_PRED;
1979 *best_tx = mbmi->tx_size;
1980 *best_tx_type = mbmi->tx_type;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001981 rate_overhead = this_rate - tokenonly_rd_stats.rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001982 }
1983 }
1984 }
1985 return rate_overhead;
1986}
Urvang Joshib100db72016-10-12 16:28:56 -07001987#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001988
Urvang Joshi52648442016-10-13 17:27:51 -07001989static int64_t rd_pick_intra4x4block(
1990 const AV1_COMP *const cpi, MACROBLOCK *x, int row, int col,
1991 PREDICTION_MODE *best_mode, const int *bmode_costs, ENTROPY_CONTEXT *a,
1992 ENTROPY_CONTEXT *l, int *bestrate, int *bestratey, int64_t *bestdistortion,
1993 BLOCK_SIZE bsize, int *y_skip, int64_t rd_thresh) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07001994#if !CONFIG_PVQ
Angie Chiang22ba7512016-10-20 17:10:33 -07001995 const AV1_COMMON *const cm = &cpi->common;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001996#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001997 PREDICTION_MODE mode;
1998 MACROBLOCKD *const xd = &x->e_mbd;
1999 int64_t best_rd = rd_thresh;
2000 struct macroblock_plane *p = &x->plane[0];
2001 struct macroblockd_plane *pd = &xd->plane[0];
2002 const int src_stride = p->src.stride;
2003 const int dst_stride = pd->dst.stride;
2004 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
2005 uint8_t *dst_init = &pd->dst.buf[row * 4 * src_stride + col * 4];
2006 ENTROPY_CONTEXT ta[2], tempa[2];
2007 ENTROPY_CONTEXT tl[2], templ[2];
2008 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2009 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2010 int idx, idy;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002011 int best_can_skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002012 uint8_t best_dst[8 * 8];
Yaowu Xuf883b422016-08-30 14:01:10 -07002013#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002014 uint16_t best_dst16[8 * 8];
2015#endif
2016
Yushin Cho77bba8d2016-11-04 16:36:56 -07002017#if CONFIG_PVQ
2018 od_rollback_buffer pre_buf, post_buf;
2019 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2020 od_encode_checkpoint(&x->daala_enc, &post_buf);
2021#endif
2022
Yaowu Xuc27fc142016-08-22 16:08:15 -07002023 memcpy(ta, a, num_4x4_blocks_wide * sizeof(a[0]));
2024 memcpy(tl, l, num_4x4_blocks_high * sizeof(l[0]));
2025 xd->mi[0]->mbmi.tx_size = TX_4X4;
Urvang Joshib100db72016-10-12 16:28:56 -07002026#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002027 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002028#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002029
Yaowu Xuf883b422016-08-30 14:01:10 -07002030#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002031 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2032 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2033 int64_t this_rd;
2034 int ratey = 0;
2035 int64_t distortion = 0;
2036 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002037 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002038
2039 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode))) continue;
2040
2041 // Only do the oblique modes if the best so far is
2042 // one of the neighboring directional modes
2043 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2044 if (conditional_skipintra(mode, *best_mode)) continue;
2045 }
2046
2047 memcpy(tempa, ta, num_4x4_blocks_wide * sizeof(ta[0]));
2048 memcpy(templ, tl, num_4x4_blocks_high * sizeof(tl[0]));
2049
2050 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
2051 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
2052 const int block = (row + idy) * 2 + (col + idx);
2053 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2054 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
2055 int16_t *const src_diff =
Yaowu Xuf883b422016-08-30 14:01:10 -07002056 av1_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002057 xd->mi[0]->bmi[block].as_mode = mode;
Jingning Hanc4c99da2016-10-24 10:27:28 -07002058 av1_predict_intra_block(xd, pd->width, pd->height, TX_4X4, mode, dst,
2059 dst_stride, dst, dst_stride, col + idx,
2060 row + idy, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07002061 aom_highbd_subtract_block(4, 4, src_diff, 8, src, src_stride, dst,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002062 dst_stride, xd->bd);
2063 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
2064 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002065 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002066 const int coeff_ctx =
2067 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002068#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002069 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2070 TX_4X4, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002071#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002072 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002073 TX_4X4, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002074#endif // CONFIG_NEW_QUANT
Angie Chiang22ba7512016-10-20 17:10:33 -07002075 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002076 scan_order->scan, scan_order->neighbors,
2077 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002078 *(tempa + idx) = !(p->eobs[block] == 0);
2079 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002080 can_skip &= (p->eobs[block] == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002081 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2082 goto next_highbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07002083 av1_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2084 dst_stride, p->eobs[block], xd->bd,
2085 DCT_DCT, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002086 } else {
2087 int64_t dist;
2088 unsigned int tmp;
2089 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002090 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002091 const int coeff_ctx =
2092 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
2093#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002094 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2095 TX_4X4, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002096#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002097 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002098 TX_4X4, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002099#endif // CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002100 av1_optimize_b(cm, x, 0, block, TX_4X4, coeff_ctx);
Angie Chiang22ba7512016-10-20 17:10:33 -07002101 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002102 scan_order->scan, scan_order->neighbors,
2103 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002104 *(tempa + idx) = !(p->eobs[block] == 0);
2105 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002106 can_skip &= (p->eobs[block] == 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07002107 av1_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2108 dst_stride, p->eobs[block], xd->bd,
2109 tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002110 cpi->fn_ptr[BLOCK_4X4].vf(src, src_stride, dst, dst_stride, &tmp);
2111 dist = (int64_t)tmp << 4;
2112 distortion += dist;
2113 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2114 goto next_highbd;
2115 }
2116 }
2117 }
2118
2119 rate += ratey;
2120 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2121
2122 if (this_rd < best_rd) {
2123 *bestrate = rate;
2124 *bestratey = ratey;
2125 *bestdistortion = distortion;
2126 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002127 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002128 *best_mode = mode;
2129 memcpy(a, tempa, num_4x4_blocks_wide * sizeof(tempa[0]));
2130 memcpy(l, templ, num_4x4_blocks_high * sizeof(templ[0]));
2131 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
2132 memcpy(best_dst16 + idy * 8,
2133 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
2134 num_4x4_blocks_wide * 4 * sizeof(uint16_t));
2135 }
2136 }
2137 next_highbd : {}
2138 }
2139
2140 if (best_rd >= rd_thresh) return best_rd;
2141
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002142 if (y_skip) *y_skip &= best_can_skip;
2143
Yaowu Xuc27fc142016-08-22 16:08:15 -07002144 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
2145 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
2146 best_dst16 + idy * 8, num_4x4_blocks_wide * 4 * sizeof(uint16_t));
2147 }
2148
2149 return best_rd;
2150 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002151#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002152
Yushin Cho77bba8d2016-11-04 16:36:56 -07002153#if CONFIG_PVQ
2154 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2155#endif
2156
Yaowu Xuc27fc142016-08-22 16:08:15 -07002157 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2158 int64_t this_rd;
2159 int ratey = 0;
2160 int64_t distortion = 0;
2161 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002162 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002163
2164 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode))) continue;
2165
2166 // Only do the oblique modes if the best so far is
2167 // one of the neighboring directional modes
2168 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2169 if (conditional_skipintra(mode, *best_mode)) continue;
2170 }
2171
2172 memcpy(tempa, ta, num_4x4_blocks_wide * sizeof(ta[0]));
2173 memcpy(templ, tl, num_4x4_blocks_high * sizeof(tl[0]));
2174
2175 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
2176 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
2177 const int block = (row + idy) * 2 + (col + idx);
2178 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2179 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Yushin Cho77bba8d2016-11-04 16:36:56 -07002180#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002181 int16_t *const src_diff =
Yaowu Xuf883b422016-08-30 14:01:10 -07002182 av1_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002183#else
2184 int lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
2185 const int diff_stride = 8;
2186 tran_low_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block);
2187 tran_low_t *const dqcoeff = BLOCK_OFFSET(xd->plane[0].dqcoeff, block);
2188 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
2189 int16_t *pred = &pd->pred[4 * (row * diff_stride + col)];
2190 int16_t *src_int16 = &p->src_int16[4 * (row * diff_stride + col)];
2191 int i, j, tx_blk_size;
2192 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
2193 int rate_pvq;
2194 int skip;
2195#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002196 xd->mi[0]->bmi[block].as_mode = mode;
Jingning Hanc4c99da2016-10-24 10:27:28 -07002197 av1_predict_intra_block(xd, pd->width, pd->height, TX_4X4, mode, dst,
2198 dst_stride, dst, dst_stride, col + idx,
2199 row + idy, 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002200#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -07002201 aom_subtract_block(4, 4, src_diff, 8, src, src_stride, dst, dst_stride);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002202#else
2203 if (lossless) tx_type = DCT_DCT;
2204 // transform block size in pixels
2205 tx_blk_size = 4;
2206
2207 // copy uint8 orig and predicted block to int16 buffer
2208 // in order to use existing VP10 transform functions
2209 for (j = 0; j < tx_blk_size; j++)
2210 for (i = 0; i < tx_blk_size; i++) {
2211 src_int16[diff_stride * j + i] = src[src_stride * j + i];
2212 pred[diff_stride * j + i] = dst[dst_stride * j + i];
2213 }
2214 {
2215 FWD_TXFM_PARAM fwd_txfm_param;
2216 fwd_txfm_param.tx_type = tx_type;
2217 fwd_txfm_param.tx_size = TX_4X4;
2218 fwd_txfm_param.fwd_txfm_opt = FWD_TXFM_OPT_NORMAL;
2219 fwd_txfm_param.rd_transform = 0;
2220 fwd_txfm_param.lossless = lossless;
2221 fwd_txfm(src_int16, coeff, diff_stride, &fwd_txfm_param);
2222 fwd_txfm(pred, ref_coeff, diff_stride, &fwd_txfm_param);
2223 }
2224#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002225
2226 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07002227#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002228 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002229 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002230 const int coeff_ctx =
2231 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002232#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002233 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2234 TX_4X4, coeff_ctx, AV1_XFORM_QUANT_B_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002235#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002236 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002237 TX_4X4, coeff_ctx, AV1_XFORM_QUANT_B);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002238#endif // CONFIG_NEW_QUANT
Angie Chiang22ba7512016-10-20 17:10:33 -07002239 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002240 scan_order->scan, scan_order->neighbors,
2241 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002242 *(tempa + idx) = !(p->eobs[block] == 0);
2243 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002244 can_skip &= (p->eobs[block] == 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002245#else
2246 skip = av1_pvq_encode_helper(&x->daala_enc, coeff, ref_coeff, dqcoeff,
2247 &p->eobs[block], pd->dequant, 0, TX_4X4,
2248 tx_type, &rate_pvq, x->pvq_speed, NULL);
2249 ratey += rate_pvq;
2250#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002251 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2252 goto next;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002253#if CONFIG_PVQ
2254 if (!skip) {
2255 for (j = 0; j < tx_blk_size; j++)
2256 for (i = 0; i < tx_blk_size; i++) dst[j * dst_stride + i] = 0;
2257#endif
2258 av1_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2259 dst_stride, p->eobs[block], DCT_DCT, 1);
2260#if CONFIG_PVQ
2261 }
2262#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002263 } else {
2264 int64_t dist;
2265 unsigned int tmp;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002266#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002267 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002268 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002269 const int coeff_ctx =
2270 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
2271#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002272 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2273 TX_4X4, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002274#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002275 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002276 TX_4X4, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002277#endif // CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002278 av1_optimize_b(cm, x, 0, block, TX_4X4, coeff_ctx);
Angie Chiang22ba7512016-10-20 17:10:33 -07002279 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002280 scan_order->scan, scan_order->neighbors,
2281 cpi->sf.use_fast_coef_costing);
Jingning Han3d45c0e2016-11-08 12:35:04 -08002282 *(tempa + idx) = !(p->eobs[block] == 0);
2283 *(templ + idy) = !(p->eobs[block] == 0);
2284 can_skip &= (p->eobs[block] == 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002285#else
2286 skip = av1_pvq_encode_helper(&x->daala_enc, coeff, ref_coeff, dqcoeff,
2287 &p->eobs[block], pd->dequant, 0, TX_4X4,
2288 tx_type, &rate_pvq, x->pvq_speed, NULL);
2289 ratey += rate_pvq;
2290#endif
2291 // No need for av1_block_error2_c because the ssz is unused
Yaowu Xuf883b422016-08-30 14:01:10 -07002292 av1_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2293 dst_stride, p->eobs[block], tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002294 cpi->fn_ptr[BLOCK_4X4].vf(src, src_stride, dst, dst_stride, &tmp);
2295 dist = (int64_t)tmp << 4;
2296 distortion += dist;
2297 // To use the pixel domain distortion, the step below needs to be
2298 // put behind the inv txfm. Compared to calculating the distortion
2299 // in the frequency domain, the overhead of encoding effort is low.
2300 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2301 goto next;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002302#if CONFIG_PVQ
2303 if (!skip) {
2304 for (j = 0; j < tx_blk_size; j++)
2305 for (i = 0; i < tx_blk_size; i++) dst[j * dst_stride + i] = 0;
2306#endif
2307#if CONFIG_PVQ
2308 }
2309#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002310 }
2311 }
2312 }
2313
2314 rate += ratey;
2315 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2316
2317 if (this_rd < best_rd) {
2318 *bestrate = rate;
2319 *bestratey = ratey;
2320 *bestdistortion = distortion;
2321 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002322 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002323 *best_mode = mode;
2324 memcpy(a, tempa, num_4x4_blocks_wide * sizeof(tempa[0]));
2325 memcpy(l, templ, num_4x4_blocks_high * sizeof(templ[0]));
Yushin Cho77bba8d2016-11-04 16:36:56 -07002326#if CONFIG_PVQ
2327 od_encode_checkpoint(&x->daala_enc, &post_buf);
2328#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002329 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
2330 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
2331 num_4x4_blocks_wide * 4);
2332 }
2333 next : {}
Yushin Cho77bba8d2016-11-04 16:36:56 -07002334#if CONFIG_PVQ
2335 od_encode_rollback(&x->daala_enc, &pre_buf);
2336#endif
2337 } // mode decision loop
Yaowu Xuc27fc142016-08-22 16:08:15 -07002338
2339 if (best_rd >= rd_thresh) return best_rd;
2340
Yushin Cho77bba8d2016-11-04 16:36:56 -07002341#if CONFIG_PVQ
2342 od_encode_rollback(&x->daala_enc, &post_buf);
2343#endif
2344
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002345 if (y_skip) *y_skip &= best_can_skip;
2346
Yaowu Xuc27fc142016-08-22 16:08:15 -07002347 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
2348 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
2349 num_4x4_blocks_wide * 4);
2350
2351 return best_rd;
2352}
2353
Urvang Joshi52648442016-10-13 17:27:51 -07002354static int64_t rd_pick_intra_sub_8x8_y_mode(const AV1_COMP *const cpi,
2355 MACROBLOCK *mb, int *rate,
2356 int *rate_y, int64_t *distortion,
2357 int *y_skip, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002358 int i, j;
2359 const MACROBLOCKD *const xd = &mb->e_mbd;
2360 MODE_INFO *const mic = xd->mi[0];
2361 const MODE_INFO *above_mi = xd->above_mi;
2362 const MODE_INFO *left_mi = xd->left_mi;
2363 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
2364 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2365 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2366 int idx, idy;
2367 int cost = 0;
2368 int64_t total_distortion = 0;
2369 int tot_rate_y = 0;
2370 int64_t total_rd = 0;
2371 const int *bmode_costs = cpi->mbmode_cost[0];
2372
2373#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002374 mic->mbmi.intra_filter = INTRA_FILTER_LINEAR;
2375#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002376#if CONFIG_FILTER_INTRA
2377 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2378#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002379
2380 // TODO(any): Add search of the tx_type to improve rd performance at the
2381 // expense of speed.
2382 mic->mbmi.tx_type = DCT_DCT;
2383 mic->mbmi.tx_size = TX_4X4;
2384
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002385 if (y_skip) *y_skip = 1;
2386
Yaowu Xuc27fc142016-08-22 16:08:15 -07002387 // Pick modes for each sub-block (of size 4x4, 4x8, or 8x4) in an 8x8 block.
2388 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
2389 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
2390 PREDICTION_MODE best_mode = DC_PRED;
2391 int r = INT_MAX, ry = INT_MAX;
2392 int64_t d = INT64_MAX, this_rd = INT64_MAX;
2393 i = idy * 2 + idx;
2394 if (cpi->common.frame_type == KEY_FRAME) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002395 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, i);
2396 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, i);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002397
2398 bmode_costs = cpi->y_mode_costs[A][L];
2399 }
2400
2401 this_rd = rd_pick_intra4x4block(
2402 cpi, mb, idy, idx, &best_mode, bmode_costs,
2403 xd->plane[0].above_context + idx, xd->plane[0].left_context + idy, &r,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002404 &ry, &d, bsize, y_skip, best_rd - total_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002405 if (this_rd >= best_rd - total_rd) return INT64_MAX;
2406
2407 total_rd += this_rd;
2408 cost += r;
2409 total_distortion += d;
2410 tot_rate_y += ry;
2411
2412 mic->bmi[i].as_mode = best_mode;
2413 for (j = 1; j < num_4x4_blocks_high; ++j)
2414 mic->bmi[i + j * 2].as_mode = best_mode;
2415 for (j = 1; j < num_4x4_blocks_wide; ++j)
2416 mic->bmi[i + j].as_mode = best_mode;
2417
2418 if (total_rd >= best_rd) return INT64_MAX;
2419 }
2420 }
2421 mic->mbmi.mode = mic->bmi[3].as_mode;
2422
2423 // Add in the cost of the transform type
2424 if (!xd->lossless[mic->mbmi.segment_id]) {
2425 int rate_tx_type = 0;
2426#if CONFIG_EXT_TX
2427 if (get_ext_tx_types(TX_4X4, bsize, 0) > 1) {
2428 const int eset = get_ext_tx_set(TX_4X4, bsize, 0);
clang-format67948d32016-09-07 22:40:40 -07002429 rate_tx_type = cpi->intra_tx_type_costs[eset][TX_4X4][mic->mbmi.mode]
2430 [mic->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002431 }
2432#else
clang-format67948d32016-09-07 22:40:40 -07002433 rate_tx_type =
2434 cpi->intra_tx_type_costs[TX_4X4]
2435 [intra_mode_to_tx_type_context[mic->mbmi.mode]]
2436 [mic->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002437#endif
2438 assert(mic->mbmi.tx_size == TX_4X4);
2439 cost += rate_tx_type;
2440 tot_rate_y += rate_tx_type;
2441 }
2442
2443 *rate = cost;
2444 *rate_y = tot_rate_y;
2445 *distortion = total_distortion;
2446
2447 return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
2448}
2449
hui su5db97432016-10-14 16:10:14 -07002450#if CONFIG_FILTER_INTRA
2451// Return 1 if an filter intra mode is selected; return 0 otherwise.
2452static int rd_pick_filter_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2453 int *rate, int *rate_tokenonly,
2454 int64_t *distortion, int *skippable,
2455 BLOCK_SIZE bsize, int mode_cost,
2456 int64_t *best_rd, uint16_t skip_mask) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002457 MACROBLOCKD *const xd = &x->e_mbd;
2458 MODE_INFO *const mic = xd->mi[0];
2459 MB_MODE_INFO *mbmi = &mic->mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002460 int this_rate;
2461 RD_STATS tokenonly_rd_stats;
hui su5db97432016-10-14 16:10:14 -07002462 int filter_intra_selected_flag = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002463 int64_t this_rd;
hui su5db97432016-10-14 16:10:14 -07002464 FILTER_INTRA_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002465 TX_SIZE best_tx_size = TX_4X4;
hui su5db97432016-10-14 16:10:14 -07002466 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002467 TX_TYPE best_tx_type;
2468
hui su5db97432016-10-14 16:10:14 -07002469 av1_zero(filter_intra_mode_info);
2470 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002471 mbmi->mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07002472#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002473 mbmi->palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002474#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002475
2476 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
2477 if (skip_mask & (1 << mode)) continue;
hui su5db97432016-10-14 16:10:14 -07002478 mbmi->filter_intra_mode_info.filter_intra_mode[0] = mode;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002479 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
2480 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002481
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002482 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07002483 av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07002484 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002485 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002486
2487 if (this_rd < *best_rd) {
2488 *best_rd = this_rd;
2489 best_tx_size = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07002490 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002491 best_tx_type = mic->mbmi.tx_type;
2492 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002493 *rate_tokenonly = tokenonly_rd_stats.rate;
2494 *distortion = tokenonly_rd_stats.dist;
2495 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07002496 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002497 }
2498 }
2499
hui su5db97432016-10-14 16:10:14 -07002500 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002501 mbmi->mode = DC_PRED;
2502 mbmi->tx_size = best_tx_size;
hui su5db97432016-10-14 16:10:14 -07002503 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] =
2504 filter_intra_mode_info.use_filter_intra_mode[0];
2505 mbmi->filter_intra_mode_info.filter_intra_mode[0] =
2506 filter_intra_mode_info.filter_intra_mode[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002507 mbmi->tx_type = best_tx_type;
2508 return 1;
2509 } else {
2510 return 0;
2511 }
2512}
hui su5db97432016-10-14 16:10:14 -07002513#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002514
hui su5db97432016-10-14 16:10:14 -07002515#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002516static void pick_intra_angle_routine_sby(
Urvang Joshi52648442016-10-13 17:27:51 -07002517 const AV1_COMP *const cpi, MACROBLOCK *x, int *rate, int *rate_tokenonly,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002518 int64_t *distortion, int *skippable, int *best_angle_delta,
2519 TX_SIZE *best_tx_size, TX_TYPE *best_tx_type, INTRA_FILTER *best_filter,
2520 BLOCK_SIZE bsize, int rate_overhead, int64_t *best_rd) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002521 int this_rate;
2522 RD_STATS tokenonly_rd_stats;
2523 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002524 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002525 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
2526 if (tokenonly_rd_stats.rate == INT_MAX) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002527
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002528 this_rate = tokenonly_rd_stats.rate + rate_overhead;
2529 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_angle_delta = mbmi->angle_delta[0];
2534 *best_tx_size = mbmi->tx_size;
2535 *best_filter = mbmi->intra_filter;
2536 *best_tx_type = mbmi->tx_type;
2537 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002538 *rate_tokenonly = tokenonly_rd_stats.rate;
2539 *distortion = tokenonly_rd_stats.dist;
2540 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002541 }
2542}
2543
Urvang Joshi52648442016-10-13 17:27:51 -07002544static int64_t rd_pick_intra_angle_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2545 int *rate, int *rate_tokenonly,
2546 int64_t *distortion, int *skippable,
2547 BLOCK_SIZE bsize, int rate_overhead,
2548 int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002549 MACROBLOCKD *const xd = &x->e_mbd;
2550 MODE_INFO *const mic = xd->mi[0];
2551 MB_MODE_INFO *mbmi = &mic->mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002552 int this_rate;
2553 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002554 int angle_delta, best_angle_delta = 0, p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07002555 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002556 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
2557 const double rd_adjust = 1.2;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002558 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002559 TX_SIZE best_tx_size = mic->mbmi.tx_size;
2560 TX_TYPE best_tx_type = mbmi->tx_type;
2561
2562 if (ANGLE_FAST_SEARCH) {
2563 int deltas_level1[3] = { 0, -2, 2 };
2564 int deltas_level2[3][2] = {
2565 { -1, 1 }, { -3, -1 }, { 1, 3 },
2566 };
2567 const int level1 = 3, level2 = 2;
2568 int i, j, best_i = -1;
2569
2570 for (i = 0; i < level1; ++i) {
2571 mic->mbmi.angle_delta[0] = deltas_level1[i];
2572 p_angle =
2573 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
2574 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2575 int64_t tmp_best_rd;
Yaowu Xuf883b422016-08-30 14:01:10 -07002576 if ((FILTER_FAST_SEARCH || !av1_is_intra_filter_switchable(p_angle)) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002577 filter != INTRA_FILTER_LINEAR)
2578 continue;
2579 mic->mbmi.intra_filter = filter;
2580 tmp_best_rd =
2581 (i == 0 && filter == INTRA_FILTER_LINEAR && best_rd < INT64_MAX)
2582 ? (int64_t)(best_rd * rd_adjust)
2583 : best_rd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002584 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, tmp_best_rd);
2585 if (tokenonly_rd_stats.rate == INT_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002586 if (i == 0 && filter == INTRA_FILTER_LINEAR)
2587 return best_rd;
2588 else
2589 continue;
2590 }
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002591 this_rate = tokenonly_rd_stats.rate + rate_overhead +
Yaowu Xuc27fc142016-08-22 16:08:15 -07002592 cpi->intra_filter_cost[intra_filter_ctx][filter];
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002593 this_rd =
2594 RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002595 if (i == 0 && filter == INTRA_FILTER_LINEAR && best_rd < INT64_MAX &&
2596 this_rd > best_rd * rd_adjust)
2597 return best_rd;
2598 if (this_rd < best_rd) {
2599 best_i = i;
2600 best_rd = this_rd;
2601 best_angle_delta = mbmi->angle_delta[0];
2602 best_tx_size = mbmi->tx_size;
2603 best_filter = mbmi->intra_filter;
2604 best_tx_type = mbmi->tx_type;
2605 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002606 *rate_tokenonly = tokenonly_rd_stats.rate;
2607 *distortion = tokenonly_rd_stats.dist;
2608 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002609 }
2610 }
2611 }
2612
2613 if (best_i >= 0) {
2614 for (j = 0; j < level2; ++j) {
2615 mic->mbmi.angle_delta[0] = deltas_level2[best_i][j];
2616 p_angle =
2617 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
2618 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2619 mic->mbmi.intra_filter = filter;
2620 if ((FILTER_FAST_SEARCH ||
Yaowu Xuf883b422016-08-30 14:01:10 -07002621 !av1_is_intra_filter_switchable(p_angle)) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002622 filter != INTRA_FILTER_LINEAR)
2623 continue;
2624 pick_intra_angle_routine_sby(
2625 cpi, x, rate, rate_tokenonly, distortion, skippable,
2626 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
2627 bsize,
2628 rate_overhead + cpi->intra_filter_cost[intra_filter_ctx][filter],
2629 &best_rd);
2630 }
2631 }
2632 }
2633 } else {
2634 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
2635 ++angle_delta) {
2636 mbmi->angle_delta[0] = angle_delta;
2637 p_angle =
2638 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
2639 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2640 mic->mbmi.intra_filter = filter;
Yaowu Xuf883b422016-08-30 14:01:10 -07002641 if ((FILTER_FAST_SEARCH || !av1_is_intra_filter_switchable(p_angle)) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002642 filter != INTRA_FILTER_LINEAR)
2643 continue;
2644 pick_intra_angle_routine_sby(
2645 cpi, x, rate, rate_tokenonly, distortion, skippable,
2646 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
2647 bsize,
2648 rate_overhead + cpi->intra_filter_cost[intra_filter_ctx][filter],
2649 &best_rd);
2650 }
2651 }
2652 }
2653
2654 if (FILTER_FAST_SEARCH && *rate_tokenonly < INT_MAX) {
2655 mbmi->angle_delta[0] = best_angle_delta;
2656 p_angle = mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07002657 if (av1_is_intra_filter_switchable(p_angle)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002658 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
2659 mic->mbmi.intra_filter = filter;
2660 pick_intra_angle_routine_sby(
2661 cpi, x, rate, rate_tokenonly, distortion, skippable,
2662 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
2663 bsize,
2664 rate_overhead + cpi->intra_filter_cost[intra_filter_ctx][filter],
2665 &best_rd);
2666 }
2667 }
2668 }
2669
2670 mbmi->tx_size = best_tx_size;
2671 mbmi->angle_delta[0] = best_angle_delta;
2672 mic->mbmi.intra_filter = best_filter;
2673 mbmi->tx_type = best_tx_type;
2674 return best_rd;
2675}
2676
2677// Indices are sign, integer, and fractional part of the gradient value
2678static const uint8_t gradient_to_angle_bin[2][7][16] = {
2679 {
2680 { 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0 },
2681 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
2682 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
2683 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
2684 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
2685 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2686 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2687 },
2688 {
2689 { 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4 },
2690 { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3 },
2691 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2692 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2693 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2694 { 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2695 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2696 },
2697};
2698
2699static const uint8_t mode_to_angle_bin[INTRA_MODES] = {
2700 0, 2, 6, 0, 4, 3, 5, 7, 1, 0,
2701};
2702
2703static void angle_estimation(const uint8_t *src, int src_stride, int rows,
2704 int cols, uint8_t *directional_mode_skip_mask) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002705 int i, r, c, index, dx, dy, temp, sn, remd, quot;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002706 uint64_t hist[DIRECTIONAL_MODES];
2707 uint64_t hist_sum = 0;
2708
2709 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
2710 src += src_stride;
2711 for (r = 1; r < rows; ++r) {
2712 for (c = 1; c < cols; ++c) {
2713 dx = src[c] - src[c - 1];
2714 dy = src[c] - src[c - src_stride];
2715 temp = dx * dx + dy * dy;
2716 if (dy == 0) {
2717 index = 2;
2718 } else {
2719 sn = (dx > 0) ^ (dy > 0);
2720 dx = abs(dx);
2721 dy = abs(dy);
2722 remd = dx % dy;
2723 quot = dx / dy;
2724 remd = remd * 16 / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07002725 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002726 }
2727 hist[index] += temp;
2728 }
2729 src += src_stride;
2730 }
2731
2732 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
2733 for (i = 0; i < INTRA_MODES; ++i) {
2734 if (i != DC_PRED && i != TM_PRED) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002735 const uint8_t angle_bin = mode_to_angle_bin[i];
2736 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002737 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07002738 if (angle_bin > 0) {
2739 score += hist[angle_bin - 1];
2740 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002741 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07002742 if (angle_bin < DIRECTIONAL_MODES - 1) {
2743 score += hist[angle_bin + 1];
2744 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002745 }
2746 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
2747 directional_mode_skip_mask[i] = 1;
2748 }
2749 }
2750}
2751
Yaowu Xuf883b422016-08-30 14:01:10 -07002752#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002753static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
2754 int rows, int cols,
2755 uint8_t *directional_mode_skip_mask) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002756 int i, r, c, index, dx, dy, temp, sn, remd, quot;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002757 uint64_t hist[DIRECTIONAL_MODES];
2758 uint64_t hist_sum = 0;
2759 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
2760
2761 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
2762 src += src_stride;
2763 for (r = 1; r < rows; ++r) {
2764 for (c = 1; c < cols; ++c) {
2765 dx = src[c] - src[c - 1];
2766 dy = src[c] - src[c - src_stride];
2767 temp = dx * dx + dy * dy;
2768 if (dy == 0) {
2769 index = 2;
2770 } else {
2771 sn = (dx > 0) ^ (dy > 0);
2772 dx = abs(dx);
2773 dy = abs(dy);
2774 remd = dx % dy;
2775 quot = dx / dy;
2776 remd = remd * 16 / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07002777 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002778 }
2779 hist[index] += temp;
2780 }
2781 src += src_stride;
2782 }
2783
2784 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
2785 for (i = 0; i < INTRA_MODES; ++i) {
2786 if (i != DC_PRED && i != TM_PRED) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002787 const uint8_t angle_bin = mode_to_angle_bin[i];
2788 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002789 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07002790 if (angle_bin > 0) {
2791 score += hist[angle_bin - 1];
2792 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002793 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07002794 if (angle_bin < DIRECTIONAL_MODES - 1) {
2795 score += hist[angle_bin + 1];
2796 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002797 }
2798 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
2799 directional_mode_skip_mask[i] = 1;
2800 }
2801 }
2802}
Yaowu Xuf883b422016-08-30 14:01:10 -07002803#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002804#endif // CONFIG_EXT_INTRA
2805
2806// This function is used only for intra_only frames
Urvang Joshi52648442016-10-13 17:27:51 -07002807static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
2808 int *rate, int *rate_tokenonly,
2809 int64_t *distortion, int *skippable,
2810 BLOCK_SIZE bsize, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002811 uint8_t mode_idx;
2812 PREDICTION_MODE mode_selected = DC_PRED;
2813 MACROBLOCKD *const xd = &x->e_mbd;
2814 MODE_INFO *const mic = xd->mi[0];
2815 int this_rate, this_rate_tokenonly, s;
2816 int64_t this_distortion, this_rd;
2817 TX_SIZE best_tx = TX_4X4;
Urvang Joshib100db72016-10-12 16:28:56 -07002818#if CONFIG_EXT_INTRA || CONFIG_PALETTE
Jingning Hanae5cfde2016-11-30 12:01:44 -08002819 const int rows = block_size_high[bsize];
2820 const int cols = block_size_wide[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07002821#endif // CONFIG_EXT_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002822#if CONFIG_EXT_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07002823 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002824 int is_directional_mode, rate_overhead, best_angle_delta = 0;
2825 INTRA_FILTER best_filter = INTRA_FILTER_LINEAR;
2826 uint8_t directional_mode_skip_mask[INTRA_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002827 const int src_stride = x->plane[0].src.stride;
2828 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002829#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002830#if CONFIG_FILTER_INTRA
2831 int beat_best_rd = 0;
2832 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
2833 uint16_t filter_intra_mode_skip_mask = (1 << FILTER_INTRA_MODES) - 1;
2834#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002835 TX_TYPE best_tx_type = DCT_DCT;
Urvang Joshi52648442016-10-13 17:27:51 -07002836 const int *bmode_costs;
Urvang Joshib100db72016-10-12 16:28:56 -07002837#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002838 PALETTE_MODE_INFO palette_mode_info;
2839 PALETTE_MODE_INFO *const pmi = &mic->mbmi.palette_mode_info;
2840 uint8_t *best_palette_color_map =
2841 cpi->common.allow_screen_content_tools
2842 ? x->palette_buffer->best_palette_color_map
2843 : NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002844 int palette_ctx = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002845#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002846 const MODE_INFO *above_mi = xd->above_mi;
2847 const MODE_INFO *left_mi = xd->left_mi;
Yaowu Xuf883b422016-08-30 14:01:10 -07002848 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, 0);
2849 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002850 const PREDICTION_MODE FINAL_MODE_SEARCH = TM_PRED + 1;
2851 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
Yushin Cho77bba8d2016-11-04 16:36:56 -07002852#if CONFIG_PVQ
2853 od_rollback_buffer pre_buf, post_buf;
2854
2855 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2856 od_encode_checkpoint(&x->daala_enc, &post_buf);
2857#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002858 bmode_costs = cpi->y_mode_costs[A][L];
2859
2860#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002861 mic->mbmi.angle_delta[0] = 0;
2862 memset(directional_mode_skip_mask, 0,
2863 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
Yaowu Xuf883b422016-08-30 14:01:10 -07002864#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002865 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
2866 highbd_angle_estimation(src, src_stride, rows, cols,
2867 directional_mode_skip_mask);
2868 else
2869#endif
2870 angle_estimation(src, src_stride, rows, cols, directional_mode_skip_mask);
2871#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002872#if CONFIG_FILTER_INTRA
2873 filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2874 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2875#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07002876#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002877 palette_mode_info.palette_size[0] = 0;
2878 pmi->palette_size[0] = 0;
2879 if (above_mi)
2880 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
2881 if (left_mi)
2882 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Urvang Joshib100db72016-10-12 16:28:56 -07002883#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002884
2885 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
2886 x->use_default_intra_tx_type = 1;
2887 else
2888 x->use_default_intra_tx_type = 0;
2889
2890 /* Y Search for intra prediction mode */
2891 for (mode_idx = DC_PRED; mode_idx <= FINAL_MODE_SEARCH; ++mode_idx) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002892 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002893 if (mode_idx == FINAL_MODE_SEARCH) {
2894 if (x->use_default_intra_tx_type == 0) break;
2895 mic->mbmi.mode = mode_selected;
2896 x->use_default_intra_tx_type = 0;
2897 } else {
2898 mic->mbmi.mode = mode_idx;
2899 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07002900#if CONFIG_PVQ
2901 od_encode_rollback(&x->daala_enc, &pre_buf);
2902#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002903#if CONFIG_EXT_INTRA
2904 is_directional_mode =
2905 (mic->mbmi.mode != DC_PRED && mic->mbmi.mode != TM_PRED);
2906 if (is_directional_mode && directional_mode_skip_mask[mic->mbmi.mode])
2907 continue;
2908 if (is_directional_mode) {
2909 rate_overhead = bmode_costs[mic->mbmi.mode] +
2910 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
2911 this_rate_tokenonly = INT_MAX;
2912 this_rd = rd_pick_intra_angle_sby(cpi, x, &this_rate,
2913 &this_rate_tokenonly, &this_distortion,
2914 &s, bsize, rate_overhead, best_rd);
2915 } else {
2916 mic->mbmi.angle_delta[0] = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002917 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
2918 this_rate_tokenonly = this_rd_stats.rate;
2919 this_distortion = this_rd_stats.dist;
2920 s = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002921 }
2922#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002923 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
2924 this_rate_tokenonly = this_rd_stats.rate;
2925 this_distortion = this_rd_stats.dist;
2926 s = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002927#endif // CONFIG_EXT_INTRA
2928
2929 if (this_rate_tokenonly == INT_MAX) continue;
2930
2931 this_rate = this_rate_tokenonly + bmode_costs[mic->mbmi.mode];
2932
2933 if (!xd->lossless[xd->mi[0]->mbmi.segment_id]) {
2934 // super_block_yrd above includes the cost of the tx_size in the
2935 // tokenonly rate, but for intra blocks, tx_size is always coded
2936 // (prediction granularity), so we account for it in the full rate,
2937 // not the tokenonly rate.
2938 this_rate_tokenonly -=
clang-format67948d32016-09-07 22:40:40 -07002939 cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
Jingning Hanb0a71302016-10-25 16:28:49 -07002940 [tx_size_to_depth(mic->mbmi.tx_size)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002941 }
Urvang Joshib100db72016-10-12 16:28:56 -07002942#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002943 if (cpi->common.allow_screen_content_tools && mic->mbmi.mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07002944 this_rate += av1_cost_bit(
2945 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07002946#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07002947#if CONFIG_FILTER_INTRA
2948 if (mic->mbmi.mode == DC_PRED)
2949 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 0);
2950#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002951#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002952 if (is_directional_mode) {
2953 int p_angle;
2954 this_rate +=
2955 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
2956 MAX_ANGLE_DELTAS + mic->mbmi.angle_delta[0]);
2957 p_angle = mode_to_angle_map[mic->mbmi.mode] +
2958 mic->mbmi.angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07002959 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07002960 this_rate +=
2961 cpi->intra_filter_cost[intra_filter_ctx][mic->mbmi.intra_filter];
2962 }
2963#endif // CONFIG_EXT_INTRA
2964 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui su5db97432016-10-14 16:10:14 -07002965#if CONFIG_FILTER_INTRA
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07002966 if (best_rd == INT64_MAX || this_rd - best_rd < (best_rd >> 4)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002967 filter_intra_mode_skip_mask ^= (1 << mic->mbmi.mode);
2968 }
hui su5db97432016-10-14 16:10:14 -07002969#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002970
2971 if (this_rd < best_rd) {
2972 mode_selected = mic->mbmi.mode;
2973 best_rd = this_rd;
2974 best_tx = mic->mbmi.tx_size;
2975#if CONFIG_EXT_INTRA
2976 best_angle_delta = mic->mbmi.angle_delta[0];
2977 best_filter = mic->mbmi.intra_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002978#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002979#if CONFIG_FILTER_INTRA
2980 beat_best_rd = 1;
2981#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002982 best_tx_type = mic->mbmi.tx_type;
2983 *rate = this_rate;
2984 *rate_tokenonly = this_rate_tokenonly;
2985 *distortion = this_distortion;
2986 *skippable = s;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002987#if CONFIG_PVQ
2988 od_encode_checkpoint(&x->daala_enc, &post_buf);
2989#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002990 }
2991 }
2992
Yushin Cho77bba8d2016-11-04 16:36:56 -07002993#if CONFIG_PVQ
2994 od_encode_rollback(&x->daala_enc, &post_buf);
2995#endif
2996
Urvang Joshib100db72016-10-12 16:28:56 -07002997#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002998 if (cpi->common.allow_screen_content_tools)
2999 rd_pick_palette_intra_sby(cpi, x, bsize, palette_ctx, bmode_costs[DC_PRED],
3000 &palette_mode_info, best_palette_color_map,
3001 &best_tx, &best_tx_type, &mode_selected,
3002 &best_rd);
Urvang Joshib100db72016-10-12 16:28:56 -07003003#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003004
hui su5db97432016-10-14 16:10:14 -07003005#if CONFIG_FILTER_INTRA
3006 if (beat_best_rd) {
3007 if (rd_pick_filter_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
3008 skippable, bsize, bmode_costs[DC_PRED],
3009 &best_rd, filter_intra_mode_skip_mask)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003010 mode_selected = mic->mbmi.mode;
3011 best_tx = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07003012 filter_intra_mode_info = mic->mbmi.filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003013 best_tx_type = mic->mbmi.tx_type;
3014 }
3015 }
3016
hui su5db97432016-10-14 16:10:14 -07003017 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] =
3018 filter_intra_mode_info.use_filter_intra_mode[0];
3019 if (filter_intra_mode_info.use_filter_intra_mode[0]) {
3020 mic->mbmi.filter_intra_mode_info.filter_intra_mode[0] =
3021 filter_intra_mode_info.filter_intra_mode[0];
Urvang Joshib100db72016-10-12 16:28:56 -07003022#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003023 palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003024#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003025 }
hui su5db97432016-10-14 16:10:14 -07003026#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003027
3028 mic->mbmi.mode = mode_selected;
3029 mic->mbmi.tx_size = best_tx;
3030#if CONFIG_EXT_INTRA
3031 mic->mbmi.angle_delta[0] = best_angle_delta;
3032 mic->mbmi.intra_filter = best_filter;
3033#endif // CONFIG_EXT_INTRA
3034 mic->mbmi.tx_type = best_tx_type;
Urvang Joshib100db72016-10-12 16:28:56 -07003035#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003036 pmi->palette_size[0] = palette_mode_info.palette_size[0];
3037 if (palette_mode_info.palette_size[0] > 0) {
3038 memcpy(pmi->palette_colors, palette_mode_info.palette_colors,
3039 PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
3040 memcpy(xd->plane[0].color_index_map, best_palette_color_map,
3041 rows * cols * sizeof(best_palette_color_map[0]));
3042 }
Urvang Joshib100db72016-10-12 16:28:56 -07003043#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003044
3045 return best_rd;
3046}
3047
Yue Chena1e48dc2016-08-29 17:29:33 -07003048// Return value 0: early termination triggered, no valid rd cost available;
3049// 1: rd cost values are valid.
Angie Chiang284d7772016-11-08 11:06:45 -08003050static int super_block_uvrd(const AV1_COMP *const cpi, MACROBLOCK *x,
3051 RD_STATS *rd_stats, BLOCK_SIZE bsize,
3052 int64_t ref_best_rd) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003053 MACROBLOCKD *const xd = &x->e_mbd;
3054 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3055 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
3056 int plane;
Yue Chena1e48dc2016-08-29 17:29:33 -07003057 int is_cost_valid = 1;
Angie Chiang284d7772016-11-08 11:06:45 -08003058 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003059
3060 if (ref_best_rd < 0) is_cost_valid = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003061#if !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07003062 if (is_inter_block(mbmi) && is_cost_valid) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003063 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
3064 av1_subtract_plane(x, bsize, plane);
3065 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003066#endif
Yue Chena1e48dc2016-08-29 17:29:33 -07003067
Yushin Cho09de28b2016-06-21 14:51:23 -07003068 if (is_cost_valid) {
3069 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003070 RD_STATS pn_rd_stats;
3071 txfm_rd_in_plane(x, cpi, &pn_rd_stats, ref_best_rd, plane, bsize,
3072 uv_tx_size, cpi->sf.use_fast_coef_costing);
3073 if (pn_rd_stats.rate == INT_MAX) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003074 is_cost_valid = 0;
3075 break;
3076 }
Angie Chiang284d7772016-11-08 11:06:45 -08003077 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
3078 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003079 ref_best_rd &&
Angie Chiang284d7772016-11-08 11:06:45 -08003080 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse) > ref_best_rd) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003081 is_cost_valid = 0;
3082 break;
3083 }
Yue Chena1e48dc2016-08-29 17:29:33 -07003084 }
3085 }
3086
3087 if (!is_cost_valid) {
3088 // reset cost value
Angie Chiang284d7772016-11-08 11:06:45 -08003089 av1_invalid_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003090 }
3091
3092 return is_cost_valid;
3093}
3094
Yaowu Xuc27fc142016-08-22 16:08:15 -07003095#if CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07003096void av1_tx_block_rd_b(const AV1_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
3097 int blk_row, int blk_col, int plane, int block,
Angie Chiangb5dda482016-11-02 16:19:58 -07003098 int plane_bsize, int coeff_ctx, RD_STATS *rd_stats) {
Angie Chiang22ba7512016-10-20 17:10:33 -07003099 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003100 MACROBLOCKD *xd = &x->e_mbd;
3101 const struct macroblock_plane *const p = &x->plane[plane];
3102 struct macroblockd_plane *const pd = &xd->plane[plane];
3103 int64_t tmp;
3104 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
3105 PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
3106 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07003107 const SCAN_ORDER *const scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07003108 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003109 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
Jingning Han9fdc4222016-10-27 21:32:19 -07003110 int bh = block_size_high[txm_bsize];
3111 int bw = block_size_wide[txm_bsize];
3112 int txb_h = tx_size_high_unit[tx_size];
3113 int txb_w = tx_size_wide_unit[tx_size];
3114
Yaowu Xuc27fc142016-08-22 16:08:15 -07003115 int src_stride = p->src.stride;
3116 uint8_t *src = &p->src.buf[4 * blk_row * src_stride + 4 * blk_col];
3117 uint8_t *dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
Yaowu Xuf883b422016-08-30 14:01:10 -07003118#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003119 DECLARE_ALIGNED(16, uint16_t, rec_buffer16[MAX_TX_SQUARE]);
3120 uint8_t *rec_buffer;
3121#else
3122 DECLARE_ALIGNED(16, uint8_t, rec_buffer[MAX_TX_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07003123#endif // CONFIG_AOM_HIGHBITDEPTH
Jingning Han9fdc4222016-10-27 21:32:19 -07003124 int max_blocks_high = block_size_high[plane_bsize];
3125 int max_blocks_wide = block_size_wide[plane_bsize];
3126 const int diff_stride = max_blocks_wide;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003127 const int16_t *diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
Angie Chiangd81fdb42016-11-03 12:20:58 -07003128 int txb_coeff_cost;
Jingning Hand3fada82016-11-22 10:46:55 -08003129
3130 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003131
3132 if (xd->mb_to_bottom_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003133 max_blocks_high += xd->mb_to_bottom_edge >> (3 + pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003134 if (xd->mb_to_right_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003135 max_blocks_wide += xd->mb_to_right_edge >> (3 + pd->subsampling_x);
3136
3137 max_blocks_high >>= tx_size_wide_log2[0];
3138 max_blocks_wide >>= tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003139
3140#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08003141 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
3142 coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003143#else
Angie Chiangff6d8902016-10-21 11:02:09 -07003144 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08003145 coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003146#endif // CONFIG_NEW_QUANT
3147
Yushin Cho721868c2016-11-14 16:04:33 +09003148 // TODO(yushin) : If PVQ is enabled, this should not be called.
Angie Chiangff6d8902016-10-21 11:02:09 -07003149 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003150
3151// TODO(any): Use dist_block to compute distortion
Yaowu Xuf883b422016-08-30 14:01:10 -07003152#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003153 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3154 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer16);
Yaowu Xuf883b422016-08-30 14:01:10 -07003155 aom_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003156 0, NULL, 0, bw, bh, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003157 } else {
3158 rec_buffer = (uint8_t *)rec_buffer16;
Yaowu Xuf883b422016-08-30 14:01:10 -07003159 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0,
Jingning Han9fdc4222016-10-27 21:32:19 -07003160 NULL, 0, bw, bh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003161 }
3162#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003163 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003164 0, bw, bh);
Yaowu Xuf883b422016-08-30 14:01:10 -07003165#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003166
Jingning Han9fdc4222016-10-27 21:32:19 -07003167 if (blk_row + txb_h > max_blocks_high || blk_col + txb_w > max_blocks_wide) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003168 int idx, idy;
Jingning Han9fdc4222016-10-27 21:32:19 -07003169 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3170 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003171 tmp = 0;
3172 for (idy = 0; idy < blocks_height; idy += 2) {
3173 for (idx = 0; idx < blocks_width; idx += 2) {
3174 const int16_t *d = diff + 4 * idy * diff_stride + 4 * idx;
Yaowu Xuf883b422016-08-30 14:01:10 -07003175 tmp += aom_sum_squares_2d_i16(d, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003176 }
3177 }
3178 } else {
Jingning Han9fdc4222016-10-27 21:32:19 -07003179 tmp = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003180 }
3181
Yaowu Xuf883b422016-08-30 14:01:10 -07003182#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003183 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
3184 tmp = ROUND_POWER_OF_TWO(tmp, (xd->bd - 8) * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07003185#endif // CONFIG_AOM_HIGHBITDEPTH
Angie Chiangb5dda482016-11-02 16:19:58 -07003186 rd_stats->sse += tmp * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003187
3188 if (p->eobs[block] > 0) {
3189 INV_TXFM_PARAM inv_txfm_param;
3190 inv_txfm_param.tx_type = tx_type;
3191 inv_txfm_param.tx_size = tx_size;
3192 inv_txfm_param.eob = p->eobs[block];
3193 inv_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
Yushin Cho721868c2016-11-14 16:04:33 +09003194// TODO(yushin) : If PVQ is enabled, rec_buffer needs be set as zeros.
Yaowu Xuf883b422016-08-30 14:01:10 -07003195#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003196 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3197 inv_txfm_param.bd = xd->bd;
3198 highbd_inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
3199 } else {
3200 inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
3201 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003202#else // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003203 inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
Yaowu Xuf883b422016-08-30 14:01:10 -07003204#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003205
Jingning Han4b47c932016-11-03 09:20:08 -07003206 if (txb_w + blk_col > max_blocks_wide ||
3207 txb_h + blk_row > max_blocks_high) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003208 int idx, idy;
3209 unsigned int this_dist;
Jingning Han9fdc4222016-10-27 21:32:19 -07003210 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3211 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003212 tmp = 0;
3213 for (idy = 0; idy < blocks_height; idy += 2) {
3214 for (idx = 0; idx < blocks_width; idx += 2) {
3215 uint8_t *const s = src + 4 * idy * src_stride + 4 * idx;
3216 uint8_t *const r = rec_buffer + 4 * idy * MAX_TX_SIZE + 4 * idx;
3217 cpi->fn_ptr[BLOCK_8X8].vf(s, src_stride, r, MAX_TX_SIZE, &this_dist);
3218 tmp += this_dist;
3219 }
3220 }
3221 } else {
3222 uint32_t this_dist;
3223 cpi->fn_ptr[txm_bsize].vf(src, src_stride, rec_buffer, MAX_TX_SIZE,
3224 &this_dist);
3225 tmp = this_dist;
3226 }
3227 }
Angie Chiangb5dda482016-11-02 16:19:58 -07003228 rd_stats->dist += tmp * 16;
Angie Chiangd81fdb42016-11-03 12:20:58 -07003229 txb_coeff_cost = av1_cost_coeffs(cm, x, plane, block, coeff_ctx, tx_size,
3230 scan_order->scan, scan_order->neighbors, 0);
3231 rd_stats->rate += txb_coeff_cost;
Angie Chiangb5dda482016-11-02 16:19:58 -07003232 rd_stats->skip &= (p->eobs[block] == 0);
Jingning Han63cbf342016-11-09 15:37:48 -08003233
Angie Chiangd81fdb42016-11-03 12:20:58 -07003234#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08003235 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
3236 txb_coeff_cost);
Angie Chiangd81fdb42016-11-03 12:20:58 -07003237#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003238}
3239
Yaowu Xuf883b422016-08-30 14:01:10 -07003240static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Jingning Han63cbf342016-11-09 15:37:48 -08003241 int blk_col, int plane, int block, int block32,
3242 TX_SIZE tx_size, int depth, BLOCK_SIZE plane_bsize,
Jingning Han94d5bfc2016-10-21 10:14:36 -07003243 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
3244 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
Angie Chiangb5dda482016-11-02 16:19:58 -07003245 RD_STATS *rd_stats, int64_t ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08003246 int *is_cost_valid, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003247 MACROBLOCKD *const xd = &x->e_mbd;
3248 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3249 struct macroblock_plane *const p = &x->plane[plane];
3250 struct macroblockd_plane *const pd = &xd->plane[plane];
3251 const int tx_row = blk_row >> (1 - pd->subsampling_y);
3252 const int tx_col = blk_col >> (1 - pd->subsampling_x);
clang-format67948d32016-09-07 22:40:40 -07003253 TX_SIZE(*const inter_tx_size)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003254 [MAX_MIB_SIZE] =
3255 (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
Jingning Hanf65b8702016-10-31 12:13:20 -07003256 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
3257 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Jingning Han58224042016-10-27 16:35:32 -07003258 const int bw = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003259 int64_t this_rd = INT64_MAX;
3260 ENTROPY_CONTEXT *pta = ta + blk_col;
3261 ENTROPY_CONTEXT *ptl = tl + blk_row;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003262 int coeff_ctx, i;
Jingning Hanc8b89362016-11-01 10:28:53 -07003263 int ctx =
3264 txfm_partition_context(tx_above + (blk_col >> 1),
3265 tx_left + (blk_row >> 1), mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003266 int64_t sum_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003267 int tmp_eob = 0;
3268 int zero_blk_rate;
Angie Chiangd7246172016-11-03 11:49:15 -07003269 RD_STATS sum_rd_stats;
Jingning Han1c019f92016-11-21 12:53:32 -08003270 const int tx_size_ctx = txsize_sqr_map[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003271
Jingning Han63cbf342016-11-09 15:37:48 -08003272 av1_init_rd_stats(&sum_rd_stats);
Jingning Hanfe45b212016-11-22 10:30:23 -08003273
Jingning Hand3fada82016-11-22 10:46:55 -08003274 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003275
3276 if (ref_best_rd < 0) {
3277 *is_cost_valid = 0;
3278 return;
3279 }
3280
Jingning Hance059e82016-10-31 16:27:28 -07003281 coeff_ctx = get_entropy_context(tx_size, pta, ptl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003282
Angie Chiangc0feea82016-11-03 15:36:18 -07003283 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003284
3285 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
3286
Jingning Han1c019f92016-11-21 12:53:32 -08003287 zero_blk_rate = x->token_costs[tx_size_ctx][pd->plane_type][1][0][0]
3288 [coeff_ctx][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003289
3290 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
3291 inter_tx_size[0][0] = tx_size;
Jingning Han63cbf342016-11-09 15:37:48 -08003292
3293 if (tx_size == TX_32X32 && mbmi->tx_type != DCT_DCT &&
3294 rd_stats_stack[block32].rate != INT_MAX) {
3295 *rd_stats = rd_stats_stack[block32];
3296 p->eobs[block] = !rd_stats->skip;
3297 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
3298 } else {
3299 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
3300 plane_bsize, coeff_ctx, rd_stats);
3301 if (tx_size == TX_32X32) {
3302 rd_stats_stack[block32] = *rd_stats;
3303 }
3304 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003305
Angie Chiangb5dda482016-11-02 16:19:58 -07003306 if ((RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >=
3307 RDCOST(x->rdmult, x->rddiv, zero_blk_rate, rd_stats->sse) ||
3308 rd_stats->skip == 1) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003309 !xd->lossless[mbmi->segment_id]) {
Angie Chiangb5dda482016-11-02 16:19:58 -07003310 rd_stats->rate = zero_blk_rate;
3311 rd_stats->dist = rd_stats->sse;
3312 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003313 x->blk_skip[plane][blk_row * bw + blk_col] = 1;
3314 p->eobs[block] = 0;
3315 } else {
3316 x->blk_skip[plane][blk_row * bw + blk_col] = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07003317 rd_stats->skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003318 }
3319
Jingning Han571189c2016-10-24 10:38:43 -07003320 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH)
Angie Chiangb5dda482016-11-02 16:19:58 -07003321 rd_stats->rate +=
3322 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
3323 this_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003324 tmp_eob = p->eobs[block];
3325 }
3326
Jingning Han571189c2016-10-24 10:38:43 -07003327 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH) {
Jingning Han18482fe2016-11-02 17:01:58 -07003328 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
3329 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07003330 int sub_step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Angie Chiangb5dda482016-11-02 16:19:58 -07003331 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003332 int this_cost_valid = 1;
3333 int64_t tmp_rd = 0;
3334
Angie Chiangd7246172016-11-03 11:49:15 -07003335 sum_rd_stats.rate =
3336 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Jingning Hand3fada82016-11-22 10:46:55 -08003337
3338 assert(tx_size < TX_SIZES_ALL);
3339
Yaowu Xuc27fc142016-08-22 16:08:15 -07003340 for (i = 0; i < 4 && this_cost_valid; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07003341 int offsetr = blk_row + (i >> 1) * bsl;
3342 int offsetc = blk_col + (i & 0x01) * bsl;
3343
3344 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
3345
Jingning Han63cbf342016-11-09 15:37:48 -08003346 select_tx_block(cpi, x, offsetr, offsetc, plane, block, block32, sub_txs,
Jingning Han98d6a1f2016-11-03 12:47:47 -07003347 depth + 1, plane_bsize, ta, tl, tx_above, tx_left,
Jingning Han63cbf342016-11-09 15:37:48 -08003348 &this_rd_stats, ref_best_rd - tmp_rd, &this_cost_valid,
3349 rd_stats_stack);
Jingning Han98d6a1f2016-11-03 12:47:47 -07003350
Angie Chiangc0feea82016-11-03 15:36:18 -07003351 av1_merge_rd_stats(&sum_rd_stats, &this_rd_stats);
Jingning Han98d6a1f2016-11-03 12:47:47 -07003352
Angie Chiangd7246172016-11-03 11:49:15 -07003353 tmp_rd =
3354 RDCOST(x->rdmult, x->rddiv, sum_rd_stats.rate, sum_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003355 if (this_rd < tmp_rd) break;
Jingning Han98d6a1f2016-11-03 12:47:47 -07003356 block += sub_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003357 }
3358 if (this_cost_valid) sum_rd = tmp_rd;
3359 }
3360
3361 if (this_rd < sum_rd) {
3362 int idx, idy;
Jingning Han58224042016-10-27 16:35:32 -07003363 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) pta[i] = !(tmp_eob == 0);
3364 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) ptl[i] = !(tmp_eob == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003365 txfm_partition_update(tx_above + (blk_col >> 1), tx_left + (blk_row >> 1),
3366 tx_size);
3367 inter_tx_size[0][0] = tx_size;
Jingning Han58224042016-10-27 16:35:32 -07003368 for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
3369 for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003370 inter_tx_size[idy][idx] = tx_size;
3371 mbmi->tx_size = tx_size;
3372 if (this_rd == INT64_MAX) *is_cost_valid = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07003373 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003374 } else {
Angie Chiangd7246172016-11-03 11:49:15 -07003375 *rd_stats = sum_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003376 if (sum_rd == INT64_MAX) *is_cost_valid = 0;
3377 }
3378}
3379
Angie Chiangb5dda482016-11-02 16:19:58 -07003380static void inter_block_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
3381 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08003382 int64_t ref_best_rd, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003383 MACROBLOCKD *const xd = &x->e_mbd;
3384 int is_cost_valid = 1;
3385 int64_t this_rd = 0;
3386
3387 if (ref_best_rd < 0) is_cost_valid = 0;
3388
Angie Chiangc0feea82016-11-03 15:36:18 -07003389 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003390
3391 if (is_cost_valid) {
3392 const struct macroblockd_plane *const pd = &xd->plane[0];
3393 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
3394 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
3395 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han70e5f3f2016-11-09 17:03:07 -08003396 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07003397 const int bh = tx_size_high_unit[max_tx_size];
3398 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003399 int idx, idy;
3400 int block = 0;
Jingning Han63cbf342016-11-09 15:37:48 -08003401 int block32 = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07003402 int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003403 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
3404 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
3405 TXFM_CONTEXT tx_above[MAX_MIB_SIZE];
3406 TXFM_CONTEXT tx_left[MAX_MIB_SIZE];
3407
Angie Chiangb5dda482016-11-02 16:19:58 -07003408 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07003409 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003410
Yaowu Xuf883b422016-08-30 14:01:10 -07003411 av1_get_entropy_contexts(bsize, TX_4X4, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003412 memcpy(tx_above, xd->above_txfm_context,
3413 sizeof(TXFM_CONTEXT) * (mi_width >> 1));
3414 memcpy(tx_left, xd->left_txfm_context,
3415 sizeof(TXFM_CONTEXT) * (mi_height >> 1));
3416
3417 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07003418 for (idx = 0; idx < mi_width; idx += bw) {
Jingning Han63cbf342016-11-09 15:37:48 -08003419 select_tx_block(cpi, x, idy, idx, 0, block, block32, max_tx_size,
Jingning Han18482fe2016-11-02 17:01:58 -07003420 mi_height != mi_width, plane_bsize, ctxa, ctxl,
Angie Chiangb5dda482016-11-02 16:19:58 -07003421 tx_above, tx_left, &pn_rd_stats, ref_best_rd - this_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08003422 &is_cost_valid, rd_stats_stack);
Angie Chiangc0feea82016-11-03 15:36:18 -07003423 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Angie Chiangb5dda482016-11-02 16:19:58 -07003424 this_rd += AOMMIN(
3425 RDCOST(x->rdmult, x->rddiv, pn_rd_stats.rate, pn_rd_stats.dist),
3426 RDCOST(x->rdmult, x->rddiv, 0, pn_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003427 block += step;
Jingning Han63cbf342016-11-09 15:37:48 -08003428 ++block32;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003429 }
3430 }
3431 }
3432
Angie Chiangb5dda482016-11-02 16:19:58 -07003433 this_rd = AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
3434 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003435 if (this_rd > ref_best_rd) is_cost_valid = 0;
3436
3437 if (!is_cost_valid) {
3438 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07003439 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003440 }
3441}
3442
Yaowu Xuf883b422016-08-30 14:01:10 -07003443static int64_t select_tx_size_fix_type(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiangb5dda482016-11-02 16:19:58 -07003444 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08003445 int64_t ref_best_rd, TX_TYPE tx_type,
3446 RD_STATS *rd_stats_stack) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003447 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003448 MACROBLOCKD *const xd = &x->e_mbd;
3449 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003450 const int is_inter = is_inter_block(mbmi);
Yaowu Xuf883b422016-08-30 14:01:10 -07003451 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
3452 int s0 = av1_cost_bit(skip_prob, 0);
3453 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003454 int64_t rd;
Jingning Hane67b38a2016-11-04 10:30:00 -07003455 int row, col;
3456 const int max_blocks_high = max_block_high(xd, bsize, 0);
3457 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003458
3459 mbmi->tx_type = tx_type;
Jingning Hane67b38a2016-11-04 10:30:00 -07003460 mbmi->min_tx_size = TX_SIZES_ALL;
Jingning Han63cbf342016-11-09 15:37:48 -08003461 inter_block_yrd(cpi, x, rd_stats, bsize, ref_best_rd, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003462
Angie Chiangb5dda482016-11-02 16:19:58 -07003463 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003464
Jingning Hane67b38a2016-11-04 10:30:00 -07003465 for (row = 0; row < max_blocks_high / 2; ++row)
3466 for (col = 0; col < max_blocks_wide / 2; ++col)
3467 mbmi->min_tx_size = AOMMIN(
3468 mbmi->min_tx_size, get_min_tx_size(mbmi->inter_tx_size[row][col]));
3469
Yaowu Xuc27fc142016-08-22 16:08:15 -07003470#if CONFIG_EXT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07003471 if (get_ext_tx_types(mbmi->min_tx_size, bsize, is_inter) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003472 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Jingning Hane67b38a2016-11-04 10:30:00 -07003473 int ext_tx_set = get_ext_tx_set(mbmi->min_tx_size, bsize, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003474 if (is_inter) {
3475 if (ext_tx_set > 0)
Angie Chiangb5dda482016-11-02 16:19:58 -07003476 rd_stats->rate +=
Jingning Hane67b38a2016-11-04 10:30:00 -07003477 cpi->inter_tx_type_costs[ext_tx_set]
3478 [txsize_sqr_map[mbmi->min_tx_size]]
Peter de Rivazb85a5a72016-10-18 11:47:56 +01003479 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003480 } else {
3481 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Jingning Hane67b38a2016-11-04 10:30:00 -07003482 rd_stats->rate +=
3483 cpi->intra_tx_type_costs[ext_tx_set][mbmi->min_tx_size][mbmi->mode]
3484 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003485 }
3486 }
3487#else // CONFIG_EXT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07003488 if (mbmi->min_tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id])
3489 rd_stats->rate +=
3490 cpi->inter_tx_type_costs[mbmi->min_tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003491#endif // CONFIG_EXT_TX
3492
Angie Chiangb5dda482016-11-02 16:19:58 -07003493 if (rd_stats->skip)
3494 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003495 else
Angie Chiangb5dda482016-11-02 16:19:58 -07003496 rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate + s0, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003497
Angie Chiangb5dda482016-11-02 16:19:58 -07003498 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
3499 !(rd_stats->skip))
3500 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003501
3502 return rd;
3503}
3504
Angie Chiangb5dda482016-11-02 16:19:58 -07003505static void select_tx_type_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
3506 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003507 int64_t ref_best_rd) {
3508 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
3509 MACROBLOCKD *const xd = &x->e_mbd;
3510 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3511 int64_t rd = INT64_MAX;
3512 int64_t best_rd = INT64_MAX;
3513 TX_TYPE tx_type, best_tx_type = DCT_DCT;
3514 const int is_inter = is_inter_block(mbmi);
3515 TX_SIZE best_tx_size[MAX_MIB_SIZE][MAX_MIB_SIZE];
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07003516 TX_SIZE best_tx = max_txsize_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07003517 TX_SIZE best_min_tx_size = TX_SIZES_ALL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003518 uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
3519 const int n4 = 1 << (num_pels_log2_lookup[bsize] - 4);
3520 int idx, idy;
3521 int prune = 0;
Jingning Han89d648b2016-11-22 11:22:08 -08003522 const int count32 = 1 << (2 * (cpi->common.mib_size_log2 -
3523 mi_width_log2_lookup[BLOCK_32X32]));
3524#if CONFIG_EXT_PARTITION
3525 RD_STATS rd_stats_stack[16];
3526#else
Jingning Han63cbf342016-11-09 15:37:48 -08003527 RD_STATS rd_stats_stack[4];
Jingning Han89d648b2016-11-22 11:22:08 -08003528#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003529#if CONFIG_EXT_TX
3530 int ext_tx_set = get_ext_tx_set(max_tx_size, bsize, is_inter);
3531#endif // CONFIG_EXT_TX
3532
3533 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
3534#if CONFIG_EXT_TX
3535 prune = prune_tx_types(cpi, bsize, x, xd, ext_tx_set);
3536#else
3537 prune = prune_tx_types(cpi, bsize, x, xd, 0);
3538#endif
3539
Angie Chiangc0feea82016-11-03 15:36:18 -07003540 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003541
Jingning Han89d648b2016-11-22 11:22:08 -08003542 for (idx = 0; idx < count32; ++idx)
3543 av1_invalid_rd_stats(&rd_stats_stack[idx]);
Jingning Han63cbf342016-11-09 15:37:48 -08003544
Yaowu Xuc27fc142016-08-22 16:08:15 -07003545 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiangb5dda482016-11-02 16:19:58 -07003546 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07003547 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003548#if CONFIG_EXT_TX
3549 if (is_inter) {
3550 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
3551 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
3552 if (!do_tx_type_search(tx_type, prune)) continue;
3553 }
3554 } else {
3555 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
3556 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
3557 }
3558 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
3559 }
3560#else // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003561 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
3562 !do_tx_type_search(tx_type, prune))
3563 continue;
3564#endif // CONFIG_EXT_TX
3565 if (is_inter && x->use_default_inter_tx_type &&
3566 tx_type != get_default_tx_type(0, xd, 0, max_tx_size))
3567 continue;
3568
Jingning Hane67b38a2016-11-04 10:30:00 -07003569 if (xd->lossless[mbmi->segment_id])
3570 if (tx_type != DCT_DCT) continue;
3571
Angie Chiangb5dda482016-11-02 16:19:58 -07003572 rd = select_tx_size_fix_type(cpi, x, &this_rd_stats, bsize, ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08003573 tx_type, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003574
3575 if (rd < best_rd) {
3576 best_rd = rd;
Angie Chiangb5dda482016-11-02 16:19:58 -07003577 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003578 best_tx_type = mbmi->tx_type;
3579 best_tx = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -07003580 best_min_tx_size = mbmi->min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003581 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
3582 for (idy = 0; idy < xd->n8_h; ++idy)
3583 for (idx = 0; idx < xd->n8_w; ++idx)
3584 best_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
3585 }
3586 }
3587
3588 mbmi->tx_type = best_tx_type;
3589 for (idy = 0; idy < xd->n8_h; ++idy)
3590 for (idx = 0; idx < xd->n8_w; ++idx)
3591 mbmi->inter_tx_size[idy][idx] = best_tx_size[idy][idx];
3592 mbmi->tx_size = best_tx;
Jingning Hane67b38a2016-11-04 10:30:00 -07003593 mbmi->min_tx_size = best_min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003594 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
3595}
3596
Yaowu Xuf883b422016-08-30 14:01:10 -07003597static void tx_block_rd(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003598 int blk_col, int plane, int block, TX_SIZE tx_size,
3599 BLOCK_SIZE plane_bsize, ENTROPY_CONTEXT *above_ctx,
Angie Chiangb5dda482016-11-02 16:19:58 -07003600 ENTROPY_CONTEXT *left_ctx, RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003601 MACROBLOCKD *const xd = &x->e_mbd;
3602 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3603 struct macroblock_plane *const p = &x->plane[plane];
3604 struct macroblockd_plane *const pd = &xd->plane[plane];
3605 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
3606 const int tx_row = blk_row >> (1 - pd->subsampling_y);
3607 const int tx_col = blk_col >> (1 - pd->subsampling_x);
3608 TX_SIZE plane_tx_size;
Jingning Han18482fe2016-11-02 17:01:58 -07003609 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
3610 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003611
Jingning Hand3fada82016-11-22 10:46:55 -08003612 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003613
Yaowu Xuc27fc142016-08-22 16:08:15 -07003614 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
3615
Debargha Mukherjee2f123402016-08-30 17:43:38 -07003616 plane_tx_size =
3617 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
3618 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003619
3620 if (tx_size == plane_tx_size) {
3621 int coeff_ctx, i;
3622 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
3623 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
Jingning Han18482fe2016-11-02 17:01:58 -07003624 coeff_ctx = get_entropy_context(tx_size, ta, tl);
Yaowu Xuf883b422016-08-30 14:01:10 -07003625 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiangb5dda482016-11-02 16:19:58 -07003626 plane_bsize, coeff_ctx, rd_stats);
Jingning Han607fa6a2016-10-26 10:46:28 -07003627
Jingning Han58224042016-10-27 16:35:32 -07003628 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003629 ta[i] = !(p->eobs[block] == 0);
Jingning Han58224042016-10-27 16:35:32 -07003630 for (i = 0; i < tx_size_high_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003631 tl[i] = !(p->eobs[block] == 0);
3632 } else {
Jingning Han18482fe2016-11-02 17:01:58 -07003633 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
3634 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07003635 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003636 int i;
3637
3638 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003639
3640 for (i = 0; i < 4; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07003641 int offsetr = blk_row + (i >> 1) * bsl;
3642 int offsetc = blk_col + (i & 0x01) * bsl;
3643
3644 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
3645
3646 tx_block_rd(cpi, x, offsetr, offsetc, plane, block, sub_txs, plane_bsize,
3647 above_ctx, left_ctx, rd_stats);
3648 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003649 }
3650 }
3651}
3652
3653// Return value 0: early termination triggered, no valid rd cost available;
3654// 1: rd cost values are valid.
Angie Chiangb5dda482016-11-02 16:19:58 -07003655static int inter_block_uvrd(const AV1_COMP *cpi, MACROBLOCK *x,
3656 RD_STATS *rd_stats, BLOCK_SIZE bsize,
3657 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003658 MACROBLOCKD *const xd = &x->e_mbd;
3659 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3660 int plane;
3661 int is_cost_valid = 1;
3662 int64_t this_rd;
3663
3664 if (ref_best_rd < 0) is_cost_valid = 0;
3665
Angie Chiangc0feea82016-11-03 15:36:18 -07003666 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003667
3668#if CONFIG_EXT_TX && CONFIG_RECT_TX
3669 if (is_rect_tx(mbmi->tx_size)) {
Angie Chiang284d7772016-11-08 11:06:45 -08003670 return super_block_uvrd(cpi, x, rd_stats, bsize, ref_best_rd);
Yue Chena1e48dc2016-08-29 17:29:33 -07003671 }
3672#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
3673
Yaowu Xuc27fc142016-08-22 16:08:15 -07003674 if (is_inter_block(mbmi) && is_cost_valid) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003675 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
Yaowu Xuf883b422016-08-30 14:01:10 -07003676 av1_subtract_plane(x, bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003677 }
3678
Yaowu Xuc27fc142016-08-22 16:08:15 -07003679 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
3680 const struct macroblockd_plane *const pd = &xd->plane[plane];
3681 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
3682 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
3683 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han70e5f3f2016-11-09 17:03:07 -08003684 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07003685 const int bh = tx_size_high_unit[max_tx_size];
3686 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003687 int idx, idy;
3688 int block = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07003689 const int step = bh * bw;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003690 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE];
3691 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE];
Angie Chiangb5dda482016-11-02 16:19:58 -07003692 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07003693 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003694
Yaowu Xuf883b422016-08-30 14:01:10 -07003695 av1_get_entropy_contexts(bsize, TX_4X4, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003696
3697 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07003698 for (idx = 0; idx < mi_width; idx += bw) {
3699 tx_block_rd(cpi, x, idy, idx, plane, block, max_tx_size, plane_bsize,
Angie Chiangb5dda482016-11-02 16:19:58 -07003700 ta, tl, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003701 block += step;
3702 }
3703 }
3704
Angie Chiangb5dda482016-11-02 16:19:58 -07003705 if (pn_rd_stats.rate == INT_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003706 is_cost_valid = 0;
3707 break;
3708 }
3709
Angie Chiang628d7c92016-11-03 16:24:56 -07003710 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003711
Angie Chiangb5dda482016-11-02 16:19:58 -07003712 this_rd =
3713 AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
3714 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003715
3716 if (this_rd > ref_best_rd) {
3717 is_cost_valid = 0;
3718 break;
3719 }
3720 }
3721
3722 if (!is_cost_valid) {
3723 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07003724 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003725 }
3726
3727 return is_cost_valid;
3728}
3729#endif // CONFIG_VAR_TX
3730
Urvang Joshib100db72016-10-12 16:28:56 -07003731#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003732static void rd_pick_palette_intra_sbuv(
Urvang Joshi52648442016-10-13 17:27:51 -07003733 const AV1_COMP *const cpi, MACROBLOCK *x, int dc_mode_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003734 PALETTE_MODE_INFO *palette_mode_info, uint8_t *best_palette_color_map,
3735 PREDICTION_MODE *mode_selected, int64_t *best_rd, int *rate,
3736 int *rate_tokenonly, int64_t *distortion, int *skippable) {
3737 MACROBLOCKD *const xd = &x->e_mbd;
3738 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3739 const BLOCK_SIZE bsize = mbmi->sb_type;
Jingning Hanae5cfde2016-11-30 12:01:44 -08003740 const int rows = block_size_high[bsize] >> (xd->plane[1].subsampling_y);
3741 const int cols = block_size_wide[bsize] >> (xd->plane[1].subsampling_x);
Angie Chiang284d7772016-11-08 11:06:45 -08003742 int this_rate;
3743 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003744 int colors_u, colors_v, colors;
3745 const int src_stride = x->plane[1].src.stride;
3746 const uint8_t *const src_u = x->plane[1].src.buf;
3747 const uint8_t *const src_v = x->plane[2].src.buf;
Angie Chiang284d7772016-11-08 11:06:45 -08003748 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003749
3750 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return;
3751
hui su5db97432016-10-14 16:10:14 -07003752#if CONFIG_FILTER_INTRA
3753 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
3754#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003755
Yaowu Xuf883b422016-08-30 14:01:10 -07003756#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003757 if (cpi->common.use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003758 colors_u = av1_count_colors_highbd(src_u, src_stride, rows, cols,
3759 cpi->common.bit_depth);
3760 colors_v = av1_count_colors_highbd(src_v, src_stride, rows, cols,
3761 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003762 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003763#endif // CONFIG_AOM_HIGHBITDEPTH
3764 colors_u = av1_count_colors(src_u, src_stride, rows, cols);
3765 colors_v = av1_count_colors(src_v, src_stride, rows, cols);
3766#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003767 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003768#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003769
3770 colors = colors_u > colors_v ? colors_u : colors_v;
3771 if (colors > 1 && colors <= 64) {
3772 int r, c, n, i, j;
3773 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07003774 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003775 float lb_u, ub_u, val_u;
3776 float lb_v, ub_v, val_v;
3777 float *const data = x->palette_buffer->kmeans_data_buf;
3778 float centroids[2 * PALETTE_MAX_SIZE];
3779 uint8_t *const color_map = xd->plane[1].color_index_map;
3780 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
3781
Yaowu Xuf883b422016-08-30 14:01:10 -07003782#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003783 uint16_t *src_u16 = CONVERT_TO_SHORTPTR(src_u);
3784 uint16_t *src_v16 = CONVERT_TO_SHORTPTR(src_v);
3785 if (cpi->common.use_highbitdepth) {
3786 lb_u = src_u16[0];
3787 ub_u = src_u16[0];
3788 lb_v = src_v16[0];
3789 ub_v = src_v16[0];
3790 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003791#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003792 lb_u = src_u[0];
3793 ub_u = src_u[0];
3794 lb_v = src_v[0];
3795 ub_v = src_v[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07003796#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003797 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003798#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003799
3800 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07003801#if CONFIG_FILTER_INTRA
3802 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
3803#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003804 for (r = 0; r < rows; ++r) {
3805 for (c = 0; c < cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003806#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003807 if (cpi->common.use_highbitdepth) {
3808 val_u = src_u16[r * src_stride + c];
3809 val_v = src_v16[r * src_stride + c];
3810 data[(r * cols + c) * 2] = val_u;
3811 data[(r * cols + c) * 2 + 1] = val_v;
3812 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003813#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003814 val_u = src_u[r * src_stride + c];
3815 val_v = src_v[r * src_stride + c];
3816 data[(r * cols + c) * 2] = val_u;
3817 data[(r * cols + c) * 2 + 1] = val_v;
Yaowu Xuf883b422016-08-30 14:01:10 -07003818#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003819 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003820#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003821 if (val_u < lb_u)
3822 lb_u = val_u;
3823 else if (val_u > ub_u)
3824 ub_u = val_u;
3825 if (val_v < lb_v)
3826 lb_v = val_v;
3827 else if (val_v > ub_v)
3828 ub_v = val_v;
3829 }
3830 }
3831
3832 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
3833 --n) {
3834 for (i = 0; i < n; ++i) {
3835 centroids[i * 2] = lb_u + (2 * i + 1) * (ub_u - lb_u) / n / 2;
3836 centroids[i * 2 + 1] = lb_v + (2 * i + 1) * (ub_v - lb_v) / n / 2;
3837 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003838 av1_k_means(data, centroids, color_map, rows * cols, n, 2, max_itr);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003839 pmi->palette_size[1] = n;
3840 for (i = 1; i < 3; ++i) {
3841 for (j = 0; j < n; ++j) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003842#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003843 if (cpi->common.use_highbitdepth)
3844 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] = clip_pixel_highbd(
3845 (int)centroids[j * 2 + i - 1], cpi->common.bit_depth);
3846 else
Yaowu Xuf883b422016-08-30 14:01:10 -07003847#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003848 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
3849 clip_pixel((int)centroids[j * 2 + i - 1]);
3850 }
3851 }
3852
Angie Chiang284d7772016-11-08 11:06:45 -08003853 super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
3854 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003855 this_rate =
Angie Chiang284d7772016-11-08 11:06:45 -08003856 tokenonly_rd_stats.rate + dc_mode_cost +
Yaowu Xuf883b422016-08-30 14:01:10 -07003857 2 * cpi->common.bit_depth * n * av1_cost_bit(128, 0) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003858 cpi->palette_uv_size_cost[bsize - BLOCK_8X8][n - 2] +
3859 write_uniform_cost(n, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07003860 av1_cost_bit(
3861 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003862
3863 for (i = 0; i < rows; ++i) {
3864 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07003865 int color_idx;
3866 const int color_ctx = av1_get_palette_color_context(
3867 color_map, cols, i, j, n, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003868 assert(color_idx >= 0 && color_idx < n);
3869 this_rate += cpi->palette_uv_color_cost[n - 2][color_ctx][color_idx];
3870 }
3871 }
3872
Angie Chiang284d7772016-11-08 11:06:45 -08003873 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003874 if (this_rd < *best_rd) {
3875 *best_rd = this_rd;
3876 *palette_mode_info = *pmi;
3877 memcpy(best_palette_color_map, color_map,
3878 rows * cols * sizeof(best_palette_color_map[0]));
3879 *mode_selected = DC_PRED;
3880 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08003881 *distortion = tokenonly_rd_stats.dist;
3882 *rate_tokenonly = tokenonly_rd_stats.rate;
3883 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003884 }
3885 }
3886 }
3887}
Urvang Joshib100db72016-10-12 16:28:56 -07003888#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003889
hui su5db97432016-10-14 16:10:14 -07003890#if CONFIG_FILTER_INTRA
3891// Return 1 if an filter intra mode is selected; return 0 otherwise.
3892static int rd_pick_filter_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
3893 int *rate, int *rate_tokenonly,
3894 int64_t *distortion, int *skippable,
3895 BLOCK_SIZE bsize, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003896 MACROBLOCKD *const xd = &x->e_mbd;
3897 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su5db97432016-10-14 16:10:14 -07003898 int filter_intra_selected_flag = 0;
Angie Chiang284d7772016-11-08 11:06:45 -08003899 int this_rate;
3900 int64_t this_rd;
hui su5db97432016-10-14 16:10:14 -07003901 FILTER_INTRA_MODE mode;
3902 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Angie Chiang284d7772016-11-08 11:06:45 -08003903 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003904
hui su5db97432016-10-14 16:10:14 -07003905 av1_zero(filter_intra_mode_info);
3906 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003907 mbmi->uv_mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07003908#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003909 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003910#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003911
3912 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su5db97432016-10-14 16:10:14 -07003913 mbmi->filter_intra_mode_info.filter_intra_mode[1] = mode;
Angie Chiang284d7772016-11-08 11:06:45 -08003914 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07003915 continue;
3916
Angie Chiang284d7772016-11-08 11:06:45 -08003917 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07003918 av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003919 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
3920 write_uniform_cost(FILTER_INTRA_MODES, mode);
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 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08003925 *rate_tokenonly = tokenonly_rd_stats.rate;
3926 *distortion = tokenonly_rd_stats.dist;
3927 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07003928 filter_intra_mode_info = mbmi->filter_intra_mode_info;
3929 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003930 }
3931 }
3932
hui su5db97432016-10-14 16:10:14 -07003933 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003934 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07003935 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
3936 filter_intra_mode_info.use_filter_intra_mode[1];
3937 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
3938 filter_intra_mode_info.filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003939 return 1;
3940 } else {
3941 return 0;
3942 }
3943}
hui su5db97432016-10-14 16:10:14 -07003944#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003945
hui su5db97432016-10-14 16:10:14 -07003946#if CONFIG_EXT_INTRA
Urvang Joshi52648442016-10-13 17:27:51 -07003947static void pick_intra_angle_routine_sbuv(
3948 const AV1_COMP *const cpi, MACROBLOCK *x, int *rate, int *rate_tokenonly,
3949 int64_t *distortion, int *skippable, int *best_angle_delta,
3950 BLOCK_SIZE bsize, int rate_overhead, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003951 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Angie Chiang284d7772016-11-08 11:06:45 -08003952 int this_rate;
3953 int64_t this_rd;
3954 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003955
Angie Chiang284d7772016-11-08 11:06:45 -08003956 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd)) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003957
Angie Chiang284d7772016-11-08 11:06:45 -08003958 this_rate = tokenonly_rd_stats.rate + rate_overhead;
3959 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003960 if (this_rd < *best_rd) {
3961 *best_rd = this_rd;
3962 *best_angle_delta = mbmi->angle_delta[1];
3963 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08003964 *rate_tokenonly = tokenonly_rd_stats.rate;
3965 *distortion = tokenonly_rd_stats.dist;
3966 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003967 }
3968}
3969
Urvang Joshi52648442016-10-13 17:27:51 -07003970static int rd_pick_intra_angle_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
3971 int *rate, int *rate_tokenonly,
3972 int64_t *distortion, int *skippable,
3973 BLOCK_SIZE bsize, int rate_overhead,
3974 int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003975 MACROBLOCKD *const xd = &x->e_mbd;
3976 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Angie Chiang284d7772016-11-08 11:06:45 -08003977 int this_rate;
3978 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003979 int angle_delta, best_angle_delta = 0;
3980 const double rd_adjust = 1.2;
Angie Chiang284d7772016-11-08 11:06:45 -08003981 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003982
3983 *rate_tokenonly = INT_MAX;
3984 if (ANGLE_FAST_SEARCH) {
3985 int deltas_level1[3] = { 0, -2, 2 };
3986 int deltas_level2[3][2] = {
3987 { -1, 1 }, { -3, -1 }, { 1, 3 },
3988 };
3989 const int level1 = 3, level2 = 2;
3990 int i, j, best_i = -1;
3991
3992 for (i = 0; i < level1; ++i) {
3993 int64_t tmp_best_rd;
3994 mbmi->angle_delta[1] = deltas_level1[i];
3995 tmp_best_rd = (i == 0 && best_rd < INT64_MAX)
3996 ? (int64_t)(best_rd * rd_adjust)
3997 : best_rd;
Angie Chiang284d7772016-11-08 11:06:45 -08003998 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, tmp_best_rd)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003999 if (i == 0)
4000 break;
4001 else
4002 continue;
4003 }
Angie Chiang284d7772016-11-08 11:06:45 -08004004 this_rate = tokenonly_rd_stats.rate + rate_overhead;
4005 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004006 if (i == 0 && best_rd < INT64_MAX && this_rd > best_rd * rd_adjust) break;
4007 if (this_rd < best_rd) {
4008 best_i = i;
4009 best_rd = this_rd;
4010 best_angle_delta = mbmi->angle_delta[1];
4011 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004012 *rate_tokenonly = tokenonly_rd_stats.rate;
4013 *distortion = tokenonly_rd_stats.dist;
4014 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004015 }
4016 }
4017
4018 if (best_i >= 0) {
4019 for (j = 0; j < level2; ++j) {
4020 mbmi->angle_delta[1] = deltas_level2[best_i][j];
4021 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly, distortion,
4022 skippable, &best_angle_delta, bsize,
4023 rate_overhead, &best_rd);
4024 }
4025 }
4026 } else {
4027 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
4028 ++angle_delta) {
4029 mbmi->angle_delta[1] = angle_delta;
4030 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly, distortion,
4031 skippable, &best_angle_delta, bsize,
4032 rate_overhead, &best_rd);
4033 }
4034 }
4035
4036 mbmi->angle_delta[1] = best_angle_delta;
4037 return *rate_tokenonly != INT_MAX;
4038}
4039#endif // CONFIG_EXT_INTRA
4040
Urvang Joshi52648442016-10-13 17:27:51 -07004041static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
4042 int *rate, int *rate_tokenonly,
4043 int64_t *distortion, int *skippable,
4044 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004045 MACROBLOCKD *xd = &x->e_mbd;
4046 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4047 PREDICTION_MODE mode;
4048 PREDICTION_MODE mode_selected = DC_PRED;
4049 int64_t best_rd = INT64_MAX, this_rd;
Angie Chiang284d7772016-11-08 11:06:45 -08004050 int this_rate;
4051 RD_STATS tokenonly_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004052#if CONFIG_PVQ
4053 od_rollback_buffer buf;
4054
4055 od_encode_checkpoint(&x->daala_enc, &buf);
4056#endif
Urvang Joshib100db72016-10-12 16:28:56 -07004057#if CONFIG_PALETTE
Jingning Hanae5cfde2016-11-30 12:01:44 -08004058 const int rows = block_size_high[bsize] >> (xd->plane[1].subsampling_y);
4059 const int cols = block_size_wide[bsize] >> (xd->plane[1].subsampling_x);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004060 PALETTE_MODE_INFO palette_mode_info;
4061 PALETTE_MODE_INFO *const pmi = &xd->mi[0]->mbmi.palette_mode_info;
4062 uint8_t *best_palette_color_map = NULL;
Urvang Joshib100db72016-10-12 16:28:56 -07004063#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004064#if CONFIG_EXT_INTRA
4065 int is_directional_mode, rate_overhead, best_angle_delta = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004066#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07004067#if CONFIG_FILTER_INTRA
4068 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
4069
4070 filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4071 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4072#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004073#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004074 palette_mode_info.palette_size[1] = 0;
4075 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004076#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004077 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
4078 if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode))) continue;
4079
4080 mbmi->uv_mode = mode;
4081#if CONFIG_EXT_INTRA
hui su0c628e62016-11-30 15:20:48 -08004082 is_directional_mode = av1_is_directional_mode(mode, mbmi->sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004083 rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
4084 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
4085 mbmi->angle_delta[1] = 0;
hui su0c628e62016-11-30 15:20:48 -08004086 if (is_directional_mode) {
Angie Chiang284d7772016-11-08 11:06:45 -08004087 if (!rd_pick_intra_angle_sbuv(
4088 cpi, x, &this_rate, &tokenonly_rd_stats.rate,
4089 &tokenonly_rd_stats.dist, &tokenonly_rd_stats.skip, bsize,
4090 rate_overhead, best_rd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004091 continue;
4092 } else {
Angie Chiang284d7772016-11-08 11:06:45 -08004093 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd)) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004094#if CONFIG_PVQ
4095 od_encode_rollback(&x->daala_enc, &buf);
4096#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004097 continue;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004098 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004099 }
Angie Chiang284d7772016-11-08 11:06:45 -08004100 this_rate =
4101 tokenonly_rd_stats.rate + cpi->intra_uv_mode_cost[mbmi->mode][mode];
hui su0c628e62016-11-30 15:20:48 -08004102 if (is_directional_mode)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004103 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
4104 MAX_ANGLE_DELTAS + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004105#else
Angie Chiang284d7772016-11-08 11:06:45 -08004106 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd)) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004107#if CONFIG_PVQ
4108 od_encode_rollback(&x->daala_enc, &buf);
4109#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004110 continue;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004111 }
Angie Chiang284d7772016-11-08 11:06:45 -08004112 this_rate =
4113 tokenonly_rd_stats.rate + cpi->intra_uv_mode_cost[mbmi->mode][mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004114#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07004115#if CONFIG_FILTER_INTRA
4116 if (mbmi->sb_type >= BLOCK_8X8 && mode == DC_PRED)
4117 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 0);
4118#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004119#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004120 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8 &&
4121 mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07004122 this_rate += av1_cost_bit(
4123 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07004124#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004125
Yushin Cho77bba8d2016-11-04 16:36:56 -07004126#if CONFIG_PVQ
4127 // For chroma channels, multiply lambda by 0.5 when doing intra prediction
4128 // NOTE: Chroma intra prediction itself has a separate RDO,
4129 // though final chroma intra mode's D and R is simply added to
4130 // those of luma then global RDO is performed to decide the modes of SB.
4131 // Also, for chroma, the RDO cannot decide tx_size (follow luma's decision)
4132 // or tx_type (DCT only), then only the intra prediction is
4133 // chroma's own mode decision based on separate RDO.
4134 // TODO(yushin) : Seek for more reasonable solution than this.
4135 this_rd = RDCOST(x->rdmult >> (1 * PVQ_CHROMA_RD), x->rddiv, this_rate,
Angie Chiang284d7772016-11-08 11:06:45 -08004136 tokenonly_rd_stats.dist);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004137 od_encode_rollback(&x->daala_enc, &buf);
4138#else
Angie Chiang284d7772016-11-08 11:06:45 -08004139 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004140#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004141
4142 if (this_rd < best_rd) {
4143 mode_selected = mode;
4144#if CONFIG_EXT_INTRA
4145 best_angle_delta = mbmi->angle_delta[1];
4146#endif // CONFIG_EXT_INTRA
4147 best_rd = this_rd;
4148 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004149 *rate_tokenonly = tokenonly_rd_stats.rate;
4150 *distortion = tokenonly_rd_stats.dist;
4151 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004152 }
4153 }
4154
Urvang Joshib100db72016-10-12 16:28:56 -07004155#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004156 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8) {
4157 best_palette_color_map = x->palette_buffer->best_palette_color_map;
4158 rd_pick_palette_intra_sbuv(
4159 cpi, x, cpi->intra_uv_mode_cost[mbmi->mode][DC_PRED],
4160 &palette_mode_info, best_palette_color_map, &mode_selected, &best_rd,
4161 rate, rate_tokenonly, distortion, skippable);
4162 }
Urvang Joshib100db72016-10-12 16:28:56 -07004163#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004164
hui su5db97432016-10-14 16:10:14 -07004165#if CONFIG_FILTER_INTRA
4166 if (mbmi->sb_type >= BLOCK_8X8) {
4167 if (rd_pick_filter_intra_sbuv(cpi, x, rate, rate_tokenonly, distortion,
4168 skippable, bsize, &best_rd)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004169 mode_selected = mbmi->uv_mode;
hui su5db97432016-10-14 16:10:14 -07004170 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004171 }
4172 }
4173
hui su5db97432016-10-14 16:10:14 -07004174 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
4175 filter_intra_mode_info.use_filter_intra_mode[1];
4176 if (filter_intra_mode_info.use_filter_intra_mode[1]) {
4177 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
4178 filter_intra_mode_info.filter_intra_mode[1];
Urvang Joshib100db72016-10-12 16:28:56 -07004179#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004180 palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004181#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004182 }
hui su5db97432016-10-14 16:10:14 -07004183#endif // CONFIG_FILTER_INTRA
4184
4185#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004186 mbmi->angle_delta[1] = best_angle_delta;
4187#endif // CONFIG_EXT_INTRA
4188 mbmi->uv_mode = mode_selected;
Urvang Joshib100db72016-10-12 16:28:56 -07004189#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004190 pmi->palette_size[1] = palette_mode_info.palette_size[1];
4191 if (palette_mode_info.palette_size[1] > 0) {
4192 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
4193 palette_mode_info.palette_colors + PALETTE_MAX_SIZE,
4194 2 * PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
4195 memcpy(xd->plane[1].color_index_map, best_palette_color_map,
4196 rows * cols * sizeof(best_palette_color_map[0]));
4197 }
Urvang Joshib100db72016-10-12 16:28:56 -07004198#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004199
4200 return best_rd;
4201}
4202
Urvang Joshi52648442016-10-13 17:27:51 -07004203static void choose_intra_uv_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004204 PICK_MODE_CONTEXT *ctx, BLOCK_SIZE bsize,
4205 TX_SIZE max_tx_size, int *rate_uv,
4206 int *rate_uv_tokenonly, int64_t *dist_uv,
4207 int *skip_uv, PREDICTION_MODE *mode_uv) {
4208 // Use an estimated rd for uv_intra based on DC_PRED if the
4209 // appropriate speed flag is set.
Jingning Han3f167252016-06-07 16:11:42 -07004210 (void)ctx;
4211 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4212 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004213 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
4214}
4215
Urvang Joshi52648442016-10-13 17:27:51 -07004216static int cost_mv_ref(const AV1_COMP *const cpi, PREDICTION_MODE mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004217#if CONFIG_REF_MV && CONFIG_EXT_INTER
4218 int is_compound,
4219#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4220 int16_t mode_context) {
4221#if CONFIG_REF_MV
4222 int mode_cost = 0;
4223#if CONFIG_EXT_INTER
4224 int16_t mode_ctx =
4225 is_compound ? mode_context : (mode_context & NEWMV_CTX_MASK);
4226#else
4227 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
4228#endif // CONFIG_EXT_INTER
4229 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
4230
4231 assert(is_inter_mode(mode));
4232
4233#if CONFIG_EXT_INTER
4234 if (is_compound) {
clang-format67948d32016-09-07 22:40:40 -07004235 return cpi->inter_compound_mode_cost[mode_context]
4236 [INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004237 } else {
4238 if (mode == NEWMV || mode == NEWFROMNEARMV) {
4239#else
4240 if (mode == NEWMV) {
4241#endif // CONFIG_EXT_INTER
4242 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
4243#if CONFIG_EXT_INTER
4244 if (!is_compound)
4245 mode_cost += cpi->new2mv_mode_cost[mode == NEWFROMNEARMV];
4246#endif // CONFIG_EXT_INTER
4247 return mode_cost;
4248 } else {
4249 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
4250 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
4251
4252 if (is_all_zero_mv) return mode_cost;
4253
4254 if (mode == ZEROMV) {
4255 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
4256 return mode_cost;
4257 } else {
4258 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
4259 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
4260
4261 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
4262 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
4263 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
4264
4265 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
4266 return mode_cost;
4267 }
4268 }
4269#if CONFIG_EXT_INTER
4270 }
4271#endif // CONFIG_EXT_INTER
4272#else
4273 assert(is_inter_mode(mode));
4274#if CONFIG_EXT_INTER
4275 if (is_inter_compound_mode(mode)) {
clang-format67948d32016-09-07 22:40:40 -07004276 return cpi->inter_compound_mode_cost[mode_context]
4277 [INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004278 } else {
4279#endif // CONFIG_EXT_INTER
4280 return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
4281#if CONFIG_EXT_INTER
4282 }
4283#endif // CONFIG_EXT_INTER
4284#endif
4285}
4286
Sarah Parker6fdc8532016-11-16 17:47:13 -08004287#if CONFIG_EXT_INTER
4288static int get_interinter_compound_type_bits(BLOCK_SIZE bsize,
4289 COMPOUND_TYPE comp_type) {
4290 switch (comp_type) {
4291 case COMPOUND_AVERAGE: return 0;
4292 case COMPOUND_WEDGE: return get_interinter_wedge_bits(bsize);
4293 default: assert(0); return 0;
4294 }
4295}
4296#endif // CONFIG_EXT_INTER
4297
Sarah Parkere5299862016-08-16 14:57:37 -07004298#if CONFIG_GLOBAL_MOTION
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08004299#define GLOBAL_MOTION_COST_AMORTIZATION_BLKS 8
4300
4301#if GLOBAL_MOTION_COST_AMORTIZATION_BLKS > 0
David Barkercf3d0b02016-11-10 10:14:49 +00004302static int get_gmbitcost(const WarpedMotionParams *gm, const aom_prob *probs) {
4303 int gmtype_cost[TRANS_TYPES];
Sarah Parkere5299862016-08-16 14:57:37 -07004304 int bits;
David Barkercf3d0b02016-11-10 10:14:49 +00004305 TransformationType type = gm->wmtype;
Sarah Parkere5299862016-08-16 14:57:37 -07004306 av1_cost_tokens(gmtype_cost, probs, av1_global_motion_types_tree);
David Barkercf3d0b02016-11-10 10:14:49 +00004307 switch (type) {
Debargha Mukherjee3fb33f02016-11-12 10:43:50 -08004308 case HOMOGRAPHY:
4309 bits = (GM_ABS_TRANS_BITS + 1) * 2 + (GM_ABS_ALPHA_BITS + 1) * 4 +
4310 (GM_ABS_ROW3HOMO_BITS + 1) * 2;
4311 break;
David Barkercf3d0b02016-11-10 10:14:49 +00004312 case AFFINE:
4313 bits = (GM_ABS_TRANS_BITS + 1) * 2 + (GM_ABS_ALPHA_BITS + 1) * 4;
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004314 break;
David Barkercf3d0b02016-11-10 10:14:49 +00004315 case ROTZOOM:
4316 bits = (GM_ABS_TRANS_BITS + 1) * 2 + (GM_ABS_ALPHA_BITS + 1) * 2;
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004317 break;
David Barkercf3d0b02016-11-10 10:14:49 +00004318 case TRANSLATION: bits = (GM_ABS_TRANS_BITS + 1) * 2; break;
4319 case IDENTITY: bits = 0; break;
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004320 default: assert(0); return 0;
Sarah Parkere5299862016-08-16 14:57:37 -07004321 }
Debargha Mukherjee53291fa2016-11-14 18:29:03 -08004322 assert(type < GLOBAL_TRANS_TYPES);
David Barkercf3d0b02016-11-10 10:14:49 +00004323 return bits ? (bits << AV1_PROB_COST_SHIFT) + gmtype_cost[type] : 0;
Sarah Parkere5299862016-08-16 14:57:37 -07004324}
4325
Debargha Mukherjee53291fa2016-11-14 18:29:03 -08004326#define GLOBAL_MOTION_RATE(ref) \
4327 (cpi->global_motion_used[ref] >= GLOBAL_MOTION_COST_AMORTIZATION_BLKS \
4328 ? 0 \
4329 : get_gmbitcost(&cm->global_motion[(ref)], \
4330 cm->fc->global_motion_types_prob) / \
Debargha Mukherjeeb2a0cfd2016-11-15 12:22:48 -08004331 GLOBAL_MOTION_COST_AMORTIZATION_BLKS)
Debargha Mukherjee53291fa2016-11-14 18:29:03 -08004332#else
4333#define GLOBAL_MOTION_RATE(ref) 0
4334#endif // GLOBAL_MOTION_COST_AMORTIZATION_BLKS > 0
Sarah Parkere5299862016-08-16 14:57:37 -07004335#endif // CONFIG_GLOBAL_MOTION
4336
Urvang Joshi52648442016-10-13 17:27:51 -07004337static int set_and_cost_bmi_mvs(const AV1_COMP *const cpi, MACROBLOCK *x,
4338 MACROBLOCKD *xd, int i, PREDICTION_MODE mode,
4339 int_mv this_mv[2],
clang-format67948d32016-09-07 22:40:40 -07004340 int_mv frame_mv[MB_MODE_COUNT]
4341 [TOTAL_REFS_PER_FRAME],
4342 int_mv seg_mvs[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004343#if CONFIG_EXT_INTER
clang-format67948d32016-09-07 22:40:40 -07004344 int_mv compound_seg_newmvs[2],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004345#endif // CONFIG_EXT_INTER
clang-format67948d32016-09-07 22:40:40 -07004346 int_mv *best_ref_mv[2], const int *mvjcost,
4347 int *mvcost[2]) {
Sarah Parkere5299862016-08-16 14:57:37 -07004348#if CONFIG_GLOBAL_MOTION
4349 const AV1_COMMON *cm = &cpi->common;
4350#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004351 MODE_INFO *const mic = xd->mi[0];
4352 const MB_MODE_INFO *const mbmi = &mic->mbmi;
4353 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4354 int thismvcost = 0;
4355 int idx, idy;
4356 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
4357 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
4358 const int is_compound = has_second_ref(mbmi);
Yaowu Xub0d0d002016-11-22 09:26:43 -08004359 int mode_ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004360
4361 switch (mode) {
4362 case NEWMV:
4363#if CONFIG_EXT_INTER
4364 case NEWFROMNEARMV:
4365#endif // CONFIG_EXT_INTER
4366 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
4367#if CONFIG_EXT_INTER
Alex Converse6317c882016-09-29 14:21:37 -07004368 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004369 lower_mv_precision(&this_mv[0].as_mv, 0);
4370#endif // CONFIG_EXT_INTER
4371
4372#if CONFIG_REF_MV
4373 for (idx = 0; idx < 1 + is_compound; ++idx) {
4374 this_mv[idx] = seg_mvs[mbmi->ref_frame[idx]];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07004375 av1_set_mvcost(x, mbmi->ref_frame[idx], idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004376 thismvcost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07004377 av1_mv_bit_cost(&this_mv[idx].as_mv, &best_ref_mv[idx]->as_mv,
4378 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004379 }
4380 (void)mvjcost;
4381 (void)mvcost;
4382#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004383 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4384 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004385#if !CONFIG_EXT_INTER
4386 if (is_compound) {
4387 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07004388 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4389 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004390 }
4391#endif // !CONFIG_EXT_INTER
4392#endif
4393 break;
4394 case NEARMV:
4395 case NEARESTMV:
4396 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4397 if (is_compound)
4398 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4399 break;
4400 case ZEROMV:
Sarah Parkere5299862016-08-16 14:57:37 -07004401#if CONFIG_GLOBAL_MOTION
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004402 this_mv[0].as_int =
David Barkercdcac6d2016-12-01 17:04:16 +00004403 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[0]],
4404 cpi->common.allow_high_precision_mv)
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004405 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07004406 thismvcost += GLOBAL_MOTION_RATE(mbmi->ref_frame[0]);
4407 if (is_compound) {
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004408 this_mv[1].as_int =
David Barkercdcac6d2016-12-01 17:04:16 +00004409 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[1]],
4410 cpi->common.allow_high_precision_mv)
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004411 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07004412 thismvcost += GLOBAL_MOTION_RATE(mbmi->ref_frame[1]);
4413 }
4414#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004415 this_mv[0].as_int = 0;
4416 if (is_compound) this_mv[1].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07004417#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004418 break;
4419#if CONFIG_EXT_INTER
4420 case NEW_NEWMV:
4421 if (compound_seg_newmvs[0].as_int == INVALID_MV ||
4422 compound_seg_newmvs[1].as_int == INVALID_MV) {
4423 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
4424 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
4425 } else {
4426 this_mv[0].as_int = compound_seg_newmvs[0].as_int;
4427 this_mv[1].as_int = compound_seg_newmvs[1].as_int;
4428 }
Alex Converse6317c882016-09-29 14:21:37 -07004429 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004430 lower_mv_precision(&this_mv[0].as_mv, 0);
Alex Converse6317c882016-09-29 14:21:37 -07004431 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004432 lower_mv_precision(&this_mv[1].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07004433 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4434 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
4435 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4436 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004437 break;
4438 case NEW_NEARMV:
4439 case NEW_NEARESTMV:
4440 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07004441 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004442 lower_mv_precision(&this_mv[0].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07004443 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4444 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004445 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4446 break;
4447 case NEAR_NEWMV:
4448 case NEAREST_NEWMV:
4449 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4450 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07004451 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004452 lower_mv_precision(&this_mv[1].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07004453 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4454 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004455 break;
4456 case NEAREST_NEARMV:
4457 case NEAR_NEARESTMV:
4458 case NEAREST_NEARESTMV:
4459 case NEAR_NEARMV:
4460 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4461 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4462 break;
4463 case ZERO_ZEROMV:
4464 this_mv[0].as_int = 0;
4465 this_mv[1].as_int = 0;
4466 break;
4467#endif // CONFIG_EXT_INTER
4468 default: break;
4469 }
4470
4471 mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
4472 if (is_compound) mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
4473
4474 mic->bmi[i].as_mode = mode;
4475
4476#if CONFIG_REF_MV
4477 if (mode == NEWMV) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07004478 mic->bmi[i].pred_mv[0].as_int =
4479 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_int;
4480 if (is_compound)
4481 mic->bmi[i].pred_mv[1].as_int =
4482 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004483 } else {
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07004484 mic->bmi[i].pred_mv[0].as_int = this_mv[0].as_int;
4485 if (is_compound) mic->bmi[i].pred_mv[1].as_int = this_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004486 }
4487#endif
4488
4489 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
4490 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
4491 memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
4492
4493#if CONFIG_REF_MV
4494#if CONFIG_EXT_INTER
4495 if (is_compound)
4496 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
4497 else
4498#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07004499 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
4500 mbmi->ref_frame, mbmi->sb_type, i);
Yaowu Xub0d0d002016-11-22 09:26:43 -08004501#else // CONFIG_REF_MV
4502 mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
4503#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07004504#if CONFIG_REF_MV && CONFIG_EXT_INTER
4505 return cost_mv_ref(cpi, mode, is_compound, mode_ctx) + thismvcost;
4506#else
4507 return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
4508#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4509}
4510
Urvang Joshi52648442016-10-13 17:27:51 -07004511static int64_t encode_inter_mb_segment(const AV1_COMP *const cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004512 int64_t best_yrd, int i, int *labelyrate,
4513 int64_t *distortion, int64_t *sse,
4514 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
4515 int ir, int ic, int mi_row, int mi_col) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004516#if !CONFIG_PVQ
Angie Chiang22ba7512016-10-20 17:10:33 -07004517 const AV1_COMMON *const cm = &cpi->common;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004518#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004519 int k;
4520 MACROBLOCKD *xd = &x->e_mbd;
4521 struct macroblockd_plane *const pd = &xd->plane[0];
4522 struct macroblock_plane *const p = &x->plane[0];
4523 MODE_INFO *const mi = xd->mi[0];
4524 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
Jingning Hanc4049db2016-10-27 14:44:13 -07004525 const int width = block_size_wide[plane_bsize];
4526 const int height = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004527 int idx, idy;
4528 const uint8_t *const src =
Yaowu Xuf883b422016-08-30 14:01:10 -07004529 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004530 uint8_t *const dst =
Yaowu Xuf883b422016-08-30 14:01:10 -07004531 &pd->dst.buf[av1_raster_block_offset(BLOCK_8X8, i, pd->dst.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004532 int64_t thisdistortion = 0, thissse = 0;
4533 int thisrate = 0;
4534 TX_SIZE tx_size = mi->mbmi.tx_size;
4535
4536 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, i, tx_size);
Jingning Hanc4049db2016-10-27 14:44:13 -07004537 const int num_4x4_w = tx_size_wide_unit[tx_size];
4538 const int num_4x4_h = tx_size_high_unit[tx_size];
Yushin Cho77bba8d2016-11-04 16:36:56 -07004539#if !CONFIG_PVQ
4540 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 1);
4541#else
4542 (void)cpi;
4543 (void)ta;
4544 (void)tl;
4545#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004546
4547#if CONFIG_EXT_TX && CONFIG_RECT_TX
4548 assert(IMPLIES(xd->lossless[mi->mbmi.segment_id], tx_size == TX_4X4));
4549 assert(IMPLIES(!xd->lossless[mi->mbmi.segment_id],
4550 tx_size == max_txsize_rect_lookup[mi->mbmi.sb_type]));
4551#else
4552 assert(tx_size == TX_4X4);
4553#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4554 assert(tx_type == DCT_DCT);
4555
Yaowu Xuf883b422016-08-30 14:01:10 -07004556 av1_build_inter_predictor_sub8x8(xd, 0, i, ir, ic, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004557
Yushin Cho77bba8d2016-11-04 16:36:56 -07004558#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -07004559#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004560 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004561 aom_highbd_subtract_block(
4562 height, width, av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
4563 8, src, p->src.stride, dst, pd->dst.stride, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004564 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004565 aom_subtract_block(height, width,
4566 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07004567 8, src, p->src.stride, dst, pd->dst.stride);
4568 }
4569#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004570 aom_subtract_block(height, width,
4571 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07004572 8, src, p->src.stride, dst, pd->dst.stride);
Yaowu Xuf883b422016-08-30 14:01:10 -07004573#endif // CONFIG_AOM_HIGHBITDEPTH
Yushin Cho77bba8d2016-11-04 16:36:56 -07004574#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004575
4576 k = i;
4577 for (idy = 0; idy < height / 4; idy += num_4x4_h) {
4578 for (idx = 0; idx < width / 4; idx += num_4x4_w) {
4579 int64_t dist, ssz, rd, rd1, rd2;
4580 int block;
Yaowu Xu02d4c3b2016-11-07 10:45:56 -08004581#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004582 int coeff_ctx;
Yaowu Xu02d4c3b2016-11-07 10:45:56 -08004583#else
Yushin Cho77bba8d2016-11-04 16:36:56 -07004584 const int src_stride = p->src.stride;
4585 const int dst_stride = pd->dst.stride;
4586 const int diff_stride = 8;
4587 tran_low_t *coeff;
4588 tran_low_t *dqcoeff;
4589 tran_low_t *ref_coeff;
4590 int16_t *pred = &pd->pred[4 * (ir * diff_stride + ic)];
4591 int16_t *src_int16 = &p->src_int16[4 * (ir * diff_stride + ic)];
4592 int ii, j, tx_blk_size;
4593 int rate_pvq;
4594#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004595 k += (idy * 2 + idx);
4596 if (tx_size == TX_4X4)
4597 block = k;
4598 else
4599 block = (i ? 2 : 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004600#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004601 coeff_ctx = combine_entropy_contexts(*(ta + (k & 1)), *(tl + (k >> 1)));
4602#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08004603 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
4604 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004605#else
Angie Chiangff6d8902016-10-21 11:02:09 -07004606 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
Debargha Mukherjeef0305582016-11-24 09:55:34 -08004607 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004608#endif // CONFIG_NEW_QUANT
4609 if (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0)
Angie Chiangff6d8902016-10-21 11:02:09 -07004610 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004611#else
4612 coeff = BLOCK_OFFSET(p->coeff, k);
4613 dqcoeff = BLOCK_OFFSET(pd->dqcoeff, k);
4614 ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, k);
4615
4616 // transform block size in pixels
4617 tx_blk_size = 4;
4618
4619 // copy uint8 orig and predicted block to int16 buffer
4620 // in order to use existing VP10 transform functions
4621 for (j = 0; j < tx_blk_size; j++)
4622 for (ii = 0; ii < tx_blk_size; ii++) {
4623 src_int16[diff_stride * j + ii] =
4624 src[src_stride * (j + 4 * idy) + (ii + 4 * idx)];
4625 pred[diff_stride * j + ii] =
4626 dst[dst_stride * (j + 4 * idy) + (ii + 4 * idx)];
4627 }
4628
Yaowu Xu3442b4b2016-11-07 10:40:41 -08004629 {
4630 FWD_TXFM_PARAM fwd_txfm_param;
4631 fwd_txfm_param.tx_type = DCT_DCT;
4632 fwd_txfm_param.tx_size = TX_4X4;
4633 fwd_txfm_param.fwd_txfm_opt = FWD_TXFM_OPT_NORMAL;
4634 fwd_txfm_param.rd_transform = 0;
4635 fwd_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
Yushin Cho77bba8d2016-11-04 16:36:56 -07004636
Yaowu Xu3442b4b2016-11-07 10:40:41 -08004637 fwd_txfm(src_int16, coeff, diff_stride, &fwd_txfm_param);
4638 fwd_txfm(pred, ref_coeff, diff_stride, &fwd_txfm_param);
4639 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004640 av1_pvq_encode_helper(&x->daala_enc, coeff, ref_coeff, dqcoeff,
4641 &p->eobs[k], pd->dequant, 0, TX_4X4, tx_type,
4642 &rate_pvq, x->pvq_speed, NULL);
4643#endif
4644
Yaowu Xuc27fc142016-08-22 16:08:15 -07004645 dist_block(cpi, x, 0, block, idy + (i >> 1), idx + (i & 0x1), tx_size,
4646 &dist, &ssz);
4647 thisdistortion += dist;
4648 thissse += ssz;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004649#if !CONFIG_PVQ
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07004650 thisrate +=
Angie Chiang22ba7512016-10-20 17:10:33 -07004651 av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size, scan_order->scan,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07004652 scan_order->neighbors, cpi->sf.use_fast_coef_costing);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004653#else
4654 thisrate += rate_pvq;
4655#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004656 *(ta + (k & 1)) = !(p->eobs[block] == 0);
4657 *(tl + (k >> 1)) = !(p->eobs[block] == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004658#if CONFIG_EXT_TX
4659 if (tx_size == TX_8X4) {
4660 *(ta + (k & 1) + 1) = *(ta + (k & 1));
4661 }
4662 if (tx_size == TX_4X8) {
4663 *(tl + (k >> 1) + 1) = *(tl + (k >> 1));
4664 }
4665#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004666 rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion);
4667 rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse);
Yaowu Xuf883b422016-08-30 14:01:10 -07004668 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004669 if (rd >= best_yrd) return INT64_MAX;
4670 }
4671 }
4672
4673 *distortion = thisdistortion;
4674 *labelyrate = thisrate;
4675 *sse = thissse;
4676
4677 return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
4678}
4679
4680typedef struct {
4681 int eobs;
4682 int brate;
4683 int byrate;
4684 int64_t bdist;
4685 int64_t bsse;
4686 int64_t brdcost;
4687 int_mv mvs[2];
4688#if CONFIG_REF_MV
4689 int_mv pred_mv[2];
4690#endif
4691#if CONFIG_EXT_INTER
4692 int_mv ref_mv[2];
4693#endif // CONFIG_EXT_INTER
4694 ENTROPY_CONTEXT ta[2];
4695 ENTROPY_CONTEXT tl[2];
4696} SEG_RDSTAT;
4697
4698typedef struct {
4699 int_mv *ref_mv[2];
4700 int_mv mvp;
4701
4702 int64_t segment_rd;
4703 int r;
4704 int64_t d;
4705 int64_t sse;
4706 int segment_yrate;
4707 PREDICTION_MODE modes[4];
4708#if CONFIG_EXT_INTER
4709 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
4710#else
4711 SEG_RDSTAT rdstat[4][INTER_MODES];
4712#endif // CONFIG_EXT_INTER
4713 int mvthresh;
4714} BEST_SEG_INFO;
4715
4716static INLINE int mv_check_bounds(const MACROBLOCK *x, const MV *mv) {
4717 return (mv->row >> 3) < x->mv_row_min || (mv->row >> 3) > x->mv_row_max ||
4718 (mv->col >> 3) < x->mv_col_min || (mv->col >> 3) > x->mv_col_max;
4719}
4720
4721static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
4722 MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
4723 struct macroblock_plane *const p = &x->plane[0];
4724 struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
4725
4726 p->src.buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07004727 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004728 assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
4729 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07004730 &pd->pre[0].buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[0].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004731 if (has_second_ref(mbmi))
4732 pd->pre[1].buf =
4733 &pd->pre[1]
Yaowu Xuf883b422016-08-30 14:01:10 -07004734 .buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[1].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004735}
4736
4737static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
4738 struct buf_2d orig_pre[2]) {
4739 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
4740 x->plane[0].src = orig_src;
4741 x->e_mbd.plane[0].pre[0] = orig_pre[0];
4742 if (has_second_ref(mbmi)) x->e_mbd.plane[0].pre[1] = orig_pre[1];
4743}
4744
4745// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
4746// TODO(aconverse): Find out if this is still productive then clean up or remove
4747static int check_best_zero_mv(
Urvang Joshi52648442016-10-13 17:27:51 -07004748 const AV1_COMP *const cpi, const int16_t mode_context[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004749#if CONFIG_REF_MV && CONFIG_EXT_INTER
4750 const int16_t compound_mode_context[TOTAL_REFS_PER_FRAME],
4751#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4752 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME], int this_mode,
4753 const MV_REFERENCE_FRAME ref_frames[2], const BLOCK_SIZE bsize, int block) {
4754
4755#if !CONFIG_EXT_INTER
4756 assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
4757#endif
4758
4759 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
4760 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
4761 (ref_frames[1] <= INTRA_FRAME ||
4762 frame_mv[this_mode][ref_frames[1]].as_int == 0)) {
4763#if CONFIG_REF_MV
4764 int16_t rfc =
Yaowu Xuf883b422016-08-30 14:01:10 -07004765 av1_mode_context_analyzer(mode_context, ref_frames, bsize, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004766#else
4767 int16_t rfc = mode_context[ref_frames[0]];
4768#endif
4769#if CONFIG_REF_MV && CONFIG_EXT_INTER
4770 int c1 = cost_mv_ref(cpi, NEARMV, ref_frames[1] > INTRA_FRAME, rfc);
4771 int c2 = cost_mv_ref(cpi, NEARESTMV, ref_frames[1] > INTRA_FRAME, rfc);
4772 int c3 = cost_mv_ref(cpi, ZEROMV, ref_frames[1] > INTRA_FRAME, rfc);
4773#else
4774 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
4775 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
4776 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
4777#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4778
4779#if !CONFIG_REF_MV
4780 (void)bsize;
4781 (void)block;
4782#endif
4783
4784 if (this_mode == NEARMV) {
4785 if (c1 > c3) return 0;
4786 } else if (this_mode == NEARESTMV) {
4787 if (c2 > c3) return 0;
4788 } else {
4789 assert(this_mode == ZEROMV);
4790 if (ref_frames[1] <= INTRA_FRAME) {
4791 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
4792 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
4793 return 0;
4794 } else {
4795 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
4796 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
4797 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
4798 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
4799 return 0;
4800 }
4801 }
4802 }
4803#if CONFIG_EXT_INTER
4804 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
4805 this_mode == NEAR_NEARESTMV || this_mode == NEAR_NEARMV ||
4806 this_mode == ZERO_ZEROMV) &&
4807 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
4808 frame_mv[this_mode][ref_frames[1]].as_int == 0) {
4809#if CONFIG_REF_MV
4810 int16_t rfc = compound_mode_context[ref_frames[0]];
4811 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, 1, rfc);
4812 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, 1, rfc);
4813 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, 1, rfc);
4814 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, 1, rfc);
4815 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, 1, rfc);
4816#else
4817 int16_t rfc = mode_context[ref_frames[0]];
4818 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
4819 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
4820 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
4821 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
4822 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, rfc);
4823#endif
4824
4825 if (this_mode == NEAREST_NEARMV) {
4826 if (c1 > c3) return 0;
4827 } else if (this_mode == NEAREST_NEARESTMV) {
4828 if (c2 > c3) return 0;
4829 } else if (this_mode == NEAR_NEARESTMV) {
4830 if (c4 > c3) return 0;
4831 } else if (this_mode == NEAR_NEARMV) {
4832 if (c5 > c3) return 0;
4833 } else {
4834 assert(this_mode == ZERO_ZEROMV);
4835 if ((c3 >= c2 && frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
4836 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
4837 (c3 >= c1 && frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
4838 frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
4839 (c3 >= c5 && frame_mv[NEAR_NEARMV][ref_frames[0]].as_int == 0 &&
4840 frame_mv[NEAR_NEARMV][ref_frames[1]].as_int == 0) ||
4841 (c3 >= c4 && frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
4842 frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
4843 return 0;
4844 }
4845 }
4846#endif // CONFIG_EXT_INTER
4847 return 1;
4848}
4849
Urvang Joshi52648442016-10-13 17:27:51 -07004850static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
4851 BLOCK_SIZE bsize, int_mv *frame_mv, int mi_row,
4852 int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004853#if CONFIG_EXT_INTER
4854 int_mv *ref_mv_sub8x8[2],
4855#endif
4856 int_mv single_newmv[TOTAL_REFS_PER_FRAME],
4857 int *rate_mv, const int block) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004858 const AV1_COMMON *const cm = &cpi->common;
Jingning Hanae5cfde2016-11-30 12:01:44 -08004859 const int pw = block_size_wide[bsize];
4860 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004861 MACROBLOCKD *xd = &x->e_mbd;
4862 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4863 const int refs[2] = { mbmi->ref_frame[0],
4864 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
4865 int_mv ref_mv[2];
4866 int ite, ref;
4867#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07004868 InterpFilter interp_filter[4] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004869 mbmi->interp_filter[0], mbmi->interp_filter[1], mbmi->interp_filter[2],
4870 mbmi->interp_filter[3],
4871 };
4872#else
James Zern7b9407a2016-05-18 23:48:05 -07004873 const InterpFilter interp_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004874#endif
4875 struct scale_factors sf;
4876
4877 // Do joint motion search in compound mode to get more accurate mv.
4878 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
4879 int last_besterr[2] = { INT_MAX, INT_MAX };
4880 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
Yaowu Xuf883b422016-08-30 14:01:10 -07004881 av1_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
4882 av1_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
Yaowu Xuc27fc142016-08-22 16:08:15 -07004883 };
4884
4885// Prediction buffer from second frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07004886#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004887 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
4888 uint8_t *second_pred;
4889#else
4890 DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07004891#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004892
4893 for (ref = 0; ref < 2; ++ref) {
4894#if CONFIG_EXT_INTER
4895 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
4896 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
4897 else
4898#endif // CONFIG_EXT_INTER
4899 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
4900
4901 if (scaled_ref_frame[ref]) {
4902 int i;
4903 // Swap out the reference frame for a version that's been scaled to
4904 // match the resolution of the current frame, allowing the existing
4905 // motion search code to be used without additional modifications.
4906 for (i = 0; i < MAX_MB_PLANE; i++)
4907 backup_yv12[ref][i] = xd->plane[i].pre[ref];
Yaowu Xuf883b422016-08-30 14:01:10 -07004908 av1_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
4909 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004910 }
4911
4912 frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
4913 }
4914
4915// Since we have scaled the reference frames to match the size of the current
4916// frame we must use a unit scaling factor during mode selection.
Yaowu Xuf883b422016-08-30 14:01:10 -07004917#if CONFIG_AOM_HIGHBITDEPTH
4918 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
4919 cm->height, cm->use_highbitdepth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004920#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004921 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
4922 cm->height);
4923#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004924
4925 // Allow joint search multiple times iteratively for each reference frame
4926 // and break out of the search loop if it couldn't find a better mv.
4927 for (ite = 0; ite < 4; ite++) {
4928 struct buf_2d ref_yv12[2];
4929 int bestsme = INT_MAX;
4930 int sadpb = x->sadperbit16;
4931 MV *const best_mv = &x->best_mv.as_mv;
4932 int search_range = 3;
4933
4934 int tmp_col_min = x->mv_col_min;
4935 int tmp_col_max = x->mv_col_max;
4936 int tmp_row_min = x->mv_row_min;
4937 int tmp_row_max = x->mv_row_max;
4938 int id = ite % 2; // Even iterations search in the first reference frame,
4939 // odd iterations search in the second. The predictor
4940 // found for the 'other' reference frame is factored in.
4941
4942 // Initialized here because of compiler problem in Visual Studio.
4943 ref_yv12[0] = xd->plane[0].pre[0];
4944 ref_yv12[1] = xd->plane[0].pre[1];
4945
4946#if CONFIG_DUAL_FILTER
4947 // reload the filter types
4948 interp_filter[0] =
4949 (id == 0) ? mbmi->interp_filter[2] : mbmi->interp_filter[0];
4950 interp_filter[1] =
4951 (id == 0) ? mbmi->interp_filter[3] : mbmi->interp_filter[1];
4952#endif
4953
4954// Get the prediction block from the 'other' reference frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07004955#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004956 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
4957 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
Yaowu Xuf883b422016-08-30 14:01:10 -07004958 av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004959 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
4960 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, 0, interp_filter,
4961 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd->bd);
4962 } else {
4963 second_pred = (uint8_t *)second_pred_alloc_16;
Yaowu Xuf883b422016-08-30 14:01:10 -07004964 av1_build_inter_predictor(ref_yv12[!id].buf, ref_yv12[!id].stride,
4965 second_pred, pw, &frame_mv[refs[!id]].as_mv,
4966 &sf, pw, ph, 0, interp_filter, MV_PRECISION_Q3,
4967 mi_col * MI_SIZE, mi_row * MI_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004968 }
4969#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004970 av1_build_inter_predictor(ref_yv12[!id].buf, ref_yv12[!id].stride,
4971 second_pred, pw, &frame_mv[refs[!id]].as_mv, &sf,
4972 pw, ph, 0, interp_filter, MV_PRECISION_Q3,
4973 mi_col * MI_SIZE, mi_row * MI_SIZE);
4974#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004975
4976 // Do compound motion search on the current reference frame.
4977 if (id) xd->plane[0].pre[0] = ref_yv12[id];
Yaowu Xuf883b422016-08-30 14:01:10 -07004978 av1_set_mv_search_range(x, &ref_mv[id].as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004979
4980 // Use the mv result from the single mode as mv predictor.
4981 *best_mv = frame_mv[refs[id]].as_mv;
4982
4983 best_mv->col >>= 3;
4984 best_mv->row >>= 3;
4985
4986#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07004987 av1_set_mvcost(x, refs[id], id, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004988#endif
4989
4990 // Small-range full-pixel motion search.
4991 bestsme =
Yaowu Xuf883b422016-08-30 14:01:10 -07004992 av1_refining_search_8p_c(x, sadpb, search_range, &cpi->fn_ptr[bsize],
4993 &ref_mv[id].as_mv, second_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004994 if (bestsme < INT_MAX)
Yaowu Xuf883b422016-08-30 14:01:10 -07004995 bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv[id].as_mv,
4996 second_pred, &cpi->fn_ptr[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004997
4998 x->mv_col_min = tmp_col_min;
4999 x->mv_col_max = tmp_col_max;
5000 x->mv_row_min = tmp_row_min;
5001 x->mv_row_max = tmp_row_max;
5002
5003 if (bestsme < INT_MAX) {
5004 int dis; /* TODO: use dis in distortion calculation later. */
5005 unsigned int sse;
5006 if (cpi->sf.use_upsampled_references) {
5007 // Use up-sampled reference frames.
5008 struct macroblockd_plane *const pd = &xd->plane[0];
5009 struct buf_2d backup_pred = pd->pre[0];
5010 const YV12_BUFFER_CONFIG *upsampled_ref =
5011 get_upsampled_ref(cpi, refs[id]);
5012
5013 // Set pred for Y plane
5014 setup_pred_plane(&pd->pre[0], upsampled_ref->y_buffer,
5015 upsampled_ref->y_crop_width,
5016 upsampled_ref->y_crop_height, upsampled_ref->y_stride,
5017 (mi_row << 3), (mi_col << 3), NULL, pd->subsampling_x,
5018 pd->subsampling_y);
5019
5020 // If bsize < BLOCK_8X8, adjust pred pointer for this block
5021 if (bsize < BLOCK_8X8)
5022 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005023 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, block,
5024 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005025 << 3];
5026
5027 bestsme = cpi->find_fractional_mv_step(
5028 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5029 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5030 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5031 &dis, &sse, second_pred, pw, ph, 1);
5032
5033 // Restore the reference frames.
5034 pd->pre[0] = backup_pred;
5035 } else {
5036 (void)block;
5037 bestsme = cpi->find_fractional_mv_step(
5038 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5039 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5040 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5041 &dis, &sse, second_pred, pw, ph, 0);
5042 }
5043 }
5044
5045 // Restore the pointer to the first (possibly scaled) prediction buffer.
5046 if (id) xd->plane[0].pre[0] = ref_yv12[0];
5047
5048 if (bestsme < last_besterr[id]) {
5049 frame_mv[refs[id]].as_mv = *best_mv;
5050 last_besterr[id] = bestsme;
5051 } else {
5052 break;
5053 }
5054 }
5055
5056 *rate_mv = 0;
5057
5058 for (ref = 0; ref < 2; ++ref) {
5059 if (scaled_ref_frame[ref]) {
5060 // Restore the prediction frame pointers to their unscaled versions.
5061 int i;
5062 for (i = 0; i < MAX_MB_PLANE; i++)
5063 xd->plane[i].pre[ref] = backup_yv12[ref][i];
5064 }
5065#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005066 av1_set_mvcost(x, refs[ref], ref, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005067#endif
5068#if CONFIG_EXT_INTER
5069 if (bsize >= BLOCK_8X8)
5070#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005071 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5072 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
5073 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005074#if CONFIG_EXT_INTER
5075 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005076 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5077 &ref_mv_sub8x8[ref]->as_mv, x->nmvjointcost,
5078 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005079#endif // CONFIG_EXT_INTER
5080 }
5081}
5082
5083static int64_t rd_pick_best_sub8x8_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07005084 const AV1_COMP *const cpi, MACROBLOCK *x, int_mv *best_ref_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005085 int_mv *second_best_ref_mv, int64_t best_rd, int *returntotrate,
5086 int *returnyrate, int64_t *returndistortion, int *skippable, int64_t *psse,
5087 int mvthresh,
5088#if CONFIG_EXT_INTER
5089 int_mv seg_mvs[4][2][TOTAL_REFS_PER_FRAME],
5090 int_mv compound_seg_newmvs[4][2],
5091#else
5092 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME],
5093#endif // CONFIG_EXT_INTER
5094 BEST_SEG_INFO *bsi_buf, int filter_idx, int mi_row, int mi_col) {
5095 BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
5096#if CONFIG_REF_MV
5097 int_mv tmp_ref_mv[2];
5098#endif
5099 MACROBLOCKD *xd = &x->e_mbd;
5100 MODE_INFO *mi = xd->mi[0];
5101 MB_MODE_INFO *mbmi = &mi->mbmi;
5102 int mode_idx;
5103 int k, br = 0, idx, idy;
5104 int64_t bd = 0, block_sse = 0;
5105 PREDICTION_MODE this_mode;
Urvang Joshi52648442016-10-13 17:27:51 -07005106 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005107 struct macroblock_plane *const p = &x->plane[0];
5108 struct macroblockd_plane *const pd = &xd->plane[0];
5109 const int label_count = 4;
5110 int64_t this_segment_rd = 0;
5111 int label_mv_thresh;
5112 int segmentyrate = 0;
5113 const BLOCK_SIZE bsize = mbmi->sb_type;
5114 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
5115 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
5116 ENTROPY_CONTEXT t_above[2], t_left[2];
5117 int subpelmv = 1, have_ref = 0;
5118 const int has_second_rf = has_second_ref(mbmi);
5119 const int inter_mode_mask = cpi->sf.inter_mode_mask[bsize];
5120 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005121#if CONFIG_PVQ
5122 od_rollback_buffer pre_buf;
5123
5124 od_encode_checkpoint(&x->daala_enc, &pre_buf);
5125#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005126#if CONFIG_EXT_TX && CONFIG_RECT_TX
5127 mbmi->tx_size =
5128 xd->lossless[mbmi->segment_id] ? TX_4X4 : max_txsize_rect_lookup[bsize];
5129#else
5130 mbmi->tx_size = TX_4X4;
5131#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5132
Yaowu Xuf883b422016-08-30 14:01:10 -07005133 av1_zero(*bsi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005134
5135 bsi->segment_rd = best_rd;
5136 bsi->ref_mv[0] = best_ref_mv;
5137 bsi->ref_mv[1] = second_best_ref_mv;
5138 bsi->mvp.as_int = best_ref_mv->as_int;
5139 bsi->mvthresh = mvthresh;
5140
5141 for (idx = 0; idx < 4; ++idx) bsi->modes[idx] = ZEROMV;
5142
5143#if CONFIG_REFMV
5144 for (idx = 0; idx < 4; ++idx) {
5145 for (k = NEARESTMV; k <= NEWMV; ++k) {
5146 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[0].as_int = INVALID_MV;
5147 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[1].as_int = INVALID_MV;
5148
5149 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[0].as_int = INVALID_MV;
5150 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[1].as_int = INVALID_MV;
5151 }
5152 }
5153#endif
5154
5155 memcpy(t_above, pd->above_context, sizeof(t_above));
5156 memcpy(t_left, pd->left_context, sizeof(t_left));
5157
5158 // 64 makes this threshold really big effectively
5159 // making it so that we very rarely check mvs on
5160 // segments. setting this to 1 would make mv thresh
5161 // roughly equal to what it is for macroblocks
5162 label_mv_thresh = 1 * bsi->mvthresh / label_count;
5163
5164 // Segmentation method overheads
5165 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
5166 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
5167 // TODO(jingning,rbultje): rewrite the rate-distortion optimization
5168 // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
5169 int_mv mode_mv[MB_MODE_COUNT][2];
5170 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
5171 PREDICTION_MODE mode_selected = ZEROMV;
Urvang Joshi454280d2016-10-14 16:51:44 -07005172 int64_t new_best_rd = INT64_MAX;
5173 const int index = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005174 int ref;
5175#if CONFIG_REF_MV
5176 CANDIDATE_MV ref_mv_stack[2][MAX_REF_MV_STACK_SIZE];
5177 uint8_t ref_mv_count[2];
5178#endif
5179#if CONFIG_EXT_INTER
5180 int mv_idx;
5181 int_mv ref_mvs_sub8x8[2][2];
5182#endif // CONFIG_EXT_INTER
Yushin Cho77bba8d2016-11-04 16:36:56 -07005183#if CONFIG_PVQ
5184 od_rollback_buffer idx_buf, post_buf;
5185 od_encode_checkpoint(&x->daala_enc, &idx_buf);
5186 od_encode_checkpoint(&x->daala_enc, &post_buf);
5187#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005188
5189 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5190 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
5191#if CONFIG_EXT_INTER
5192 int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
Urvang Joshi454280d2016-10-14 16:51:44 -07005193 av1_update_mv_context(xd, mi, frame, mv_ref_list, index, mi_row, mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -07005194 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005195#endif // CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005196#if CONFIG_GLOBAL_MOTION
5197 frame_mv[ZEROMV][frame].as_int =
David Barkercdcac6d2016-12-01 17:04:16 +00005198 gm_get_motion_vector(&cm->global_motion[frame],
5199 cm->allow_high_precision_mv)
5200 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07005201#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005202 frame_mv[ZEROMV][frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07005203#endif // CONFIG_GLOBAL_MOTION
Urvang Joshi454280d2016-10-14 16:51:44 -07005204 av1_append_sub8x8_mvs_for_idx(cm, xd, index, ref, mi_row, mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005205#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07005206 ref_mv_stack[ref], &ref_mv_count[ref],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005207#endif
5208#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005209 mv_ref_list,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005210#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005211 &frame_mv[NEARESTMV][frame],
5212 &frame_mv[NEARMV][frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005213
5214#if CONFIG_REF_MV
5215 tmp_ref_mv[ref] = frame_mv[NEARESTMV][mbmi->ref_frame[ref]];
5216 lower_mv_precision(&tmp_ref_mv[ref].as_mv, cm->allow_high_precision_mv);
5217 bsi->ref_mv[ref] = &tmp_ref_mv[ref];
5218 mbmi_ext->ref_mvs[frame][0] = tmp_ref_mv[ref];
5219#endif
5220
5221#if CONFIG_EXT_INTER
5222 mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
5223 mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07005224 av1_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
5225 &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005226
5227 if (has_second_rf) {
5228 frame_mv[ZERO_ZEROMV][frame].as_int = 0;
5229 frame_mv[NEAREST_NEARESTMV][frame].as_int =
5230 frame_mv[NEARESTMV][frame].as_int;
5231
5232 if (ref == 0) {
5233 frame_mv[NEAREST_NEARMV][frame].as_int =
5234 frame_mv[NEARESTMV][frame].as_int;
5235 frame_mv[NEAR_NEARESTMV][frame].as_int =
5236 frame_mv[NEARMV][frame].as_int;
5237 frame_mv[NEAREST_NEWMV][frame].as_int =
5238 frame_mv[NEARESTMV][frame].as_int;
5239 frame_mv[NEAR_NEWMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5240 frame_mv[NEAR_NEARMV][frame].as_int =
5241 frame_mv[NEARMV][frame].as_int;
5242 } else if (ref == 1) {
5243 frame_mv[NEAREST_NEARMV][frame].as_int =
5244 frame_mv[NEARMV][frame].as_int;
5245 frame_mv[NEAR_NEARESTMV][frame].as_int =
5246 frame_mv[NEARESTMV][frame].as_int;
5247 frame_mv[NEW_NEARESTMV][frame].as_int =
5248 frame_mv[NEARESTMV][frame].as_int;
5249 frame_mv[NEW_NEARMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5250 frame_mv[NEAR_NEARMV][frame].as_int =
5251 frame_mv[NEARMV][frame].as_int;
5252 }
5253 }
5254#endif // CONFIG_EXT_INTER
5255 }
5256
5257// search for the best motion vector on this segment
5258#if CONFIG_EXT_INTER
5259 for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
5260 this_mode <= (has_second_rf ? NEW_NEWMV : NEWFROMNEARMV);
5261 ++this_mode)
5262#else
5263 for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode)
5264#endif // CONFIG_EXT_INTER
5265 {
5266 const struct buf_2d orig_src = x->plane[0].src;
5267 struct buf_2d orig_pre[2];
5268 // This flag controls if the motion estimation will kick off. When it
5269 // is set to a non-zero value, the encoder will force motion estimation.
5270 int run_mv_search = 0;
5271
5272 mode_idx = INTER_OFFSET(this_mode);
5273#if CONFIG_EXT_INTER
5274 mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
5275
5276 for (ref = 0; ref < 1 + has_second_rf; ++ref)
5277 bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[mv_idx][ref].as_int;
5278#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005279 bsi->rdstat[index][mode_idx].brdcost = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005280 if (!(inter_mode_mask & (1 << this_mode))) continue;
5281
5282#if CONFIG_REF_MV
5283 run_mv_search = 2;
5284#if !CONFIG_EXT_INTER
5285 if (filter_idx > 0 && this_mode == NEWMV) {
5286 BEST_SEG_INFO *ref_bsi = bsi_buf;
Urvang Joshi454280d2016-10-14 16:51:44 -07005287 SEG_RDSTAT *ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005288
5289 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005290 if (seg_mvs[index][mbmi->ref_frame[0]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005291 ref_rdstat->mvs[0].as_int &&
5292 ref_rdstat->mvs[0].as_int != INVALID_MV)
5293 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
5294 --run_mv_search;
5295
Urvang Joshi454280d2016-10-14 16:51:44 -07005296 if (seg_mvs[index][mbmi->ref_frame[1]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005297 ref_rdstat->mvs[1].as_int &&
5298 ref_rdstat->mvs[1].as_int != INVALID_MV)
5299 if (bsi->ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
5300 --run_mv_search;
5301 } else {
5302 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
5303 ref_rdstat->mvs[0].as_int != INVALID_MV) {
5304 run_mv_search = 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005305 seg_mvs[index][mbmi->ref_frame[0]].as_int =
5306 ref_rdstat->mvs[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005307 }
5308 }
5309
5310 if (run_mv_search != 0 && filter_idx > 1) {
5311 ref_bsi = bsi_buf + 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07005312 ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005313 run_mv_search = 2;
5314
5315 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005316 if (seg_mvs[index][mbmi->ref_frame[0]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005317 ref_rdstat->mvs[0].as_int &&
5318 ref_rdstat->mvs[0].as_int != INVALID_MV)
5319 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
5320 --run_mv_search;
5321
Urvang Joshi454280d2016-10-14 16:51:44 -07005322 if (seg_mvs[index][mbmi->ref_frame[1]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005323 ref_rdstat->mvs[1].as_int &&
5324 ref_rdstat->mvs[1].as_int != INVALID_MV)
5325 if (bsi->ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
5326 --run_mv_search;
5327 } else {
5328 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
5329 ref_rdstat->mvs[0].as_int != INVALID_MV) {
5330 run_mv_search = 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005331 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005332 ref_rdstat->mvs[0].as_int;
5333 }
5334 }
5335 }
5336 }
5337#endif // CONFIG_EXT_INTER
5338#endif // CONFIG_REF_MV
5339
Sarah Parkere5299862016-08-16 14:57:37 -07005340#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +00005341 if (cm->global_motion[mbmi->ref_frame[0]].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -07005342 (!has_second_rf ||
David Barkercf3d0b02016-11-10 10:14:49 +00005343 cm->global_motion[mbmi->ref_frame[1]].wmtype == IDENTITY))
Sarah Parkere5299862016-08-16 14:57:37 -07005344#endif // CONFIG_GLOBAL_MOTION
5345
5346 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005347#if CONFIG_REF_MV && CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005348 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005349#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005350 frame_mv, this_mode, mbmi->ref_frame, bsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07005351 index))
Sarah Parkere5299862016-08-16 14:57:37 -07005352 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005353
5354 memcpy(orig_pre, pd->pre, sizeof(orig_pre));
Urvang Joshi454280d2016-10-14 16:51:44 -07005355 memcpy(bsi->rdstat[index][mode_idx].ta, t_above,
5356 sizeof(bsi->rdstat[index][mode_idx].ta));
5357 memcpy(bsi->rdstat[index][mode_idx].tl, t_left,
5358 sizeof(bsi->rdstat[index][mode_idx].tl));
Yushin Cho77bba8d2016-11-04 16:36:56 -07005359#if CONFIG_PVQ
5360 od_encode_rollback(&x->daala_enc, &idx_buf);
5361#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005362
5363 // motion search for newmv (single predictor case only)
5364 if (!has_second_rf &&
5365#if CONFIG_EXT_INTER
5366 have_newmv_in_inter_mode(this_mode) &&
Alex Converse6317c882016-09-29 14:21:37 -07005367 (seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005368#else
5369 this_mode == NEWMV &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005370 (seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07005371 run_mv_search)
5372#endif // CONFIG_EXT_INTER
5373 ) {
5374 int step_param = 0;
5375 int bestsme = INT_MAX;
5376 int sadpb = x->sadperbit4;
5377 MV mvp_full;
5378 int max_mv;
5379 int cost_list[5];
5380 int tmp_col_min = x->mv_col_min;
5381 int tmp_col_max = x->mv_col_max;
5382 int tmp_row_min = x->mv_row_min;
5383 int tmp_row_max = x->mv_row_max;
5384
5385 /* Is the best so far sufficiently good that we cant justify doing
5386 * and new motion search. */
Urvang Joshi454280d2016-10-14 16:51:44 -07005387 if (new_best_rd < label_mv_thresh) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005388
5389 if (cpi->oxcf.mode != BEST) {
5390#if CONFIG_EXT_INTER
5391 bsi->mvp.as_int = bsi->ref_mv[0]->as_int;
5392#else
5393// use previous block's result as next block's MV predictor.
5394#if !CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07005395 if (index > 0) {
5396 bsi->mvp.as_int = mi->bmi[index - 1].as_mv[0].as_int;
5397 if (index == 2)
5398 bsi->mvp.as_int = mi->bmi[index - 2].as_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005399 }
5400#endif
5401#endif // CONFIG_EXT_INTER
5402 }
Urvang Joshi454280d2016-10-14 16:51:44 -07005403 max_mv = (index == 0) ? (int)x->max_mv_context[mbmi->ref_frame[0]]
5404 : AOMMAX(abs(bsi->mvp.as_mv.row),
5405 abs(bsi->mvp.as_mv.col)) >>
5406 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005407
5408 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
5409 // Take wtd average of the step_params based on the last frame's
5410 // max mv magnitude and the best ref mvs of the current block for
5411 // the given reference.
5412 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07005413 (av1_init_search_range(max_mv) + cpi->mv_step_param) / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005414 } else {
5415 step_param = cpi->mv_step_param;
5416 }
5417
5418#if CONFIG_REF_MV
5419 mvp_full.row = bsi->ref_mv[0]->as_mv.row >> 3;
5420 mvp_full.col = bsi->ref_mv[0]->as_mv.col >> 3;
5421#else
5422 mvp_full.row = bsi->mvp.as_mv.row >> 3;
5423 mvp_full.col = bsi->mvp.as_mv.col >> 3;
5424#endif
5425
5426 if (cpi->sf.adaptive_motion_search) {
5427 mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
5428 mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
Yaowu Xuf883b422016-08-30 14:01:10 -07005429 step_param = AOMMAX(step_param, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005430 }
5431
5432 // adjust src pointer for this block
Urvang Joshi454280d2016-10-14 16:51:44 -07005433 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005434
Yaowu Xuf883b422016-08-30 14:01:10 -07005435 av1_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005436
5437 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
5438
5439#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005440 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005441#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07005442 bestsme = av1_full_pixel_search(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005443 cpi, x, bsize, &mvp_full, step_param, sadpb,
5444 cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
5445 &bsi->ref_mv[0]->as_mv, INT_MAX, 1);
5446
5447 x->mv_col_min = tmp_col_min;
5448 x->mv_col_max = tmp_col_max;
5449 x->mv_row_min = tmp_row_min;
5450 x->mv_row_max = tmp_row_max;
5451
5452 if (bestsme < INT_MAX) {
5453 int distortion;
5454 if (cpi->sf.use_upsampled_references) {
5455 int best_mv_var;
5456 const int try_second =
5457 x->second_best_mv.as_int != INVALID_MV &&
5458 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08005459 const int pw = block_size_wide[bsize];
5460 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005461 // Use up-sampled reference frames.
Yaowu Xuc27fc142016-08-22 16:08:15 -07005462 struct buf_2d backup_pred = pd->pre[0];
5463 const YV12_BUFFER_CONFIG *upsampled_ref =
5464 get_upsampled_ref(cpi, mbmi->ref_frame[0]);
5465
5466 // Set pred for Y plane
5467 setup_pred_plane(
5468 &pd->pre[0], upsampled_ref->y_buffer,
5469 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
5470 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
5471 pd->subsampling_x, pd->subsampling_y);
5472
5473 // adjust pred pointer for this block
5474 pd->pre[0].buf =
Urvang Joshi454280d2016-10-14 16:51:44 -07005475 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, index,
Yaowu Xuf883b422016-08-30 14:01:10 -07005476 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005477 << 3];
5478
5479 best_mv_var = cpi->find_fractional_mv_step(
5480 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
5481 x->errorperbit, &cpi->fn_ptr[bsize],
5482 cpi->sf.mv.subpel_force_stop,
5483 cpi->sf.mv.subpel_iters_per_step,
5484 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
5485 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, pw, ph,
5486 1);
5487
5488 if (try_second) {
5489 int this_var;
5490 MV best_mv = x->best_mv.as_mv;
5491 const MV ref_mv = bsi->ref_mv[0]->as_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07005492 const int minc = AOMMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
5493 const int maxc = AOMMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
5494 const int minr = AOMMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
5495 const int maxr = AOMMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005496
5497 x->best_mv = x->second_best_mv;
5498 if (x->best_mv.as_mv.row * 8 <= maxr &&
5499 x->best_mv.as_mv.row * 8 >= minr &&
5500 x->best_mv.as_mv.col * 8 <= maxc &&
5501 x->best_mv.as_mv.col * 8 >= minc) {
5502 this_var = cpi->find_fractional_mv_step(
5503 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
5504 x->errorperbit, &cpi->fn_ptr[bsize],
5505 cpi->sf.mv.subpel_force_stop,
5506 cpi->sf.mv.subpel_iters_per_step,
5507 cond_cost_list(cpi, cost_list), x->nmvjointcost,
5508 x->mvcost, &distortion, &x->pred_sse[mbmi->ref_frame[0]],
5509 NULL, pw, ph, 1);
5510 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
5511 x->best_mv.as_mv = best_mv;
5512 }
5513 }
5514
5515 // Restore the reference frames.
5516 pd->pre[0] = backup_pred;
5517 } else {
5518 cpi->find_fractional_mv_step(
5519 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
5520 x->errorperbit, &cpi->fn_ptr[bsize],
5521 cpi->sf.mv.subpel_force_stop,
5522 cpi->sf.mv.subpel_iters_per_step,
5523 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
5524 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, 0, 0, 0);
5525 }
5526
5527// save motion search result for use in compound prediction
5528#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005529 seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005530#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005531 seg_mvs[index][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005532#endif // CONFIG_EXT_INTER
5533 }
5534
5535 if (cpi->sf.adaptive_motion_search)
5536 x->pred_mv[mbmi->ref_frame[0]] = x->best_mv.as_mv;
5537
5538#if CONFIG_EXT_INTER
5539 mode_mv[this_mode][0] = x->best_mv;
5540#else
5541 mode_mv[NEWMV][0] = x->best_mv;
5542#endif // CONFIG_EXT_INTER
5543
5544 // restore src pointers
5545 mi_buf_restore(x, orig_src, orig_pre);
5546 }
5547
5548 if (has_second_rf) {
5549#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005550 if (seg_mvs[index][mv_idx][mbmi->ref_frame[1]].as_int == INVALID_MV ||
5551 seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005552#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005553 if (seg_mvs[index][mbmi->ref_frame[1]].as_int == INVALID_MV ||
5554 seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005555#endif // CONFIG_EXT_INTER
5556 continue;
5557 }
5558
5559#if CONFIG_DUAL_FILTER
5560 (void)run_mv_search;
5561#endif
5562
5563 if (has_second_rf &&
5564#if CONFIG_EXT_INTER
5565 this_mode == NEW_NEWMV &&
5566#else
5567 this_mode == NEWMV &&
5568#endif // CONFIG_EXT_INTER
5569#if CONFIG_DUAL_FILTER
5570 (mbmi->interp_filter[0] == EIGHTTAP_REGULAR || run_mv_search))
5571#else
5572 (mbmi->interp_filter == EIGHTTAP_REGULAR || run_mv_search))
5573#endif
5574 {
5575 // adjust src pointers
Urvang Joshi454280d2016-10-14 16:51:44 -07005576 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005577 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
5578 int rate_mv;
5579 joint_motion_search(cpi, x, bsize, frame_mv[this_mode], mi_row,
5580 mi_col,
5581#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005582 bsi->ref_mv, seg_mvs[index][mv_idx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005583#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005584 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005585#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005586 &rate_mv, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005587#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005588 compound_seg_newmvs[index][0].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005589 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07005590 compound_seg_newmvs[index][1].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005591 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
5592#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005593 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005594 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07005595 seg_mvs[index][mbmi->ref_frame[1]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005596 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
5597#endif // CONFIG_EXT_INTER
5598 }
5599 // restore src pointers
5600 mi_buf_restore(x, orig_src, orig_pre);
5601 }
5602
Urvang Joshi454280d2016-10-14 16:51:44 -07005603 bsi->rdstat[index][mode_idx].brate = set_and_cost_bmi_mvs(
5604 cpi, x, xd, index, this_mode, mode_mv[this_mode], frame_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005605#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005606 seg_mvs[index][mv_idx], compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005607#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005608 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005609#endif // CONFIG_EXT_INTER
5610 bsi->ref_mv, x->nmvjointcost, x->mvcost);
5611
5612 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005613 bsi->rdstat[index][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005614 mode_mv[this_mode][ref].as_int;
5615 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005616 bsi->rdstat[index + 1][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005617 mode_mv[this_mode][ref].as_int;
5618 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005619 bsi->rdstat[index + 2][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005620 mode_mv[this_mode][ref].as_int;
5621#if CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07005622 bsi->rdstat[index][mode_idx].pred_mv[ref].as_int =
5623 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005624 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005625 bsi->rdstat[index + 1][mode_idx].pred_mv[ref].as_int =
5626 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005627 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005628 bsi->rdstat[index + 2][mode_idx].pred_mv[ref].as_int =
5629 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005630#endif
5631#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005632 bsi->rdstat[index][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005633 bsi->ref_mv[ref]->as_int;
5634 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005635 bsi->rdstat[index + 1][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005636 bsi->ref_mv[ref]->as_int;
5637 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005638 bsi->rdstat[index + 2][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005639 bsi->ref_mv[ref]->as_int;
5640#endif // CONFIG_EXT_INTER
5641 }
5642
5643 // Trap vectors that reach beyond the UMV borders
5644 if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
5645 (has_second_rf && mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
5646 continue;
5647
5648 if (filter_idx > 0) {
5649 BEST_SEG_INFO *ref_bsi = bsi_buf;
5650 subpelmv = 0;
5651 have_ref = 1;
5652
5653 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5654 subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
5655#if CONFIG_EXT_INTER
5656 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07005657 have_ref &=
5658 ((mode_mv[this_mode][ref].as_int ==
5659 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
5660 (bsi->ref_mv[ref]->as_int ==
5661 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005662 else
5663#endif // CONFIG_EXT_INTER
5664 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07005665 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005666 }
5667
Urvang Joshi454280d2016-10-14 16:51:44 -07005668 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005669
5670 if (filter_idx > 1 && !subpelmv && !have_ref) {
5671 ref_bsi = bsi_buf + 1;
5672 have_ref = 1;
5673 for (ref = 0; ref < 1 + has_second_rf; ++ref)
5674#if CONFIG_EXT_INTER
5675 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07005676 have_ref &=
5677 ((mode_mv[this_mode][ref].as_int ==
5678 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
5679 (bsi->ref_mv[ref]->as_int ==
5680 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005681 else
5682#endif // CONFIG_EXT_INTER
5683 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07005684 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005685
Urvang Joshi454280d2016-10-14 16:51:44 -07005686 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005687 }
5688
5689 if (!subpelmv && have_ref &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005690 ref_bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005691#if CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07005692 bsi->rdstat[index][mode_idx].byrate =
5693 ref_bsi->rdstat[index][mode_idx].byrate;
5694 bsi->rdstat[index][mode_idx].bdist =
5695 ref_bsi->rdstat[index][mode_idx].bdist;
5696 bsi->rdstat[index][mode_idx].bsse =
5697 ref_bsi->rdstat[index][mode_idx].bsse;
5698 bsi->rdstat[index][mode_idx].brate +=
5699 ref_bsi->rdstat[index][mode_idx].byrate;
5700 bsi->rdstat[index][mode_idx].eobs =
5701 ref_bsi->rdstat[index][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005702
Urvang Joshi454280d2016-10-14 16:51:44 -07005703 bsi->rdstat[index][mode_idx].brdcost =
5704 RDCOST(x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate,
5705 bsi->rdstat[index][mode_idx].bdist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005706
Urvang Joshi454280d2016-10-14 16:51:44 -07005707 memcpy(bsi->rdstat[index][mode_idx].ta,
5708 ref_bsi->rdstat[index][mode_idx].ta,
5709 sizeof(bsi->rdstat[index][mode_idx].ta));
5710 memcpy(bsi->rdstat[index][mode_idx].tl,
5711 ref_bsi->rdstat[index][mode_idx].tl,
5712 sizeof(bsi->rdstat[index][mode_idx].tl));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005713#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005714 memcpy(&bsi->rdstat[index][mode_idx],
5715 &ref_bsi->rdstat[index][mode_idx], sizeof(SEG_RDSTAT));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005716#endif
5717 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005718 bsi->rdstat[index + 1][mode_idx].eobs =
5719 ref_bsi->rdstat[index + 1][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005720 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005721 bsi->rdstat[index + 2][mode_idx].eobs =
5722 ref_bsi->rdstat[index + 2][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005723
Urvang Joshi454280d2016-10-14 16:51:44 -07005724 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005725#if CONFIG_REF_MV
5726 // If the NEWMV mode is using the same motion vector as the
5727 // NEARESTMV mode, skip the rest rate-distortion calculations
5728 // and use the inferred motion vector modes.
5729 if (this_mode == NEWMV) {
5730 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005731 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005732 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005733 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005734 bsi->ref_mv[1]->as_int)
5735 continue;
5736 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07005737 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005738 bsi->ref_mv[0]->as_int)
5739 continue;
5740 }
5741 }
5742#endif
5743 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07005744 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005745#if CONFIG_PVQ
5746 od_encode_checkpoint(&x->daala_enc, &post_buf);
5747#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005748 }
5749 continue;
5750 }
5751 }
5752
Urvang Joshi454280d2016-10-14 16:51:44 -07005753 bsi->rdstat[index][mode_idx].brdcost = encode_inter_mb_segment(
5754 cpi, x, bsi->segment_rd - this_segment_rd, index,
5755 &bsi->rdstat[index][mode_idx].byrate,
5756 &bsi->rdstat[index][mode_idx].bdist,
5757 &bsi->rdstat[index][mode_idx].bsse, bsi->rdstat[index][mode_idx].ta,
5758 bsi->rdstat[index][mode_idx].tl, idy, idx, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005759
Urvang Joshi454280d2016-10-14 16:51:44 -07005760 if (bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
5761 bsi->rdstat[index][mode_idx].brdcost += RDCOST(
5762 x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate, 0);
5763 bsi->rdstat[index][mode_idx].brate +=
5764 bsi->rdstat[index][mode_idx].byrate;
5765 bsi->rdstat[index][mode_idx].eobs = p->eobs[index];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005766 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005767 bsi->rdstat[index + 1][mode_idx].eobs = p->eobs[index + 1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005768 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005769 bsi->rdstat[index + 2][mode_idx].eobs = p->eobs[index + 2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005770 }
5771
Urvang Joshi454280d2016-10-14 16:51:44 -07005772 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005773#if CONFIG_REF_MV
5774 // If the NEWMV mode is using the same motion vector as the
5775 // NEARESTMV mode, skip the rest rate-distortion calculations
5776 // and use the inferred motion vector modes.
5777 if (this_mode == NEWMV) {
5778 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005779 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005780 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005781 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005782 bsi->ref_mv[1]->as_int)
5783 continue;
5784 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07005785 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005786 bsi->ref_mv[0]->as_int)
5787 continue;
5788 }
5789 }
5790#endif
5791 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07005792 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005793
5794#if CONFIG_PVQ
5795 od_encode_checkpoint(&x->daala_enc, &post_buf);
5796#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005797 }
5798 } /*for each 4x4 mode*/
5799
Urvang Joshi454280d2016-10-14 16:51:44 -07005800 if (new_best_rd == INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005801 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07005802 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005803#if CONFIG_EXT_INTER
5804 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
5805#else
5806 for (midx = 0; midx < INTER_MODES; ++midx)
5807#endif // CONFIG_EXT_INTER
5808 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
5809 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005810#if CONFIG_PVQ
5811 od_encode_rollback(&x->daala_enc, &pre_buf);
5812#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005813 return INT64_MAX;
5814 }
5815
5816 mode_idx = INTER_OFFSET(mode_selected);
Urvang Joshi454280d2016-10-14 16:51:44 -07005817 memcpy(t_above, bsi->rdstat[index][mode_idx].ta, sizeof(t_above));
5818 memcpy(t_left, bsi->rdstat[index][mode_idx].tl, sizeof(t_left));
Yushin Cho77bba8d2016-11-04 16:36:56 -07005819#if CONFIG_PVQ
5820 od_encode_rollback(&x->daala_enc, &post_buf);
5821#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005822
5823#if CONFIG_EXT_INTER
5824 mv_idx = (mode_selected == NEWFROMNEARMV) ? 1 : 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005825 bsi->ref_mv[0]->as_int = bsi->rdstat[index][mode_idx].ref_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005826 if (has_second_rf)
Urvang Joshi454280d2016-10-14 16:51:44 -07005827 bsi->ref_mv[1]->as_int = bsi->rdstat[index][mode_idx].ref_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005828#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005829 set_and_cost_bmi_mvs(cpi, x, xd, index, mode_selected,
5830 mode_mv[mode_selected], frame_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005831#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005832 seg_mvs[index][mv_idx], compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005833#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005834 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005835#endif // CONFIG_EXT_INTER
5836 bsi->ref_mv, x->nmvjointcost, x->mvcost);
5837
Urvang Joshi454280d2016-10-14 16:51:44 -07005838 br += bsi->rdstat[index][mode_idx].brate;
5839 bd += bsi->rdstat[index][mode_idx].bdist;
5840 block_sse += bsi->rdstat[index][mode_idx].bsse;
5841 segmentyrate += bsi->rdstat[index][mode_idx].byrate;
5842 this_segment_rd += bsi->rdstat[index][mode_idx].brdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005843
5844 if (this_segment_rd > bsi->segment_rd) {
5845 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07005846 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005847#if CONFIG_EXT_INTER
5848 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
5849#else
5850 for (midx = 0; midx < INTER_MODES; ++midx)
5851#endif // CONFIG_EXT_INTER
5852 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
5853 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005854#if CONFIG_PVQ
5855 od_encode_rollback(&x->daala_enc, &pre_buf);
5856#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005857 return INT64_MAX;
5858 }
5859 }
5860 } /* for each label */
Yushin Cho77bba8d2016-11-04 16:36:56 -07005861#if CONFIG_PVQ
5862 od_encode_rollback(&x->daala_enc, &pre_buf);
5863#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005864
5865 bsi->r = br;
5866 bsi->d = bd;
5867 bsi->segment_yrate = segmentyrate;
5868 bsi->segment_rd = this_segment_rd;
5869 bsi->sse = block_sse;
5870
5871 // update the coding decisions
5872 for (k = 0; k < 4; ++k) bsi->modes[k] = mi->bmi[k].as_mode;
5873
5874 if (bsi->segment_rd > best_rd) return INT64_MAX;
5875 /* set it to the best */
5876 for (idx = 0; idx < 4; idx++) {
5877 mode_idx = INTER_OFFSET(bsi->modes[idx]);
5878 mi->bmi[idx].as_mv[0].as_int = bsi->rdstat[idx][mode_idx].mvs[0].as_int;
5879 if (has_second_ref(mbmi))
5880 mi->bmi[idx].as_mv[1].as_int = bsi->rdstat[idx][mode_idx].mvs[1].as_int;
5881#if CONFIG_REF_MV
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07005882 mi->bmi[idx].pred_mv[0] = bsi->rdstat[idx][mode_idx].pred_mv[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005883 if (has_second_ref(mbmi))
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07005884 mi->bmi[idx].pred_mv[1] = bsi->rdstat[idx][mode_idx].pred_mv[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005885#endif
5886#if CONFIG_EXT_INTER
5887 mi->bmi[idx].ref_mv[0].as_int = bsi->rdstat[idx][mode_idx].ref_mv[0].as_int;
5888 if (has_second_rf)
5889 mi->bmi[idx].ref_mv[1].as_int =
5890 bsi->rdstat[idx][mode_idx].ref_mv[1].as_int;
5891#endif // CONFIG_EXT_INTER
5892 x->plane[0].eobs[idx] = bsi->rdstat[idx][mode_idx].eobs;
5893 mi->bmi[idx].as_mode = bsi->modes[idx];
5894 }
5895
5896 /*
5897 * used to set mbmi->mv.as_int
5898 */
5899 *returntotrate = bsi->r;
5900 *returndistortion = bsi->d;
5901 *returnyrate = bsi->segment_yrate;
Yaowu Xuf883b422016-08-30 14:01:10 -07005902 *skippable = av1_is_skippable_in_plane(x, BLOCK_8X8, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005903 *psse = bsi->sse;
5904 mbmi->mode = bsi->modes[3];
5905
5906 return bsi->segment_rd;
5907}
5908
Yaowu Xuf883b422016-08-30 14:01:10 -07005909static void estimate_ref_frame_costs(const AV1_COMMON *cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005910 const MACROBLOCKD *xd, int segment_id,
5911 unsigned int *ref_costs_single,
5912 unsigned int *ref_costs_comp,
Yaowu Xuf883b422016-08-30 14:01:10 -07005913 aom_prob *comp_mode_p) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005914 int seg_ref_active =
5915 segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
5916 if (seg_ref_active) {
5917 memset(ref_costs_single, 0,
5918 TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_single));
5919 memset(ref_costs_comp, 0, TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_comp));
5920 *comp_mode_p = 128;
5921 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005922 aom_prob intra_inter_p = av1_get_intra_inter_prob(cm, xd);
5923 aom_prob comp_inter_p = 128;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005924
5925 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005926 comp_inter_p = av1_get_reference_mode_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005927 *comp_mode_p = comp_inter_p;
5928 } else {
5929 *comp_mode_p = 128;
5930 }
5931
Yaowu Xuf883b422016-08-30 14:01:10 -07005932 ref_costs_single[INTRA_FRAME] = av1_cost_bit(intra_inter_p, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005933
5934 if (cm->reference_mode != COMPOUND_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005935 aom_prob ref_single_p1 = av1_get_pred_prob_single_ref_p1(cm, xd);
5936 aom_prob ref_single_p2 = av1_get_pred_prob_single_ref_p2(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005937#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005938 aom_prob ref_single_p3 = av1_get_pred_prob_single_ref_p3(cm, xd);
5939 aom_prob ref_single_p4 = av1_get_pred_prob_single_ref_p4(cm, xd);
5940 aom_prob ref_single_p5 = av1_get_pred_prob_single_ref_p5(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005941#endif // CONFIG_EXT_REFS
5942
Yaowu Xuf883b422016-08-30 14:01:10 -07005943 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005944
5945 ref_costs_single[LAST_FRAME] =
5946#if CONFIG_EXT_REFS
5947 ref_costs_single[LAST2_FRAME] = ref_costs_single[LAST3_FRAME] =
5948 ref_costs_single[BWDREF_FRAME] =
5949#endif // CONFIG_EXT_REFS
5950 ref_costs_single[GOLDEN_FRAME] =
5951 ref_costs_single[ALTREF_FRAME] = base_cost;
5952
5953#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005954 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
5955 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p1, 0);
5956 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p1, 0);
5957 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 0);
5958 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
5959 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005960
Yaowu Xuf883b422016-08-30 14:01:10 -07005961 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p3, 0);
5962 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p3, 0);
5963 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p3, 1);
5964 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p3, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005965
Yaowu Xuf883b422016-08-30 14:01:10 -07005966 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p2, 0);
5967 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005968
Yaowu Xuf883b422016-08-30 14:01:10 -07005969 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p4, 0);
5970 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p4, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005971
Yaowu Xuf883b422016-08-30 14:01:10 -07005972 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p5, 0);
5973 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p5, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005974#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005975 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
5976 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 1);
5977 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005978
Yaowu Xuf883b422016-08-30 14:01:10 -07005979 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p2, 0);
5980 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005981#endif // CONFIG_EXT_REFS
5982 } else {
5983 ref_costs_single[LAST_FRAME] = 512;
5984#if CONFIG_EXT_REFS
5985 ref_costs_single[LAST2_FRAME] = 512;
5986 ref_costs_single[LAST3_FRAME] = 512;
5987 ref_costs_single[BWDREF_FRAME] = 512;
5988#endif // CONFIG_EXT_REFS
5989 ref_costs_single[GOLDEN_FRAME] = 512;
5990 ref_costs_single[ALTREF_FRAME] = 512;
5991 }
5992
5993 if (cm->reference_mode != SINGLE_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005994 aom_prob ref_comp_p = av1_get_pred_prob_comp_ref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005995#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005996 aom_prob ref_comp_p1 = av1_get_pred_prob_comp_ref_p1(cm, xd);
5997 aom_prob ref_comp_p2 = av1_get_pred_prob_comp_ref_p2(cm, xd);
5998 aom_prob bwdref_comp_p = av1_get_pred_prob_comp_bwdref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005999#endif // CONFIG_EXT_REFS
6000
Yaowu Xuf883b422016-08-30 14:01:10 -07006001 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006002
6003 ref_costs_comp[LAST_FRAME] =
6004#if CONFIG_EXT_REFS
6005 ref_costs_comp[LAST2_FRAME] = ref_costs_comp[LAST3_FRAME] =
6006#endif // CONFIG_EXT_REFS
6007 ref_costs_comp[GOLDEN_FRAME] = base_cost;
6008
6009#if CONFIG_EXT_REFS
6010 ref_costs_comp[BWDREF_FRAME] = ref_costs_comp[ALTREF_FRAME] = 0;
6011#endif // CONFIG_EXT_REFS
6012
6013#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006014 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6015 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p, 0);
6016 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p, 1);
6017 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006018
Yaowu Xuf883b422016-08-30 14:01:10 -07006019 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p1, 1);
6020 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006021
Yaowu Xuf883b422016-08-30 14:01:10 -07006022 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p2, 0);
6023 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006024
6025 // NOTE(zoeliu): BWDREF and ALTREF each add an extra cost by coding 1
6026 // more bit.
Yaowu Xuf883b422016-08-30 14:01:10 -07006027 ref_costs_comp[BWDREF_FRAME] += av1_cost_bit(bwdref_comp_p, 0);
6028 ref_costs_comp[ALTREF_FRAME] += av1_cost_bit(bwdref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006029#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006030 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6031 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006032#endif // CONFIG_EXT_REFS
6033 } else {
6034 ref_costs_comp[LAST_FRAME] = 512;
6035#if CONFIG_EXT_REFS
6036 ref_costs_comp[LAST2_FRAME] = 512;
6037 ref_costs_comp[LAST3_FRAME] = 512;
6038 ref_costs_comp[BWDREF_FRAME] = 512;
6039 ref_costs_comp[ALTREF_FRAME] = 512;
6040#endif // CONFIG_EXT_REFS
6041 ref_costs_comp[GOLDEN_FRAME] = 512;
6042 }
6043 }
6044}
6045
6046static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
6047 int mode_index,
6048 int64_t comp_pred_diff[REFERENCE_MODES],
6049 int skippable) {
6050 MACROBLOCKD *const xd = &x->e_mbd;
6051
6052 // Take a snapshot of the coding context so it can be
6053 // restored if we decide to encode this way
6054 ctx->skip = x->skip;
6055 ctx->skippable = skippable;
6056 ctx->best_mode_index = mode_index;
6057 ctx->mic = *xd->mi[0];
6058 ctx->mbmi_ext = *x->mbmi_ext;
6059 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
6060 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
6061 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
6062}
6063
Urvang Joshi52648442016-10-13 17:27:51 -07006064static void setup_buffer_inter(const AV1_COMP *const cpi, MACROBLOCK *x,
clang-format67948d32016-09-07 22:40:40 -07006065 MV_REFERENCE_FRAME ref_frame,
6066 BLOCK_SIZE block_size, int mi_row, int mi_col,
6067 int_mv frame_nearest_mv[TOTAL_REFS_PER_FRAME],
6068 int_mv frame_near_mv[TOTAL_REFS_PER_FRAME],
6069 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME]
6070 [MAX_MB_PLANE]) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006071 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006072 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
6073 MACROBLOCKD *const xd = &x->e_mbd;
6074 MODE_INFO *const mi = xd->mi[0];
6075 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
6076 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
6077 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6078
6079 assert(yv12 != NULL);
6080
6081 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
6082 // use the UV scaling factors.
Yaowu Xuf883b422016-08-30 14:01:10 -07006083 av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006084
6085 // Gets an initial list of candidate vectors from neighbours and orders them
Yaowu Xuf883b422016-08-30 14:01:10 -07006086 av1_find_mv_refs(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006087 cm, xd, mi, ref_frame,
6088#if CONFIG_REF_MV
6089 &mbmi_ext->ref_mv_count[ref_frame], mbmi_ext->ref_mv_stack[ref_frame],
6090#if CONFIG_EXT_INTER
6091 mbmi_ext->compound_mode_context,
6092#endif // CONFIG_EXT_INTER
6093#endif
6094 candidates, mi_row, mi_col, NULL, NULL, mbmi_ext->mode_context);
6095
6096 // Candidate refinement carried out at encoder and decoder
Yaowu Xuf883b422016-08-30 14:01:10 -07006097 av1_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
6098 &frame_nearest_mv[ref_frame],
6099 &frame_near_mv[ref_frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006100
6101 // Further refinement that is encode side only to test the top few candidates
6102 // in full and choose the best as the centre point for subsequent searches.
6103 // The current implementation doesn't support scaling.
Yaowu Xuf883b422016-08-30 14:01:10 -07006104 if (!av1_is_scaled(sf) && block_size >= BLOCK_8X8)
6105 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6106 block_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006107}
6108
Urvang Joshi52648442016-10-13 17:27:51 -07006109static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
6110 BLOCK_SIZE bsize, int mi_row, int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006111#if CONFIG_EXT_INTER
6112 int ref_idx, int mv_idx,
6113#endif // CONFIG_EXT_INTER
6114 int *rate_mv) {
6115 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07006116 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006117 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6118 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
6119 int bestsme = INT_MAX;
6120 int step_param;
6121 int sadpb = x->sadperbit16;
6122 MV mvp_full;
6123#if CONFIG_EXT_INTER
6124 int ref = mbmi->ref_frame[ref_idx];
6125 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
6126#else
6127 int ref = mbmi->ref_frame[0];
6128 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6129 int ref_idx = 0;
6130#endif // CONFIG_EXT_INTER
6131
6132 int tmp_col_min = x->mv_col_min;
6133 int tmp_col_max = x->mv_col_max;
6134 int tmp_row_min = x->mv_row_min;
6135 int tmp_row_max = x->mv_row_max;
6136 int cost_list[5];
6137
6138 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07006139 av1_get_scaled_ref_frame(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006140
6141 MV pred_mv[3];
6142 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6143 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
6144 pred_mv[2] = x->pred_mv[ref];
6145
Yaowu Xuc27fc142016-08-22 16:08:15 -07006146 if (scaled_ref_frame) {
6147 int i;
6148 // Swap out the reference frame for a version that's been scaled to
6149 // match the resolution of the current frame, allowing the existing
6150 // motion search code to be used without additional modifications.
6151 for (i = 0; i < MAX_MB_PLANE; i++)
6152 backup_yv12[i] = xd->plane[i].pre[ref_idx];
6153
Yaowu Xuf883b422016-08-30 14:01:10 -07006154 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006155 }
6156
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006157 av1_set_mv_search_range(x, &ref_mv);
6158
6159#if CONFIG_REF_MV
6160 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
6161#endif
6162
Yaowu Xuc27fc142016-08-22 16:08:15 -07006163 // Work out the size of the first step in the mv step search.
Yaowu Xuf883b422016-08-30 14:01:10 -07006164 // 0 here is maximum length first step. 1 is AOMMAX >> 1 etc.
Yaowu Xuc27fc142016-08-22 16:08:15 -07006165 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6166 // Take wtd average of the step_params based on the last frame's
6167 // max mv magnitude and that based on the best ref mvs of the current
6168 // block for the given reference.
6169 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006170 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07006171 2;
6172 } else {
6173 step_param = cpi->mv_step_param;
6174 }
6175
6176 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size) {
6177 int boffset =
6178 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07006179 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
6180 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006181 }
6182
6183 if (cpi->sf.adaptive_motion_search) {
6184 int bwl = b_width_log2_lookup[bsize];
6185 int bhl = b_height_log2_lookup[bsize];
6186 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
6187
6188 if (tlevel < 5) step_param += 2;
6189
6190 // prev_mv_sad is not setup for dynamically scaled frames.
6191 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
6192 int i;
6193 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
6194 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
6195 x->pred_mv[ref].row = 0;
6196 x->pred_mv[ref].col = 0;
6197 x->best_mv.as_int = INVALID_MV;
6198
6199 if (scaled_ref_frame) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006200 int j;
6201 for (j = 0; j < MAX_MB_PLANE; ++j)
6202 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006203 }
6204 return;
6205 }
6206 }
6207 }
6208 }
6209
Yaowu Xuf883b422016-08-30 14:01:10 -07006210 av1_set_mv_search_range(x, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006211
Yue Chene9638cc2016-10-10 12:37:54 -07006212#if CONFIG_MOTION_VAR
6213 if (mbmi->motion_mode != SIMPLE_TRANSLATION)
6214 mvp_full = mbmi->mv[0].as_mv;
6215 else
6216#endif // CONFIG_MOTION_VAR
6217 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006218
6219 mvp_full.col >>= 3;
6220 mvp_full.row >>= 3;
6221
6222 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
6223
Yue Chene9638cc2016-10-10 12:37:54 -07006224#if CONFIG_MOTION_VAR
6225 switch (mbmi->motion_mode) {
6226 case SIMPLE_TRANSLATION:
6227#endif // CONFIG_MOTION_VAR
6228 bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
6229 sadpb, cond_cost_list(cpi, cost_list),
6230 &ref_mv, INT_MAX, 1);
6231#if CONFIG_MOTION_VAR
6232 break;
6233 case OBMC_CAUSAL:
6234 bestsme = av1_obmc_full_pixel_diamond(
6235 cpi, x, &mvp_full, step_param, sadpb,
6236 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
6237 &(x->best_mv.as_mv), 0);
6238 break;
6239 default: assert("Invalid motion mode!\n");
6240 }
6241#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006242
6243 x->mv_col_min = tmp_col_min;
6244 x->mv_col_max = tmp_col_max;
6245 x->mv_row_min = tmp_row_min;
6246 x->mv_row_max = tmp_row_max;
6247
6248 if (bestsme < INT_MAX) {
6249 int dis; /* TODO: use dis in distortion calculation later. */
Yue Chene9638cc2016-10-10 12:37:54 -07006250#if CONFIG_MOTION_VAR
6251 switch (mbmi->motion_mode) {
6252 case SIMPLE_TRANSLATION:
6253#endif // CONFIG_MOTION_VAR
6254 if (cpi->sf.use_upsampled_references) {
6255 int best_mv_var;
6256 const int try_second = x->second_best_mv.as_int != INVALID_MV &&
6257 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006258 const int pw = block_size_wide[bsize];
6259 const int ph = block_size_high[bsize];
Yue Chene9638cc2016-10-10 12:37:54 -07006260 // Use up-sampled reference frames.
6261 struct macroblockd_plane *const pd = &xd->plane[0];
6262 struct buf_2d backup_pred = pd->pre[ref_idx];
6263 const YV12_BUFFER_CONFIG *upsampled_ref = get_upsampled_ref(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006264
Yue Chene9638cc2016-10-10 12:37:54 -07006265 // Set pred for Y plane
6266 setup_pred_plane(
6267 &pd->pre[ref_idx], upsampled_ref->y_buffer,
6268 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
6269 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
6270 pd->subsampling_x, pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006271
Yue Chene9638cc2016-10-10 12:37:54 -07006272 best_mv_var = cpi->find_fractional_mv_step(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006273 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6274 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6275 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
6276 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, pw, ph,
6277 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006278
Yue Chene9638cc2016-10-10 12:37:54 -07006279 if (try_second) {
6280 const int minc = AOMMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
6281 const int maxc = AOMMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
6282 const int minr = AOMMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
6283 const int maxr = AOMMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
6284 int this_var;
6285 MV best_mv = x->best_mv.as_mv;
6286
6287 x->best_mv = x->second_best_mv;
6288 if (x->best_mv.as_mv.row * 8 <= maxr &&
6289 x->best_mv.as_mv.row * 8 >= minr &&
6290 x->best_mv.as_mv.col * 8 <= maxc &&
6291 x->best_mv.as_mv.col * 8 >= minc) {
6292 this_var = cpi->find_fractional_mv_step(
6293 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6294 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6295 cpi->sf.mv.subpel_iters_per_step,
6296 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
6297 &dis, &x->pred_sse[ref], NULL, pw, ph, 1);
6298 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
6299 x->best_mv.as_mv = best_mv;
6300 }
6301 }
6302
6303 // Restore the reference frames.
6304 pd->pre[ref_idx] = backup_pred;
6305 } else {
6306 cpi->find_fractional_mv_step(
6307 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6308 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6309 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
6310 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, 0, 0,
6311 0);
6312 }
6313#if CONFIG_MOTION_VAR
6314 break;
6315 case OBMC_CAUSAL:
6316 av1_find_best_obmc_sub_pixel_tree_up(
6317 cpi, x, mi_row, mi_col, &x->best_mv.as_mv, &ref_mv,
6318 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
6319 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
6320 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], 0,
6321 cpi->sf.use_upsampled_references);
6322 break;
6323 default: assert("Invalid motion mode!\n");
Yaowu Xuc27fc142016-08-22 16:08:15 -07006324 }
Yue Chene9638cc2016-10-10 12:37:54 -07006325#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006326 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006327 *rate_mv = av1_mv_bit_cost(&x->best_mv.as_mv, &ref_mv, x->nmvjointcost,
6328 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006329
Yue Chene9638cc2016-10-10 12:37:54 -07006330#if CONFIG_MOTION_VAR
6331 if (cpi->sf.adaptive_motion_search && mbmi->motion_mode == SIMPLE_TRANSLATION)
6332#else
6333 if (cpi->sf.adaptive_motion_search)
6334#endif // CONFIG_MOTION_VAR
6335 x->pred_mv[ref] = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006336
6337 if (scaled_ref_frame) {
6338 int i;
6339 for (i = 0; i < MAX_MB_PLANE; i++)
6340 xd->plane[i].pre[ref_idx] = backup_yv12[i];
6341 }
6342}
6343
6344static INLINE void restore_dst_buf(MACROBLOCKD *xd,
6345 uint8_t *orig_dst[MAX_MB_PLANE],
6346 int orig_dst_stride[MAX_MB_PLANE]) {
6347 int i;
6348 for (i = 0; i < MAX_MB_PLANE; i++) {
6349 xd->plane[i].dst.buf = orig_dst[i];
6350 xd->plane[i].dst.stride = orig_dst_stride[i];
6351 }
6352}
6353
Yaowu Xuc27fc142016-08-22 16:08:15 -07006354#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07006355static void do_masked_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006356 const uint8_t *mask, int mask_stride,
6357 BLOCK_SIZE bsize, int mi_row, int mi_col,
6358 int_mv *tmp_mv, int *rate_mv, int ref_idx,
6359 int mv_idx) {
6360 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07006361 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006362 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6363 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
6364 int bestsme = INT_MAX;
6365 int step_param;
6366 int sadpb = x->sadperbit16;
6367 MV mvp_full;
6368 int ref = mbmi->ref_frame[ref_idx];
6369 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
6370
6371 int tmp_col_min = x->mv_col_min;
6372 int tmp_col_max = x->mv_col_max;
6373 int tmp_row_min = x->mv_row_min;
6374 int tmp_row_max = x->mv_row_max;
6375
6376 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07006377 av1_get_scaled_ref_frame(cpi, ref);
Urvang Joshi368fbc92016-10-17 16:31:34 -07006378 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006379
6380 MV pred_mv[3];
6381 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6382 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
6383 pred_mv[2] = x->pred_mv[ref];
6384
6385#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006386 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006387#endif
6388
6389 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006390 // Swap out the reference frame for a version that's been scaled to
6391 // match the resolution of the current frame, allowing the existing
6392 // motion search code to be used without additional modifications.
6393 for (i = 0; i < MAX_MB_PLANE; i++)
6394 backup_yv12[i] = xd->plane[i].pre[ref_idx];
6395
Yaowu Xuf883b422016-08-30 14:01:10 -07006396 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006397 }
6398
Yaowu Xuf883b422016-08-30 14:01:10 -07006399 av1_set_mv_search_range(x, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006400
6401 // Work out the size of the first step in the mv step search.
6402 // 0 here is maximum length first step. 1 is MAX >> 1 etc.
6403 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6404 // Take wtd average of the step_params based on the last frame's
6405 // max mv magnitude and that based on the best ref mvs of the current
6406 // block for the given reference.
6407 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006408 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07006409 2;
6410 } else {
6411 step_param = cpi->mv_step_param;
6412 }
6413
6414 // TODO(debargha): is show_frame needed here?
6415 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size && cm->show_frame) {
6416 int boffset =
6417 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07006418 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
6419 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006420 }
6421
6422 if (cpi->sf.adaptive_motion_search) {
6423 int bwl = b_width_log2_lookup[bsize];
6424 int bhl = b_height_log2_lookup[bsize];
6425 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
6426
6427 if (tlevel < 5) step_param += 2;
6428
6429 // prev_mv_sad is not setup for dynamically scaled frames.
6430 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006431 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
6432 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
6433 x->pred_mv[ref].row = 0;
6434 x->pred_mv[ref].col = 0;
6435 tmp_mv->as_int = INVALID_MV;
6436
6437 if (scaled_ref_frame) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07006438 int j;
6439 for (j = 0; j < MAX_MB_PLANE; ++j)
6440 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006441 }
6442 return;
6443 }
6444 }
6445 }
6446 }
6447
6448 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
6449
6450 mvp_full.col >>= 3;
6451 mvp_full.row >>= 3;
6452
Yaowu Xuf883b422016-08-30 14:01:10 -07006453 bestsme = av1_masked_full_pixel_diamond(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006454 cpi, x, mask, mask_stride, &mvp_full, step_param, sadpb,
6455 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
6456 &tmp_mv->as_mv, ref_idx);
6457
6458 x->mv_col_min = tmp_col_min;
6459 x->mv_col_max = tmp_col_max;
6460 x->mv_row_min = tmp_row_min;
6461 x->mv_row_max = tmp_row_max;
6462
6463 if (bestsme < INT_MAX) {
6464 int dis; /* TODO: use dis in distortion calculation later. */
Yaowu Xuf883b422016-08-30 14:01:10 -07006465 av1_find_best_masked_sub_pixel_tree_up(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006466 cpi, x, mask, mask_stride, mi_row, mi_col, &tmp_mv->as_mv, &ref_mv,
6467 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
6468 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
6469 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], ref_idx,
6470 cpi->sf.use_upsampled_references);
6471 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006472 *rate_mv = av1_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmvjointcost,
6473 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006474
6475 if (cpi->sf.adaptive_motion_search && cm->show_frame)
6476 x->pred_mv[ref] = tmp_mv->as_mv;
6477
6478 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006479 for (i = 0; i < MAX_MB_PLANE; i++)
6480 xd->plane[i].pre[ref_idx] = backup_yv12[i];
6481 }
6482}
6483
Sarah Parker6fdc8532016-11-16 17:47:13 -08006484static void do_masked_motion_search_indexed(
6485 const AV1_COMP *const cpi, MACROBLOCK *x,
6486 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE bsize,
6487 int mi_row, int mi_col, int_mv *tmp_mv, int *rate_mv, int mv_idx[2],
6488 int which) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006489 // NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both
6490 MACROBLOCKD *xd = &x->e_mbd;
6491 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6492 BLOCK_SIZE sb_type = mbmi->sb_type;
6493 const uint8_t *mask;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006494 const int mask_stride = block_size_wide[bsize];
Sarah Parker6fdc8532016-11-16 17:47:13 -08006495 mask = av1_get_compound_type_mask(comp_data, sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006496
6497 if (which == 0 || which == 2)
6498 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
6499 &tmp_mv[0], &rate_mv[0], 0, mv_idx[0]);
6500
6501 if (which == 1 || which == 2) {
6502 // get the negative mask
Sarah Parker6fdc8532016-11-16 17:47:13 -08006503 mask = av1_get_compound_type_mask(comp_data, sb_type, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006504 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
6505 &tmp_mv[1], &rate_mv[1], 1, mv_idx[1]);
6506 }
6507}
6508#endif // CONFIG_EXT_INTER
6509
6510// In some situations we want to discount tha pparent cost of a new motion
6511// vector. Where there is a subtle motion field and especially where there is
6512// low spatial complexity then it can be hard to cover the cost of a new motion
6513// vector in a single block, even if that motion vector reduces distortion.
6514// However, once established that vector may be usable through the nearest and
6515// near mv modes to reduce distortion in subsequent blocks and also improve
6516// visual quality.
Urvang Joshi52648442016-10-13 17:27:51 -07006517static int discount_newmv_test(const AV1_COMP *const cpi, int this_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006518 int_mv this_mv,
6519 int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME],
6520 int ref_frame) {
6521 return (!cpi->rc.is_src_frame_alt_ref && (this_mode == NEWMV) &&
6522 (this_mv.as_int != 0) &&
6523 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
6524 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
6525 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
6526 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
6527}
6528
Yaowu Xu671f2bd2016-09-30 15:07:57 -07006529#define LEFT_TOP_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
6530#define RIGHT_BOTTOM_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006531
6532// TODO(jingning): this mv clamping function should be block size dependent.
6533static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
6534 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
6535 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
6536 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
6537 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
6538}
6539
6540#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006541static int estimate_wedge_sign(const AV1_COMP *cpi, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006542 const BLOCK_SIZE bsize, const uint8_t *pred0,
6543 int stride0, const uint8_t *pred1, int stride1) {
6544 const struct macroblock_plane *const p = &x->plane[0];
6545 const uint8_t *src = p->src.buf;
6546 int src_stride = p->src.stride;
6547 const int f_index = bsize - BLOCK_8X8;
6548 const int bw = 4 << (b_width_log2_lookup[bsize]);
6549 const int bh = 4 << (b_height_log2_lookup[bsize]);
6550 uint32_t esq[2][4], var;
6551 int64_t tl, br;
6552
Yaowu Xuf883b422016-08-30 14:01:10 -07006553#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006554 if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6555 pred0 = CONVERT_TO_BYTEPTR(pred0);
6556 pred1 = CONVERT_TO_BYTEPTR(pred1);
6557 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006558#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006559
6560 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred0, stride0, &esq[0][0]);
6561 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred0 + bw / 2,
6562 stride0, &esq[0][1]);
6563 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
6564 pred0 + bh / 2 * stride0, stride0, &esq[0][2]);
6565 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
6566 pred0 + bh / 2 * stride0 + bw / 2, stride0,
6567 &esq[0][3]);
6568 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred1, stride1, &esq[1][0]);
6569 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred1 + bw / 2,
6570 stride1, &esq[1][1]);
6571 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
6572 pred1 + bh / 2 * stride1, stride0, &esq[1][2]);
6573 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
6574 pred1 + bh / 2 * stride1 + bw / 2, stride0,
6575 &esq[1][3]);
6576 (void)var;
6577
6578 tl = (int64_t)(esq[0][0] + esq[0][1] + esq[0][2]) -
6579 (int64_t)(esq[1][0] + esq[1][1] + esq[1][2]);
6580 br = (int64_t)(esq[1][3] + esq[1][1] + esq[1][2]) -
6581 (int64_t)(esq[0][3] + esq[0][1] + esq[0][2]);
6582 return (tl + br > 0);
6583}
6584#endif // CONFIG_EXT_INTER
6585
6586#if !CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07006587static InterpFilter predict_interp_filter(
Yaowu Xuf883b422016-08-30 14:01:10 -07006588 const AV1_COMP *cpi, const MACROBLOCK *x, const BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006589 const int mi_row, const int mi_col,
James Zern7b9407a2016-05-18 23:48:05 -07006590 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME]) {
6591 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuf883b422016-08-30 14:01:10 -07006592 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006593 const MACROBLOCKD *xd = &x->e_mbd;
6594 int bsl = mi_width_log2_lookup[bsize];
6595 int pred_filter_search =
6596 cpi->sf.cb_pred_filter_search
6597 ? (((mi_row + mi_col) >> bsl) +
6598 get_chessboard_index(cm->current_video_frame)) &
6599 0x1
6600 : 0;
6601 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6602 const int is_comp_pred = has_second_ref(mbmi);
6603 const int this_mode = mbmi->mode;
6604 int refs[2] = { mbmi->ref_frame[0],
6605 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Yaowu Xuc27fc142016-08-22 16:08:15 -07006606 if (pred_filter_search) {
James Zern7b9407a2016-05-18 23:48:05 -07006607 InterpFilter af = SWITCHABLE, lf = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006608 if (xd->up_available) af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
6609 if (xd->left_available) lf = xd->mi[-1]->mbmi.interp_filter;
6610
6611#if CONFIG_EXT_INTER
6612 if ((this_mode != NEWMV && this_mode != NEWFROMNEARMV &&
6613 this_mode != NEW_NEWMV) ||
6614 (af == lf))
6615#else
6616 if ((this_mode != NEWMV) || (af == lf))
6617#endif // CONFIG_EXT_INTER
6618 best_filter = af;
6619 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006620 if (is_comp_pred) {
6621 if (cpi->sf.adaptive_mode_search) {
6622#if CONFIG_EXT_INTER
6623 switch (this_mode) {
6624 case NEAREST_NEARESTMV:
6625 if (single_filter[NEARESTMV][refs[0]] ==
6626 single_filter[NEARESTMV][refs[1]])
6627 best_filter = single_filter[NEARESTMV][refs[0]];
6628 break;
6629 case NEAREST_NEARMV:
6630 if (single_filter[NEARESTMV][refs[0]] ==
6631 single_filter[NEARMV][refs[1]])
6632 best_filter = single_filter[NEARESTMV][refs[0]];
6633 break;
6634 case NEAR_NEARESTMV:
6635 if (single_filter[NEARMV][refs[0]] ==
6636 single_filter[NEARESTMV][refs[1]])
6637 best_filter = single_filter[NEARMV][refs[0]];
6638 break;
6639 case NEAR_NEARMV:
6640 if (single_filter[NEARMV][refs[0]] == single_filter[NEARMV][refs[1]])
6641 best_filter = single_filter[NEARMV][refs[0]];
6642 break;
6643 case ZERO_ZEROMV:
6644 if (single_filter[ZEROMV][refs[0]] == single_filter[ZEROMV][refs[1]])
6645 best_filter = single_filter[ZEROMV][refs[0]];
6646 break;
6647 case NEW_NEWMV:
6648 if (single_filter[NEWMV][refs[0]] == single_filter[NEWMV][refs[1]])
6649 best_filter = single_filter[NEWMV][refs[0]];
6650 break;
6651 case NEAREST_NEWMV:
6652 if (single_filter[NEARESTMV][refs[0]] ==
6653 single_filter[NEWMV][refs[1]])
6654 best_filter = single_filter[NEARESTMV][refs[0]];
6655 break;
6656 case NEAR_NEWMV:
6657 if (single_filter[NEARMV][refs[0]] == single_filter[NEWMV][refs[1]])
6658 best_filter = single_filter[NEARMV][refs[0]];
6659 break;
6660 case NEW_NEARESTMV:
6661 if (single_filter[NEWMV][refs[0]] ==
6662 single_filter[NEARESTMV][refs[1]])
6663 best_filter = single_filter[NEWMV][refs[0]];
6664 break;
6665 case NEW_NEARMV:
6666 if (single_filter[NEWMV][refs[0]] == single_filter[NEARMV][refs[1]])
6667 best_filter = single_filter[NEWMV][refs[0]];
6668 break;
6669 default:
6670 if (single_filter[this_mode][refs[0]] ==
6671 single_filter[this_mode][refs[1]])
6672 best_filter = single_filter[this_mode][refs[0]];
6673 break;
6674 }
6675#else
6676 if (single_filter[this_mode][refs[0]] ==
6677 single_filter[this_mode][refs[1]])
6678 best_filter = single_filter[this_mode][refs[0]];
6679#endif // CONFIG_EXT_INTER
6680 }
6681 }
Angie Chiang75c22092016-10-25 12:19:16 -07006682 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
6683 best_filter = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006684 }
6685 return best_filter;
6686}
6687#endif
6688
6689#if CONFIG_EXT_INTER
6690// Choose the best wedge index and sign
Yaowu Xuf883b422016-08-30 14:01:10 -07006691static int64_t pick_wedge(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006692 const BLOCK_SIZE bsize, const uint8_t *const p0,
6693 const uint8_t *const p1, int *const best_wedge_sign,
6694 int *const best_wedge_index) {
6695 const MACROBLOCKD *const xd = &x->e_mbd;
6696 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006697 const int bw = block_size_wide[bsize];
6698 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006699 const int N = bw * bh;
6700 int rate;
6701 int64_t dist;
6702 int64_t rd, best_rd = INT64_MAX;
6703 int wedge_index;
6704 int wedge_sign;
6705 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
6706 const uint8_t *mask;
6707 uint64_t sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006708#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006709 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
6710 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
6711#else
6712 const int bd_round = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07006713#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006714
6715 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
6716 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
6717 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
6718 DECLARE_ALIGNED(32, int16_t, ds[MAX_SB_SQUARE]);
6719
6720 int64_t sign_limit;
6721
Yaowu Xuf883b422016-08-30 14:01:10 -07006722#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006723 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006724 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006725 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006726 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006727 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006728 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006729 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
6730 } else // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07006731#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006732 {
Yaowu Xuf883b422016-08-30 14:01:10 -07006733 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
6734 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
6735 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006736 }
6737
Yaowu Xuf883b422016-08-30 14:01:10 -07006738 sign_limit = ((int64_t)aom_sum_squares_i16(r0, N) -
6739 (int64_t)aom_sum_squares_i16(r1, N)) *
Yaowu Xuc27fc142016-08-22 16:08:15 -07006740 (1 << WEDGE_WEIGHT_BITS) / 2;
6741
Yaowu Xuf883b422016-08-30 14:01:10 -07006742 av1_wedge_compute_delta_squares(ds, r0, r1, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006743
6744 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006745 mask = av1_get_contiguous_soft_mask(wedge_index, 0, bsize);
6746 wedge_sign = av1_wedge_sign_from_residuals(ds, mask, N, sign_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006747
Yaowu Xuf883b422016-08-30 14:01:10 -07006748 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
6749 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006750 sse = ROUND_POWER_OF_TWO(sse, bd_round);
6751
6752 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
6753 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
6754
6755 if (rd < best_rd) {
6756 *best_wedge_index = wedge_index;
6757 *best_wedge_sign = wedge_sign;
6758 best_rd = rd;
6759 }
6760 }
6761
6762 return best_rd;
6763}
6764
6765// Choose the best wedge index the specified sign
6766static int64_t pick_wedge_fixed_sign(
Yaowu Xuf883b422016-08-30 14:01:10 -07006767 const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006768 const BLOCK_SIZE bsize, const uint8_t *const p0, const uint8_t *const p1,
6769 const int wedge_sign, int *const best_wedge_index) {
6770 const MACROBLOCKD *const xd = &x->e_mbd;
6771 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006772 const int bw = block_size_wide[bsize];
6773 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006774 const int N = bw * bh;
6775 int rate;
6776 int64_t dist;
6777 int64_t rd, best_rd = INT64_MAX;
6778 int wedge_index;
6779 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
6780 const uint8_t *mask;
6781 uint64_t sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006782#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006783 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
6784 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
6785#else
6786 const int bd_round = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07006787#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006788
6789 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
6790 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
6791
Yaowu Xuf883b422016-08-30 14:01:10 -07006792#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006793 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006794 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006795 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006796 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006797 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
6798 } else // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07006799#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006800 {
Yaowu Xuf883b422016-08-30 14:01:10 -07006801 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
6802 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006803 }
6804
6805 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006806 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
6807 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006808 sse = ROUND_POWER_OF_TWO(sse, bd_round);
6809
6810 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
6811 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
6812
6813 if (rd < best_rd) {
6814 *best_wedge_index = wedge_index;
6815 best_rd = rd;
6816 }
6817 }
6818
6819 return best_rd;
6820}
6821
Yaowu Xuf883b422016-08-30 14:01:10 -07006822static int64_t pick_interinter_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006823 const MACROBLOCK *const x,
6824 const BLOCK_SIZE bsize,
6825 const uint8_t *const p0,
6826 const uint8_t *const p1) {
6827 const MACROBLOCKD *const xd = &x->e_mbd;
6828 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006829 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006830
6831 int64_t rd;
6832 int wedge_index = -1;
6833 int wedge_sign = 0;
6834
6835 assert(is_interinter_wedge_used(bsize));
6836
6837 if (cpi->sf.fast_wedge_sign_estimate) {
6838 wedge_sign = estimate_wedge_sign(cpi, x, bsize, p0, bw, p1, bw);
6839 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, wedge_sign, &wedge_index);
6840 } else {
6841 rd = pick_wedge(cpi, x, bsize, p0, p1, &wedge_sign, &wedge_index);
6842 }
6843
Sarah Parker6fdc8532016-11-16 17:47:13 -08006844 mbmi->interinter_compound_data.wedge_sign = wedge_sign;
6845 mbmi->interinter_compound_data.wedge_index = wedge_index;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006846 return rd;
6847}
6848
Yaowu Xuf883b422016-08-30 14:01:10 -07006849static int64_t pick_interintra_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006850 const MACROBLOCK *const x,
6851 const BLOCK_SIZE bsize,
6852 const uint8_t *const p0,
6853 const uint8_t *const p1) {
6854 const MACROBLOCKD *const xd = &x->e_mbd;
6855 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6856
6857 int64_t rd;
6858 int wedge_index = -1;
6859
6860 assert(is_interintra_wedge_used(bsize));
6861
6862 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, 0, &wedge_index);
6863
6864 mbmi->interintra_wedge_sign = 0;
6865 mbmi->interintra_wedge_index = wedge_index;
6866 return rd;
6867}
Sarah Parker6fdc8532016-11-16 17:47:13 -08006868
6869static int interinter_compound_motion_search(const AV1_COMP *const cpi,
6870 MACROBLOCK *x,
6871 const BLOCK_SIZE bsize,
6872 const int this_mode, int mi_row,
6873 int mi_col) {
6874 const MACROBLOCKD *const xd = &x->e_mbd;
6875 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6876 int_mv tmp_mv[2];
6877 int rate_mvs[2], tmp_rate_mv = 0;
6878 if (this_mode == NEW_NEWMV) {
6879 int mv_idxs[2] = { 0, 0 };
6880 do_masked_motion_search_indexed(cpi, x, &mbmi->interinter_compound_data,
6881 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
6882 mv_idxs, 2);
6883 tmp_rate_mv = rate_mvs[0] + rate_mvs[1];
6884 mbmi->mv[0].as_int = tmp_mv[0].as_int;
6885 mbmi->mv[1].as_int = tmp_mv[1].as_int;
6886 } else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
6887 int mv_idxs[2] = { 0, 0 };
6888 do_masked_motion_search_indexed(cpi, x, &mbmi->interinter_compound_data,
6889 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
6890 mv_idxs, 0);
6891 tmp_rate_mv = rate_mvs[0];
6892 mbmi->mv[0].as_int = tmp_mv[0].as_int;
6893 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
6894 int mv_idxs[2] = { 0, 0 };
6895 do_masked_motion_search_indexed(cpi, x, &mbmi->interinter_compound_data,
6896 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
6897 mv_idxs, 1);
6898 tmp_rate_mv = rate_mvs[1];
6899 mbmi->mv[1].as_int = tmp_mv[1].as_int;
6900 }
6901 return tmp_rate_mv;
6902}
6903
6904static int64_t build_and_cost_compound_wedge(
6905 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
6906 const BLOCK_SIZE bsize, const int this_mode, int rs2, int rate_mv,
6907 int *out_rate_mv, uint8_t **preds0, uint8_t **preds1, int *strides,
6908 int mi_row, int mi_col) {
6909 MACROBLOCKD *xd = &x->e_mbd;
6910 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6911 int rate_sum;
6912 int64_t dist_sum;
6913 int64_t best_rd_cur = INT64_MAX;
6914 int64_t rd = INT64_MAX;
6915 int tmp_skip_txfm_sb;
6916 int64_t tmp_skip_sse_sb;
6917
6918 best_rd_cur = pick_interinter_wedge(cpi, x, bsize, *preds0, *preds1);
6919 best_rd_cur += RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv, 0);
6920
6921 if (have_newmv_in_inter_mode(this_mode)) {
6922 *out_rate_mv = interinter_compound_motion_search(cpi, x, bsize, this_mode,
6923 mi_row, mi_col);
6924 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
6925 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
6926 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
6927 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
6928 if (rd < best_rd_cur) {
6929 best_rd_cur = rd;
6930 } else {
6931 mbmi->mv[0].as_int = cur_mv[0].as_int;
6932 mbmi->mv[1].as_int = cur_mv[1].as_int;
6933 *out_rate_mv = rate_mv;
6934 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0, preds0, strides,
6935 preds1, strides);
6936 }
6937 av1_subtract_plane(x, bsize, 0);
6938 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
6939 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
6940 if (rd != INT64_MAX)
6941 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
6942 best_rd_cur = rd;
6943
6944 } else {
6945 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0, preds0, strides,
6946 preds1, strides);
6947 av1_subtract_plane(x, bsize, 0);
6948 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
6949 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
6950 if (rd != INT64_MAX)
6951 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
6952 best_rd_cur = rd;
6953 }
6954 return best_rd_cur;
6955}
Yaowu Xuc27fc142016-08-22 16:08:15 -07006956#endif // CONFIG_EXT_INTER
6957
6958static int64_t handle_inter_mode(
Angie Chiang76159122016-11-09 12:13:22 -08006959 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
6960 RD_STATS *rd_stats, RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006961 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
6962 int mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07006963#if CONFIG_MOTION_VAR
Yue Chene9638cc2016-10-10 12:37:54 -07006964 uint8_t *above_pred_buf[3], int above_pred_stride[3],
6965 uint8_t *left_pred_buf[3], int left_pred_stride[3],
Yue Chencb60b182016-10-13 15:18:22 -07006966#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006967#if CONFIG_EXT_INTER
6968 int_mv single_newmvs[2][TOTAL_REFS_PER_FRAME],
6969 int single_newmvs_rate[2][TOTAL_REFS_PER_FRAME],
Sarah Parker6fdc8532016-11-16 17:47:13 -08006970 int *compmode_interintra_cost, int *compmode_interinter_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006971 int64_t (*const modelled_rd)[TOTAL_REFS_PER_FRAME],
6972#else
6973 int_mv single_newmv[TOTAL_REFS_PER_FRAME],
6974#endif // CONFIG_EXT_INTER
James Zern7b9407a2016-05-18 23:48:05 -07006975 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME],
Angie Chiang76159122016-11-09 12:13:22 -08006976 int (*single_skippable)[TOTAL_REFS_PER_FRAME], const int64_t ref_best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07006977 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006978 MACROBLOCKD *xd = &x->e_mbd;
6979 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6980 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6981 const int is_comp_pred = has_second_ref(mbmi);
6982 const int this_mode = mbmi->mode;
6983 int_mv *frame_mv = mode_mv[this_mode];
6984 int i;
6985 int refs[2] = { mbmi->ref_frame[0],
6986 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
6987 int_mv cur_mv[2];
6988 int rate_mv = 0;
6989#if CONFIG_EXT_INTER
Angie Chiang75c22092016-10-25 12:19:16 -07006990 int pred_exists = 1;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006991 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006992 int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
6993 int_mv single_newmv[TOTAL_REFS_PER_FRAME];
6994 const unsigned int *const interintra_mode_cost =
6995 cpi->interintra_mode_cost[size_group_lookup[bsize]];
6996 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
6997#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07006998 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006999#endif
7000#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07007001#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007002 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
7003#else
7004 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07007005#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007006 uint8_t *tmp_buf;
7007
Yue Chencb60b182016-10-13 15:18:22 -07007008#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yue Chen69f18e12016-09-08 14:48:15 -07007009 MOTION_MODE motion_mode, last_motion_mode_allowed;
Angie Chiang76159122016-11-09 12:13:22 -08007010 int rate2_nocoeff = 0, best_xskip, best_disable_skip = 0;
7011 RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007012#if CONFIG_VAR_TX
7013 uint8_t best_blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
7014#endif // CONFIG_VAR_TX
Angie Chiang75c22092016-10-25 12:19:16 -07007015 int64_t best_rd = INT64_MAX;
Yue Chend326f762016-11-29 12:11:32 -08007016 MB_MODE_INFO base_mbmi, best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007017#if CONFIG_EXT_INTER
7018 int rate2_bmc_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007019 MB_MODE_INFO best_bmc_mbmi;
Yue Chen69f18e12016-09-08 14:48:15 -07007020#if CONFIG_MOTION_VAR
7021 int rate_mv_bmc;
7022#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007023#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07007024#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yue Chen69f18e12016-09-08 14:48:15 -07007025#if CONFIG_WARPED_MOTION
7026 double pts[144], pts_inref[144];
7027#endif // CONFIG_WARPED_MOTION
Angie Chiang75c22092016-10-25 12:19:16 -07007028 int64_t rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007029 uint8_t *orig_dst[MAX_MB_PLANE];
7030 int orig_dst_stride[MAX_MB_PLANE];
Angie Chiang75c22092016-10-25 12:19:16 -07007031 uint8_t *tmp_dst[MAX_MB_PLANE];
7032 int tmp_dst_stride[MAX_MB_PLANE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007033 int rs = 0;
Angie Chiang75c22092016-10-25 12:19:16 -07007034 InterpFilter assign_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007035
7036 int skip_txfm_sb = 0;
7037 int64_t skip_sse_sb = INT64_MAX;
Yaowu Xub0d0d002016-11-22 09:26:43 -08007038 int16_t mode_ctx;
Angie Chiang76159122016-11-09 12:13:22 -08007039#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7040 av1_invalid_rd_stats(&best_rd_stats);
7041#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007042
7043#if CONFIG_EXT_INTER
7044 *compmode_interintra_cost = 0;
7045 mbmi->use_wedge_interintra = 0;
Sarah Parker6fdc8532016-11-16 17:47:13 -08007046 *compmode_interinter_cost = 0;
7047 mbmi->interinter_compound_data.type = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007048
7049 // is_comp_interintra_pred implies !is_comp_pred
7050 assert(!is_comp_interintra_pred || (!is_comp_pred));
7051 // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
7052 assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
7053#endif // CONFIG_EXT_INTER
7054
7055#if CONFIG_REF_MV
7056#if CONFIG_EXT_INTER
7057 if (is_comp_pred)
7058 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
7059 else
7060#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07007061 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
7062 mbmi->ref_frame, bsize, -1);
Yaowu Xub0d0d002016-11-22 09:26:43 -08007063#else // CONFIG_REF_MV
7064 mode_ctx = mbmi_ext->mode_context[refs[0]];
7065#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07007066
Yaowu Xuf883b422016-08-30 14:01:10 -07007067#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007068 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
7069 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf_);
7070 else
Yaowu Xuf883b422016-08-30 14:01:10 -07007071#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007072 tmp_buf = tmp_buf_;
David Barkerb8069f92016-11-18 14:49:56 +00007073 // Make sure that we didn't leave the plane destination buffers set
7074 // to tmp_buf at the end of the last iteration
7075 assert(xd->plane[0].dst.buf != tmp_buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007076
Yue Chen69f18e12016-09-08 14:48:15 -07007077#if CONFIG_WARPED_MOTION
7078 mbmi->num_proj_ref[0] = 0;
7079 mbmi->num_proj_ref[1] = 0;
7080#endif // CONFIG_WARPED_MOTION
7081
Yaowu Xuc27fc142016-08-22 16:08:15 -07007082 if (is_comp_pred) {
7083 if (frame_mv[refs[0]].as_int == INVALID_MV ||
7084 frame_mv[refs[1]].as_int == INVALID_MV)
7085 return INT64_MAX;
7086 }
7087
Yue Chene9638cc2016-10-10 12:37:54 -07007088 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007089 if (have_newmv_in_inter_mode(this_mode)) {
7090 if (is_comp_pred) {
7091#if CONFIG_EXT_INTER
7092 for (i = 0; i < 2; ++i) {
7093 single_newmv[refs[i]].as_int = single_newmvs[mv_idx][refs[i]].as_int;
7094 }
7095
7096 if (this_mode == NEW_NEWMV) {
7097 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7098 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7099
7100 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
7101 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, NULL,
7102 single_newmv, &rate_mv, 0);
7103 } else {
7104#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007105 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007106#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07007107 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007108 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007109 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007110#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007111 av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007112#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07007113 rate_mv += av1_mv_bit_cost(
Zoe Liu82c8c922016-11-01 14:52:34 -07007114 &frame_mv[refs[1]].as_mv, &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007115 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7116 }
7117 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
7118 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07007119 rate_mv = av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007120 &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007121 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007122 } else {
7123 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07007124 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007125 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007126 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007127 }
7128#else
7129 // Initialize mv using single prediction mode result.
7130 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7131 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7132
7133 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
7134 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col,
7135 single_newmv, &rate_mv, 0);
7136 } else {
7137#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007138 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007139#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07007140 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007141 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007142 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007143#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007144 av1_set_mvcost(x, mbmi->ref_frame[1], 1, 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[1]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007147 &mbmi_ext->ref_mvs[refs[1]][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 }
7150#endif // CONFIG_EXT_INTER
7151 } else {
7152#if CONFIG_EXT_INTER
7153 if (is_comp_interintra_pred) {
7154 x->best_mv = single_newmvs[mv_idx][refs[0]];
7155 rate_mv = single_newmvs_rate[mv_idx][refs[0]];
7156 } else {
7157 single_motion_search(cpi, x, bsize, mi_row, mi_col, 0, mv_idx,
7158 &rate_mv);
7159 single_newmvs[mv_idx][refs[0]] = x->best_mv;
7160 single_newmvs_rate[mv_idx][refs[0]] = rate_mv;
7161 }
7162#else
7163 single_motion_search(cpi, x, bsize, mi_row, mi_col, &rate_mv);
7164 single_newmv[refs[0]] = x->best_mv;
7165#endif // CONFIG_EXT_INTER
7166
7167 if (x->best_mv.as_int == INVALID_MV) return INT64_MAX;
7168
7169 frame_mv[refs[0]] = x->best_mv;
7170 xd->mi[0]->bmi[0].as_mv[0] = x->best_mv;
7171
7172 // Estimate the rate implications of a new mv but discount this
7173 // under certain circumstances where we want to help initiate a weak
7174 // motion field, where the distortion gain for a single block may not
7175 // be enough to overcome the cost of a new mv.
7176 if (discount_newmv_test(cpi, this_mode, x->best_mv, mode_mv, refs[0])) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007177 rate_mv = AOMMAX((rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007178 }
7179 }
Angie Chiang76159122016-11-09 12:13:22 -08007180 rd_stats->rate += rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007181 }
7182
7183 for (i = 0; i < is_comp_pred + 1; ++i) {
7184 cur_mv[i] = frame_mv[refs[i]];
7185// Clip "next_nearest" so that it does not extend to far out of image
7186#if CONFIG_EXT_INTER
7187 if (this_mode != NEWMV && this_mode != NEWFROMNEARMV)
7188#else
7189 if (this_mode != NEWMV)
7190#endif // CONFIG_EXT_INTER
7191 clamp_mv2(&cur_mv[i].as_mv, xd);
7192
7193 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
7194 mbmi->mv[i].as_int = cur_mv[i].as_int;
7195 }
7196
7197#if CONFIG_REF_MV
7198#if CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08007199 if (this_mode == NEAREST_NEARESTMV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007200#else
Angie Chiang78a3bc12016-11-06 12:55:46 -08007201 if (this_mode == NEARESTMV && is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007202#endif // CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08007203 {
7204#if !CONFIG_EXT_INTER
7205 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
7206#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007207 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
7208 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
7209 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
7210
7211 for (i = 0; i < 2; ++i) {
7212 clamp_mv2(&cur_mv[i].as_mv, xd);
7213 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
7214 mbmi->mv[i].as_int = cur_mv[i].as_int;
7215 }
7216 }
7217 }
7218
7219#if CONFIG_EXT_INTER
7220 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
7221 if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
7222 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
7223
7224 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
7225 clamp_mv2(&cur_mv[0].as_mv, xd);
7226 if (mv_check_bounds(x, &cur_mv[0].as_mv)) return INT64_MAX;
7227 mbmi->mv[0].as_int = cur_mv[0].as_int;
7228 }
7229
7230 if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
7231 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
7232
7233 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
7234 clamp_mv2(&cur_mv[1].as_mv, xd);
7235 if (mv_check_bounds(x, &cur_mv[1].as_mv)) return INT64_MAX;
7236 mbmi->mv[1].as_int = cur_mv[1].as_int;
7237 }
7238 }
7239
7240 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
7241 if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV ||
7242 this_mode == NEAR_NEARMV) {
7243 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][1].this_mv;
7244
7245 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
7246 clamp_mv2(&cur_mv[0].as_mv, xd);
7247 if (mv_check_bounds(x, &cur_mv[0].as_mv)) return INT64_MAX;
7248 mbmi->mv[0].as_int = cur_mv[0].as_int;
7249 }
7250
7251 if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV ||
7252 this_mode == NEAR_NEARMV) {
7253 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][1].comp_mv;
7254
7255 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
7256 clamp_mv2(&cur_mv[1].as_mv, xd);
7257 if (mv_check_bounds(x, &cur_mv[1].as_mv)) return INT64_MAX;
7258 mbmi->mv[1].as_int = cur_mv[1].as_int;
7259 }
7260 }
7261#else
7262 if (this_mode == NEARMV && is_comp_pred) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007263 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007264 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
7265 int ref_mv_idx = mbmi->ref_mv_idx + 1;
7266 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
7267 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
7268
7269 for (i = 0; i < 2; ++i) {
7270 clamp_mv2(&cur_mv[i].as_mv, xd);
7271 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
7272 mbmi->mv[i].as_int = cur_mv[i].as_int;
7273 }
7274 }
7275 }
7276#endif // CONFIG_EXT_INTER
7277#endif // CONFIG_REF_MV
7278
7279 // do first prediction into the destination buffer. Do the next
7280 // prediction into a temporary buffer. Then keep track of which one
7281 // of these currently holds the best predictor, and use the other
7282 // one for future predictions. In the end, copy from tmp_buf to
7283 // dst if necessary.
7284 for (i = 0; i < MAX_MB_PLANE; i++) {
Angie Chiang75c22092016-10-25 12:19:16 -07007285 tmp_dst[i] = tmp_buf + i * MAX_SB_SQUARE;
7286 tmp_dst_stride[i] = MAX_SB_SIZE;
7287 }
7288 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007289 orig_dst[i] = xd->plane[i].dst.buf;
7290 orig_dst_stride[i] = xd->plane[i].dst.stride;
7291 }
7292
7293 // We don't include the cost of the second reference here, because there
7294 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
7295 // words if you present them in that order, the second one is always known
7296 // if the first is known.
7297 //
7298 // Under some circumstances we discount the cost of new mv mode to encourage
7299 // initiation of a motion field.
7300 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]], mode_mv,
7301 refs[0])) {
7302#if CONFIG_REF_MV && CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08007303 rd_stats->rate +=
7304 AOMMIN(cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx),
7305 cost_mv_ref(cpi, NEARESTMV, is_comp_pred, mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007306#else
Angie Chiang76159122016-11-09 12:13:22 -08007307 rd_stats->rate += AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
7308 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007309#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
7310 } else {
7311#if CONFIG_REF_MV && CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08007312 rd_stats->rate += cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007313#else
Angie Chiang76159122016-11-09 12:13:22 -08007314 rd_stats->rate += cost_mv_ref(cpi, this_mode, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007315#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
7316 }
7317
Angie Chiang76159122016-11-09 12:13:22 -08007318 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, 0) > ref_best_rd &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07007319#if CONFIG_EXT_INTER
7320 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV
7321#else
7322 mbmi->mode != NEARESTMV
7323#endif // CONFIG_EXT_INTER
7324 )
7325 return INT64_MAX;
7326
Angie Chiang75c22092016-10-25 12:19:16 -07007327 if (cm->interp_filter == SWITCHABLE) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007328#if !CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007329 assign_filter =
7330 predict_interp_filter(cpi, x, bsize, mi_row, mi_col, single_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007331#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007332#if CONFIG_EXT_INTERP || CONFIG_DUAL_FILTER
7333 if (!av1_is_interp_needed(xd)) assign_filter = EIGHTTAP_REGULAR;
7334#endif
7335 } else {
7336 assign_filter = cm->interp_filter;
7337 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007338
Angie Chiang75c22092016-10-25 12:19:16 -07007339 { // Do interpolation filter search in the parentheses
7340 int tmp_rate;
7341 int64_t tmp_dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007342#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007343 mbmi->interp_filter[0] =
7344 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
7345 mbmi->interp_filter[1] =
7346 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
7347 mbmi->interp_filter[2] =
7348 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
7349 mbmi->interp_filter[3] =
7350 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007351#else
Angie Chiang75c22092016-10-25 12:19:16 -07007352 mbmi->interp_filter =
7353 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007354#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007355 rs = av1_get_switchable_rate(cpi, xd);
7356 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
7357 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7358 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7359 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007360
Angie Chiang75c22092016-10-25 12:19:16 -07007361 if (assign_filter == SWITCHABLE) {
7362 // do interp_filter search
7363 if (av1_is_interp_needed(xd)) {
Angie Chiang5678ad92016-11-21 09:38:40 -08007364#if CONFIG_DUAL_FILTER
7365 const int filter_set_size = DUAL_FILTER_SET_SIZE;
7366#else
7367 const int filter_set_size = SWITCHABLE_FILTERS;
7368#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007369 int best_in_temp = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007370#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007371 InterpFilter best_filter[4];
7372 av1_copy(best_filter, mbmi->interp_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007373#else
Angie Chiang75c22092016-10-25 12:19:16 -07007374 InterpFilter best_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007375#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007376 restore_dst_buf(xd, tmp_dst, tmp_dst_stride);
Angie Chiang75c22092016-10-25 12:19:16 -07007377 // EIGHTTAP_REGULAR mode is calculated beforehand
Angie Chiang5678ad92016-11-21 09:38:40 -08007378 for (i = 1; i < filter_set_size; ++i) {
Angie Chiang75c22092016-10-25 12:19:16 -07007379 int tmp_skip_sb = 0;
7380 int64_t tmp_skip_sse = INT64_MAX;
7381 int tmp_rs;
Angie Chiang3655dcd2016-10-28 09:05:27 -07007382 int64_t tmp_rd;
Angie Chiang75c22092016-10-25 12:19:16 -07007383#if CONFIG_DUAL_FILTER
7384 mbmi->interp_filter[0] = filter_sets[i][0];
7385 mbmi->interp_filter[1] = filter_sets[i][1];
7386 mbmi->interp_filter[2] = filter_sets[i][0];
7387 mbmi->interp_filter[3] = filter_sets[i][1];
7388#else
7389 mbmi->interp_filter = i;
7390#endif
7391 tmp_rs = av1_get_switchable_rate(cpi, xd);
7392 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
7393 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7394 &tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
7395 tmp_rd = RDCOST(x->rdmult, x->rddiv, tmp_rs + tmp_rate, tmp_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007396
Angie Chiang75c22092016-10-25 12:19:16 -07007397 if (tmp_rd < rd) {
7398 rd = tmp_rd;
7399 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007400#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007401 av1_copy(best_filter, mbmi->interp_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007402#else
Angie Chiang75c22092016-10-25 12:19:16 -07007403 best_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007404#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007405 skip_txfm_sb = tmp_skip_sb;
7406 skip_sse_sb = tmp_skip_sse;
7407 best_in_temp = !best_in_temp;
7408 if (best_in_temp) {
7409 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7410 } else {
7411 restore_dst_buf(xd, tmp_dst, tmp_dst_stride);
7412 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007413 }
7414 }
Angie Chiang75c22092016-10-25 12:19:16 -07007415 if (best_in_temp) {
7416 restore_dst_buf(xd, tmp_dst, tmp_dst_stride);
7417 } else {
7418 restore_dst_buf(xd, orig_dst, orig_dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007419 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007420#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007421 av1_copy(mbmi->interp_filter, best_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007422#else
Angie Chiang75c22092016-10-25 12:19:16 -07007423 mbmi->interp_filter = best_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007424#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007425 } else {
Angie Chiang75c22092016-10-25 12:19:16 -07007426#if !CONFIG_EXT_INTERP && !CONFIG_DUAL_FILTER
7427 int tmp_rs;
7428 InterpFilter best_filter = mbmi->interp_filter;
7429 rs = av1_get_switchable_rate(cpi, xd);
7430 for (i = 1; i < SWITCHABLE_FILTERS; ++i) {
7431 mbmi->interp_filter = i;
7432 tmp_rs = av1_get_switchable_rate(cpi, xd);
7433 if (tmp_rs < rs) {
7434 rs = tmp_rs;
7435 best_filter = i;
7436 }
7437 }
7438 mbmi->interp_filter = best_filter;
7439#else
7440 assert(0);
7441#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007442 }
7443 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007444 }
7445
Yaowu Xuc27fc142016-08-22 16:08:15 -07007446#if CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07007447#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007448 best_bmc_mbmi = *mbmi;
Angie Chiang76159122016-11-09 12:13:22 -08007449 rate2_bmc_nocoeff = rd_stats->rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007450 if (cm->interp_filter == SWITCHABLE) rate2_bmc_nocoeff += rs;
Yue Chen69f18e12016-09-08 14:48:15 -07007451#if CONFIG_MOTION_VAR
7452 rate_mv_bmc = rate_mv;
Yue Chencb60b182016-10-13 15:18:22 -07007453#endif // CONFIG_MOTION_VAR
Yue Chen69f18e12016-09-08 14:48:15 -07007454#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007455
Sarah Parker6fdc8532016-11-16 17:47:13 -08007456 if (is_comp_pred) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07007457 int rate_sum, rs2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007458 int64_t dist_sum;
Sarah Parker6fdc8532016-11-16 17:47:13 -08007459 int64_t best_rd_compound = INT64_MAX, best_rd_cur = INT64_MAX;
7460 INTERINTER_COMPOUND_DATA best_compound_data;
7461 int_mv best_mv[2];
7462 int best_tmp_rate_mv = rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007463 int tmp_skip_txfm_sb;
7464 int64_t tmp_skip_sse_sb;
Sarah Parker6fddd182016-11-10 20:57:20 -08007465 int compound_type_cost[COMPOUND_TYPES];
Sarah Parker6fdc8532016-11-16 17:47:13 -08007466 uint8_t pred0[2 * MAX_SB_SQUARE];
7467 uint8_t pred1[2 * MAX_SB_SQUARE];
7468 uint8_t *preds0[1] = { pred0 };
7469 uint8_t *preds1[1] = { pred1 };
7470 int strides[1] = { bw };
7471 COMPOUND_TYPE cur_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007472
Sarah Parker6fdc8532016-11-16 17:47:13 -08007473 best_mv[0].as_int = cur_mv[0].as_int;
7474 best_mv[1].as_int = cur_mv[1].as_int;
7475 memset(&best_compound_data, 0, sizeof(INTERINTER_COMPOUND_DATA));
Sarah Parker6fddd182016-11-10 20:57:20 -08007476 av1_cost_tokens(compound_type_cost, cm->fc->compound_type_prob[bsize],
7477 av1_compound_type_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007478
Sarah Parker6fdc8532016-11-16 17:47:13 -08007479 if (is_interinter_wedge_used(bsize)) {
7480 // get inter predictors to use for masked compound modes
Yaowu Xuf883b422016-08-30 14:01:10 -07007481 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007482 xd, bsize, 0, 0, mi_row, mi_col, 0, preds0, strides);
Yaowu Xuf883b422016-08-30 14:01:10 -07007483 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007484 xd, bsize, 0, 0, mi_row, mi_col, 1, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007485 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007486
Sarah Parker6fdc8532016-11-16 17:47:13 -08007487 for (cur_type = COMPOUND_AVERAGE; cur_type < COMPOUND_TYPES; cur_type++) {
7488 best_rd_cur = INT64_MAX;
7489 mbmi->interinter_compound_data.type = cur_type;
7490 rs2 = av1_cost_literal(get_interinter_compound_type_bits(
7491 bsize, mbmi->interinter_compound_data.type)) +
7492 compound_type_cost[mbmi->interinter_compound_data.type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007493
Sarah Parker6fdc8532016-11-16 17:47:13 -08007494 switch (cur_type) {
7495 case COMPOUND_AVERAGE:
7496 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
7497 av1_subtract_plane(x, bsize, 0);
7498 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7499 &tmp_skip_txfm_sb, &tmp_skip_sse_sb,
7500 INT64_MAX);
7501 if (rd != INT64_MAX)
7502 rd =
7503 RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
7504 best_rd_compound = rd;
7505 break;
7506 case COMPOUND_WEDGE:
7507 if (!is_interinter_wedge_used(bsize)) break;
7508 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
7509 best_rd_compound / 3 < ref_best_rd) {
7510 int tmp_rate_mv = 0;
7511 best_rd_cur = build_and_cost_compound_wedge(
7512 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &tmp_rate_mv,
7513 preds0, preds1, strides, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007514
Sarah Parker6fdc8532016-11-16 17:47:13 -08007515 if (best_rd_cur < best_rd_compound) {
7516 best_rd_compound = best_rd_cur;
7517 memcpy(&best_compound_data, &mbmi->interinter_compound_data,
7518 sizeof(best_compound_data));
7519 if (have_newmv_in_inter_mode(this_mode)) {
7520 best_tmp_rate_mv = tmp_rate_mv;
7521 best_mv[0].as_int = mbmi->mv[0].as_int;
7522 best_mv[1].as_int = mbmi->mv[1].as_int;
7523 // reset to original mvs for next iteration
7524 mbmi->mv[0].as_int = cur_mv[0].as_int;
7525 mbmi->mv[1].as_int = cur_mv[1].as_int;
7526 }
7527 }
7528 }
7529 break;
7530 default: assert(0); return 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007531 }
7532 }
Sarah Parker6fdc8532016-11-16 17:47:13 -08007533 memcpy(&mbmi->interinter_compound_data, &best_compound_data,
7534 sizeof(INTERINTER_COMPOUND_DATA));
7535 if (have_newmv_in_inter_mode(this_mode)) {
7536 mbmi->mv[0].as_int = best_mv[0].as_int;
7537 mbmi->mv[1].as_int = best_mv[1].as_int;
7538 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
7539 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
7540 if (mbmi->interinter_compound_data.type) {
7541 rd_stats->rate += best_tmp_rate_mv - rate_mv;
7542 rate_mv = best_tmp_rate_mv;
7543 }
7544 }
7545
7546 if (ref_best_rd < INT64_MAX && best_rd_compound / 3 > ref_best_rd) {
David Barkerb8069f92016-11-18 14:49:56 +00007547 restore_dst_buf(xd, orig_dst, orig_dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007548 return INT64_MAX;
David Barkerb8069f92016-11-18 14:49:56 +00007549 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007550
7551 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007552
Sarah Parker6fdc8532016-11-16 17:47:13 -08007553 *compmode_interinter_cost =
7554 compound_type_cost[mbmi->interinter_compound_data.type] +
7555 av1_cost_literal(get_interinter_compound_type_bits(
7556 bsize, mbmi->interinter_compound_data.type));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007557 }
7558
7559 if (is_comp_interintra_pred) {
7560 INTERINTRA_MODE best_interintra_mode = II_DC_PRED;
7561 int64_t best_interintra_rd = INT64_MAX;
7562 int rmode, rate_sum;
7563 int64_t dist_sum;
7564 int j;
7565 int64_t best_interintra_rd_nowedge = INT64_MAX;
7566 int64_t best_interintra_rd_wedge = INT64_MAX;
7567 int rwedge;
7568 int_mv tmp_mv;
7569 int tmp_rate_mv = 0;
7570 int tmp_skip_txfm_sb;
7571 int64_t tmp_skip_sse_sb;
7572 DECLARE_ALIGNED(16, uint8_t, intrapred_[2 * MAX_SB_SQUARE]);
7573 uint8_t *intrapred;
7574
Yaowu Xuf883b422016-08-30 14:01:10 -07007575#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007576 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
7577 intrapred = CONVERT_TO_BYTEPTR(intrapred_);
7578 else
Yaowu Xuf883b422016-08-30 14:01:10 -07007579#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007580 intrapred = intrapred_;
7581
7582 mbmi->ref_frame[1] = NONE;
7583 for (j = 0; j < MAX_MB_PLANE; j++) {
7584 xd->plane[j].dst.buf = tmp_buf + j * MAX_SB_SQUARE;
7585 xd->plane[j].dst.stride = bw;
7586 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007587 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007588 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7589 mbmi->ref_frame[1] = INTRA_FRAME;
7590 mbmi->use_wedge_interintra = 0;
7591
7592 for (j = 0; j < INTERINTRA_MODES; ++j) {
7593 mbmi->interintra_mode = (INTERINTRA_MODE)j;
7594 rmode = interintra_mode_cost[mbmi->interintra_mode];
Yaowu Xuf883b422016-08-30 14:01:10 -07007595 av1_build_intra_predictors_for_interintra(xd, bsize, 0, intrapred, bw);
7596 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007597 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7598 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7599 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate_mv + rate_sum, dist_sum);
7600 if (rd < best_interintra_rd) {
7601 best_interintra_rd = rd;
7602 best_interintra_mode = mbmi->interintra_mode;
7603 }
7604 }
7605 mbmi->interintra_mode = best_interintra_mode;
7606 rmode = interintra_mode_cost[mbmi->interintra_mode];
Yaowu Xuf883b422016-08-30 14:01:10 -07007607 av1_build_intra_predictors_for_interintra(xd, bsize, 0, intrapred, bw);
7608 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
7609 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007610 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7611 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7612 if (rd != INT64_MAX)
7613 rd = RDCOST(x->rdmult, x->rddiv, rate_mv + rmode + rate_sum, dist_sum);
7614 best_interintra_rd = rd;
7615
7616 if (ref_best_rd < INT64_MAX && best_interintra_rd > 2 * ref_best_rd) {
David Barkerb8069f92016-11-18 14:49:56 +00007617 // Don't need to call restore_dst_buf here
Yaowu Xuc27fc142016-08-22 16:08:15 -07007618 return INT64_MAX;
7619 }
7620 if (is_interintra_wedge_used(bsize)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007621 rwedge = av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007622 if (rd != INT64_MAX)
7623 rd = RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge + rate_sum,
7624 dist_sum);
7625 best_interintra_rd_nowedge = rd;
7626
7627 // Disbale wedge search if source variance is small
7628 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh) {
7629 mbmi->use_wedge_interintra = 1;
7630
Yaowu Xuf883b422016-08-30 14:01:10 -07007631 rwedge = av1_cost_literal(get_interintra_wedge_bits(bsize)) +
7632 av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007633
7634 best_interintra_rd_wedge =
7635 pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
7636
7637 best_interintra_rd_wedge +=
7638 RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge, 0);
7639 // Refine motion vector.
7640 if (have_newmv_in_inter_mode(this_mode)) {
7641 // get negative of mask
Yaowu Xuf883b422016-08-30 14:01:10 -07007642 const uint8_t *mask = av1_get_contiguous_soft_mask(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007643 mbmi->interintra_wedge_index, 1, bsize);
7644 do_masked_motion_search(cpi, x, mask, bw, bsize, mi_row, mi_col,
7645 &tmp_mv, &tmp_rate_mv, 0, mv_idx);
7646 mbmi->mv[0].as_int = tmp_mv.as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07007647 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007648 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7649 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7650 rd = RDCOST(x->rdmult, x->rddiv,
7651 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
7652 if (rd < best_interintra_rd_wedge) {
7653 best_interintra_rd_wedge = rd;
7654 } else {
7655 tmp_mv.as_int = cur_mv[0].as_int;
7656 tmp_rate_mv = rate_mv;
7657 }
7658 } else {
7659 tmp_mv.as_int = cur_mv[0].as_int;
7660 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07007661 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007662 }
7663 // Evaluate closer to true rd
Yaowu Xuf883b422016-08-30 14:01:10 -07007664 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007665 rd =
7666 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7667 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7668 if (rd != INT64_MAX)
7669 rd = RDCOST(x->rdmult, x->rddiv,
7670 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
7671 best_interintra_rd_wedge = rd;
7672 if (best_interintra_rd_wedge < best_interintra_rd_nowedge) {
7673 mbmi->use_wedge_interintra = 1;
7674 best_interintra_rd = best_interintra_rd_wedge;
7675 mbmi->mv[0].as_int = tmp_mv.as_int;
Angie Chiang76159122016-11-09 12:13:22 -08007676 rd_stats->rate += tmp_rate_mv - rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007677 rate_mv = tmp_rate_mv;
7678 } else {
7679 mbmi->use_wedge_interintra = 0;
7680 best_interintra_rd = best_interintra_rd_nowedge;
7681 mbmi->mv[0].as_int = cur_mv[0].as_int;
7682 }
7683 } else {
7684 mbmi->use_wedge_interintra = 0;
7685 best_interintra_rd = best_interintra_rd_nowedge;
7686 }
7687 }
7688
7689 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007690 *compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07007691 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007692 *compmode_interintra_cost += interintra_mode_cost[mbmi->interintra_mode];
7693 if (is_interintra_wedge_used(bsize)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007694 *compmode_interintra_cost += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007695 cm->fc->wedge_interintra_prob[bsize], mbmi->use_wedge_interintra);
7696 if (mbmi->use_wedge_interintra) {
7697 *compmode_interintra_cost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07007698 av1_cost_literal(get_interintra_wedge_bits(bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007699 }
7700 }
7701 } else if (is_interintra_allowed(mbmi)) {
7702 *compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07007703 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007704 }
7705
7706#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07007707 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007708#if CONFIG_DUAL_FILTER
7709 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = EIGHTTAP_REGULAR;
7710#else
7711 mbmi->interp_filter = EIGHTTAP_REGULAR;
7712#endif
7713 pred_exists = 0;
7714 }
7715#endif // CONFIG_EXT_INTERP
Angie Chiang75c22092016-10-25 12:19:16 -07007716 if (pred_exists == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007717 int tmp_rate;
7718 int64_t tmp_dist;
Yaowu Xuf883b422016-08-30 14:01:10 -07007719 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007720 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7721 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7722 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
7723 }
Angie Chiang75c22092016-10-25 12:19:16 -07007724#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07007725
7726#if CONFIG_DUAL_FILTER
7727 if (!is_comp_pred) single_filter[this_mode][refs[0]] = mbmi->interp_filter[0];
7728#else
7729 if (!is_comp_pred) single_filter[this_mode][refs[0]] = mbmi->interp_filter;
7730#endif
7731
7732#if CONFIG_EXT_INTER
7733 if (modelled_rd != NULL) {
7734 if (is_comp_pred) {
7735 const int mode0 = compound_ref0_mode(this_mode);
7736 const int mode1 = compound_ref1_mode(this_mode);
7737 int64_t mrd =
Yaowu Xuf883b422016-08-30 14:01:10 -07007738 AOMMIN(modelled_rd[mode0][refs[0]], modelled_rd[mode1][refs[1]]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007739 if (rd / 4 * 3 > mrd && ref_best_rd < INT64_MAX) {
7740 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7741 return INT64_MAX;
7742 }
7743 } else if (!is_comp_interintra_pred) {
7744 modelled_rd[this_mode][refs[0]] = rd;
7745 }
7746 }
7747#endif // CONFIG_EXT_INTER
7748
7749 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
7750 // if current pred_error modeled rd is substantially more than the best
7751 // so far, do not bother doing full rd
7752 if (rd / 2 > ref_best_rd) {
7753 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7754 return INT64_MAX;
7755 }
7756 }
7757
Angie Chiang76159122016-11-09 12:13:22 -08007758 if (cm->interp_filter == SWITCHABLE) rd_stats->rate += rs;
Yue Chen69f18e12016-09-08 14:48:15 -07007759#if CONFIG_WARPED_MOTION
7760 aom_clear_system_state();
7761 mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
7762#endif // CONFIG_WARPED_MOTION
7763#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08007764 rate2_nocoeff = rd_stats->rate;
Yue Chen69f18e12016-09-08 14:48:15 -07007765 last_motion_mode_allowed = motion_mode_allowed(mbmi);
Yue Chend326f762016-11-29 12:11:32 -08007766 base_mbmi = *mbmi;
Yue Chen69f18e12016-09-08 14:48:15 -07007767#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007768
Yue Chencb60b182016-10-13 15:18:22 -07007769#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007770 best_rd = INT64_MAX;
Yue Chend326f762016-11-29 12:11:32 -08007771 for (motion_mode = SIMPLE_TRANSLATION;
Yue Chen69f18e12016-09-08 14:48:15 -07007772 motion_mode <= last_motion_mode_allowed; motion_mode++) {
7773 int64_t tmp_rd = INT64_MAX;
Yue Chend326f762016-11-29 12:11:32 -08007774 int tmp_rate;
Yue Chen69f18e12016-09-08 14:48:15 -07007775 int64_t tmp_dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007776#if CONFIG_EXT_INTER
Yue Chend326f762016-11-29 12:11:32 -08007777 int tmp_rate2 =
7778 motion_mode != SIMPLE_TRANSLATION ? rate2_bmc_nocoeff : rate2_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007779#else
7780 int tmp_rate2 = rate2_nocoeff;
7781#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07007782
Yue Chend326f762016-11-29 12:11:32 -08007783 *mbmi = base_mbmi;
7784 mbmi->motion_mode = motion_mode;
Yue Chencb60b182016-10-13 15:18:22 -07007785#if CONFIG_MOTION_VAR
Yue Chencb60b182016-10-13 15:18:22 -07007786 if (mbmi->motion_mode == OBMC_CAUSAL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007787#if CONFIG_EXT_INTER
7788 *mbmi = best_bmc_mbmi;
Yue Chencb60b182016-10-13 15:18:22 -07007789 mbmi->motion_mode = OBMC_CAUSAL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007790#endif // CONFIG_EXT_INTER
7791 if (!is_comp_pred && have_newmv_in_inter_mode(this_mode)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007792 int tmp_rate_mv = 0;
7793
Yue Chene9638cc2016-10-10 12:37:54 -07007794 single_motion_search(cpi, x, bsize, mi_row, mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007795#if CONFIG_EXT_INTER
Yue Chene9638cc2016-10-10 12:37:54 -07007796 0, mv_idx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007797#endif // CONFIG_EXT_INTER
Yue Chene9638cc2016-10-10 12:37:54 -07007798 &tmp_rate_mv);
7799 mbmi->mv[0].as_int = x->best_mv.as_int;
7800 if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
7801 refs[0])) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007802 tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007803 }
7804#if CONFIG_EXT_INTER
7805 tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
7806#else
7807 tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
7808#endif // CONFIG_EXT_INTER
7809#if CONFIG_EXT_INTERP
7810#if CONFIG_DUAL_FILTER
7811 if (!has_subpel_mv_component(xd->mi[0], xd, 0))
Yue Chend326f762016-11-29 12:11:32 -08007812 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007813 if (!has_subpel_mv_component(xd->mi[0], xd, 1))
Yue Chend326f762016-11-29 12:11:32 -08007814 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007815#else
Yue Chend326f762016-11-29 12:11:32 -08007816 if (!av1_is_interp_needed(xd)) mbmi->interp_filter = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007817#endif // CONFIG_DUAL_FILTER
7818 // This is not quite correct with CONFIG_DUAL_FILTER when a filter
7819 // is needed in only one direction
Yaowu Xuf883b422016-08-30 14:01:10 -07007820 if (!av1_is_interp_needed(xd)) tmp_rate2 -= rs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007821#endif // CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07007822 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007823#if CONFIG_EXT_INTER
7824 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07007825 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007826#endif // CONFIG_EXT_INTER
7827 }
Yue Chene9638cc2016-10-10 12:37:54 -07007828 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, above_pred_buf,
7829 above_pred_stride, left_pred_buf,
7830 left_pred_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007831 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7832 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7833 }
Yue Chencb60b182016-10-13 15:18:22 -07007834#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007835
7836#if CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07007837 if (mbmi->motion_mode == WARPED_CAUSAL) {
Yue Chen69f18e12016-09-08 14:48:15 -07007838#if CONFIG_EXT_INTER
7839 *mbmi = best_bmc_mbmi;
7840 mbmi->motion_mode = WARPED_CAUSAL;
7841#endif // CONFIG_EXT_INTER
7842 mbmi->wm_params[0].wmtype = DEFAULT_WMTYPE;
7843#if CONFIG_DUAL_FILTER
7844 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
7845 ? EIGHTTAP_REGULAR
7846 : cm->interp_filter;
7847 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
7848 ? EIGHTTAP_REGULAR
7849 : cm->interp_filter;
7850#else
7851 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
7852 : cm->interp_filter;
7853#endif // CONFIG_DUAL_FILTER
7854
7855 if (find_projection(mbmi->num_proj_ref[0], pts, pts_inref,
7856 &mbmi->wm_params[0]) == 0) {
7857 int plane;
7858#if CONFIG_AOM_HIGHBITDEPTH
7859 int use_hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7860#endif // CONFIG_AOM_HIGHBITDEPTH
7861
7862 for (plane = 0; plane < 3; ++plane) {
7863 const struct macroblockd_plane *pd = &xd->plane[plane];
7864
7865 av1_warp_plane(&mbmi->wm_params[0],
7866#if CONFIG_AOM_HIGHBITDEPTH
7867 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
7868#endif // CONFIG_AOM_HIGHBITDEPTH
7869 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
7870 pd->pre[0].stride, pd->dst.buf,
7871 (mi_col * MI_SIZE) >> pd->subsampling_x,
7872 (mi_row * MI_SIZE) >> pd->subsampling_y,
7873 (xd->n8_w * 8) >> pd->subsampling_x,
7874 (xd->n8_h * 8) >> pd->subsampling_y, pd->dst.stride,
7875 pd->subsampling_x, pd->subsampling_y, 16, 16, 0);
7876 }
7877
7878 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7879 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7880 } else {
7881 continue;
7882 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007883 }
7884#endif // CONFIG_WARPED_MOTION
7885 x->skip = 0;
7886
Yue Chen8a78a2b2016-11-17 18:23:38 -08007887 rd_stats->dist = 0;
7888 rd_stats->sse = 0;
7889 rd_stats->skip = 1;
Angie Chiang76159122016-11-09 12:13:22 -08007890 rd_stats->rate = tmp_rate2;
Yue Chen69f18e12016-09-08 14:48:15 -07007891 if (last_motion_mode_allowed > SIMPLE_TRANSLATION) {
7892#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7893 if (last_motion_mode_allowed == WARPED_CAUSAL)
7894#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7895 rd_stats->rate += cpi->motion_mode_cost[bsize][mbmi->motion_mode];
7896#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7897 else
7898 rd_stats->rate += cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
7899#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7900 }
7901#if CONFIG_WARPED_MOTION
7902 if (mbmi->motion_mode == WARPED_CAUSAL) {
7903 rd_stats->rate -= rs;
7904 }
7905#endif // CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07007906#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007907 if (!skip_txfm_sb) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007908 int64_t rdcosty = INT64_MAX;
Angie Chiangb5dda482016-11-02 16:19:58 -07007909 int is_cost_valid_uv = 0;
Angie Chiang76159122016-11-09 12:13:22 -08007910
Yaowu Xu1e761992016-11-09 15:01:47 -08007911 // cost and distortion
Yaowu Xu1e761992016-11-09 15:01:47 -08007912 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007913#if CONFIG_VAR_TX
Yaowu Xu1e761992016-11-09 15:01:47 -08007914 if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id]) {
Angie Chiang76159122016-11-09 12:13:22 -08007915 select_tx_type_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
Yaowu Xu1e761992016-11-09 15:01:47 -08007916 } else {
7917 int idx, idy;
Angie Chiang76159122016-11-09 12:13:22 -08007918 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
Yaowu Xu1e761992016-11-09 15:01:47 -08007919 for (idy = 0; idy < xd->n8_h; ++idy)
7920 for (idx = 0; idx < xd->n8_w; ++idx)
7921 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang3aab6502016-11-10 17:48:16 -08007922 memset(x->blk_skip[0], rd_stats_y->skip,
Yaowu Xu1e761992016-11-09 15:01:47 -08007923 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7924 }
Angie Chiang0e9a2e92016-11-08 09:45:40 -08007925#else
Yaowu Xu1e761992016-11-09 15:01:47 -08007926 /* clang-format off */
Angie Chiang76159122016-11-09 12:13:22 -08007927 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
Yaowu Xu1e761992016-11-09 15:01:47 -08007928/* clang-format on */
Yaowu Xuc27fc142016-08-22 16:08:15 -07007929#endif // CONFIG_VAR_TX
7930
Angie Chiang76159122016-11-09 12:13:22 -08007931 if (rd_stats_y->rate == INT_MAX) {
7932 av1_invalid_rd_stats(rd_stats);
Yue Chencb60b182016-10-13 15:18:22 -07007933#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7934 if (mbmi->motion_mode != SIMPLE_TRANSLATION) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007935 continue;
7936 } else {
Yue Chencb60b182016-10-13 15:18:22 -07007937#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007938 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7939 return INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007940#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007941 }
Yue Chencb60b182016-10-13 15:18:22 -07007942#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007943 }
7944
Angie Chiang76159122016-11-09 12:13:22 -08007945 av1_merge_rd_stats(rd_stats, rd_stats_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007946
Angie Chiang76159122016-11-09 12:13:22 -08007947 rdcosty = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
7948 rdcosty = AOMMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc1c6f6a2016-11-08 11:24:01 -08007949/* clang-format off */
Yaowu Xuc27fc142016-08-22 16:08:15 -07007950#if CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07007951 is_cost_valid_uv =
Angie Chiang76159122016-11-09 12:13:22 -08007952 inter_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
Angie Chiang284d7772016-11-08 11:06:45 -08007953#else
7954 is_cost_valid_uv =
Angie Chiang76159122016-11-09 12:13:22 -08007955 super_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
Angie Chiang284d7772016-11-08 11:06:45 -08007956#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07007957 if (!is_cost_valid_uv) {
Yue Chencb60b182016-10-13 15:18:22 -07007958#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007959 continue;
7960#else
Debargha Mukherjee0e119122016-11-04 12:10:23 -07007961 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7962 return INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007963#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007964 }
Yaowu Xuc1c6f6a2016-11-08 11:24:01 -08007965 /* clang-format on */
Angie Chiang76159122016-11-09 12:13:22 -08007966 av1_merge_rd_stats(rd_stats, rd_stats_uv);
Angie Chiang3963d632016-11-10 18:41:40 -08007967#if CONFIG_RD_DEBUG
7968 // record transform block coefficient cost
7969 // TODO(angiebird): So far rd_debug tool only detects descrepancy of
7970 // coefficient cost. Therefore, it is fine to copy rd_stats into mbmi
7971 // here because we already collect the coefficient cost. Move this part to
7972 // other place when we need to compare non-coefficient cost.
7973 mbmi->rd_stats = *rd_stats;
7974#endif
Yue Chencb60b182016-10-13 15:18:22 -07007975#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08007976 if (rd_stats->skip) {
7977 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
7978 rd_stats_y->rate = 0;
7979 rd_stats_uv->rate = 0;
7980 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007981 mbmi->skip = 0;
7982 // here mbmi->skip temporarily plays a role as what this_skip2 does
7983 } else if (!xd->lossless[mbmi->segment_id] &&
7984 (RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08007985 rd_stats_y->rate + rd_stats_uv->rate +
Yaowu Xuf883b422016-08-30 14:01:10 -07007986 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Angie Chiang76159122016-11-09 12:13:22 -08007987 rd_stats->dist) >=
Yaowu Xuc27fc142016-08-22 16:08:15 -07007988 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08007989 av1_cost_bit(av1_get_skip_prob(cm, xd), 1),
7990 rd_stats->sse))) {
7991 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
7992 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
7993 rd_stats->dist = rd_stats->sse;
7994 rd_stats_y->rate = 0;
7995 rd_stats_uv->rate = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007996 mbmi->skip = 1;
7997 } else {
Angie Chiang76159122016-11-09 12:13:22 -08007998 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007999 mbmi->skip = 0;
8000 }
8001 *disable_skip = 0;
Yue Chencb60b182016-10-13 15:18:22 -07008002#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008003 } else {
8004 x->skip = 1;
8005 *disable_skip = 1;
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07008006 mbmi->tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008007
8008// The cost of skip bit needs to be added.
Yue Chencb60b182016-10-13 15:18:22 -07008009#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008010 mbmi->skip = 0;
Yue Chencb60b182016-10-13 15:18:22 -07008011#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08008012 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008013
Angie Chiang76159122016-11-09 12:13:22 -08008014 rd_stats->dist = skip_sse_sb;
8015 rd_stats->sse = skip_sse_sb;
8016 rd_stats_y->rate = 0;
8017 rd_stats_uv->rate = 0;
8018 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008019 }
Yue Chen8a78a2b2016-11-17 18:23:38 -08008020#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8021 if (!is_comp_pred && mbmi->motion_mode == SIMPLE_TRANSLATION)
8022 single_skippable[this_mode][refs[0]] = rd_stats->skip;
8023#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parkere5299862016-08-16 14:57:37 -07008024#if CONFIG_GLOBAL_MOTION
8025 if (this_mode == ZEROMV) {
Angie Chiang76159122016-11-09 12:13:22 -08008026 rd_stats->rate += GLOBAL_MOTION_RATE(mbmi->ref_frame[0]);
8027 if (is_comp_pred)
8028 rd_stats->rate += GLOBAL_MOTION_RATE(mbmi->ref_frame[1]);
Sarah Parkere5299862016-08-16 14:57:37 -07008029 }
8030#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008031
Yue Chencb60b182016-10-13 15:18:22 -07008032#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08008033 tmp_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
Yue Chencb60b182016-10-13 15:18:22 -07008034 if (mbmi->motion_mode == SIMPLE_TRANSLATION || (tmp_rd < best_rd)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008035 best_mbmi = *mbmi;
8036 best_rd = tmp_rd;
Angie Chiang76159122016-11-09 12:13:22 -08008037 best_rd_stats = *rd_stats;
8038 best_rd_stats_y = *rd_stats_y;
8039 best_rd_stats_uv = *rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008040#if CONFIG_VAR_TX
8041 for (i = 0; i < MAX_MB_PLANE; ++i)
8042 memcpy(best_blk_skip[i], x->blk_skip[i],
8043 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8044#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07008045 best_xskip = x->skip;
8046 best_disable_skip = *disable_skip;
Yaowu Xuf883b422016-08-30 14:01:10 -07008047#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008048 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008049 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008050 cpi, &xd->plane[0].dst, bsize, xd->bd);
8051 } else {
8052 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008053 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008054 }
8055#else
8056 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008057 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
8058#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008059 }
8060 }
8061
8062 if (best_rd == INT64_MAX) {
Angie Chiang76159122016-11-09 12:13:22 -08008063 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008064 restore_dst_buf(xd, orig_dst, orig_dst_stride);
8065 return INT64_MAX;
8066 }
8067 *mbmi = best_mbmi;
Angie Chiang76159122016-11-09 12:13:22 -08008068 *rd_stats = best_rd_stats;
8069 *rd_stats_y = best_rd_stats_y;
8070 *rd_stats_uv = best_rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008071#if CONFIG_VAR_TX
8072 for (i = 0; i < MAX_MB_PLANE; ++i)
8073 memcpy(x->blk_skip[i], best_blk_skip[i],
8074 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8075#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07008076 x->skip = best_xskip;
8077 *disable_skip = best_disable_skip;
Yue Chencb60b182016-10-13 15:18:22 -07008078#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008079
Yue Chen8a78a2b2016-11-17 18:23:38 -08008080#if !(CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION)
Angie Chiang76159122016-11-09 12:13:22 -08008081 if (!is_comp_pred) single_skippable[this_mode][refs[0]] = rd_stats->skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008082
Yaowu Xuf883b422016-08-30 14:01:10 -07008083#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008084 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008085 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008086 cpi, &xd->plane[0].dst, bsize, xd->bd);
8087 } else {
8088 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008089 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008090 }
8091#else
8092 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008093 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
8094#endif // CONFIG_AOM_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07008095#endif // !(CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008096
8097 restore_dst_buf(xd, orig_dst, orig_dst_stride);
8098 return 0; // The rate-distortion cost will be re-calculated by caller.
8099}
8100
Urvang Joshi52648442016-10-13 17:27:51 -07008101void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
8102 RD_COST *rd_cost, BLOCK_SIZE bsize,
8103 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
8104 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008105 MACROBLOCKD *const xd = &x->e_mbd;
8106 struct macroblockd_plane *const pd = xd->plane;
8107 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
8108 int y_skip = 0, uv_skip = 0;
8109 int64_t dist_y = 0, dist_uv = 0;
8110 TX_SIZE max_uv_tx_size;
8111 ctx->skip = 0;
8112 xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
8113 xd->mi[0]->mbmi.ref_frame[1] = NONE;
8114
8115 if (bsize >= BLOCK_8X8) {
8116 if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y,
8117 &y_skip, bsize, best_rd) >= best_rd) {
8118 rd_cost->rate = INT_MAX;
8119 return;
8120 }
8121 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008122 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07008123 &dist_y, &y_skip, best_rd) >= best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008124 rd_cost->rate = INT_MAX;
8125 return;
8126 }
8127 }
Debargha Mukherjee2f123402016-08-30 17:43:38 -07008128 max_uv_tx_size = uv_txsize_lookup[bsize][xd->mi[0]->mbmi.tx_size]
8129 [pd[1].subsampling_x][pd[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008130 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
Yaowu Xuf883b422016-08-30 14:01:10 -07008131 &uv_skip, AOMMAX(BLOCK_8X8, bsize), max_uv_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008132
8133 if (y_skip && uv_skip) {
8134 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
Yaowu Xuf883b422016-08-30 14:01:10 -07008135 av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008136 rd_cost->dist = dist_y + dist_uv;
8137 } else {
8138 rd_cost->rate =
Yaowu Xuf883b422016-08-30 14:01:10 -07008139 rate_y + rate_uv + av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008140 rd_cost->dist = dist_y + dist_uv;
8141 }
8142
8143 ctx->mic = *xd->mi[0];
8144 ctx->mbmi_ext = *x->mbmi_ext;
8145 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
8146}
8147
Yaowu Xuc27fc142016-08-22 16:08:15 -07008148// Do we have an internal image edge (e.g. formatting bars).
Urvang Joshi52648442016-10-13 17:27:51 -07008149int av1_internal_image_edge(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008150 return (cpi->oxcf.pass == 2) &&
8151 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
8152 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
8153}
8154
8155// Checks to see if a super block is on a horizontal image edge.
8156// In most cases this is the "real" edge unless there are formatting
8157// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07008158int av1_active_h_edge(const AV1_COMP *cpi, int mi_row, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008159 int top_edge = 0;
8160 int bottom_edge = cpi->common.mi_rows;
8161 int is_active_h_edge = 0;
8162
8163 // For two pass account for any formatting bars detected.
8164 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07008165 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008166
8167 // The inactive region is specified in MBs not mi units.
8168 // The image edge is in the following MB row.
8169 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
8170
8171 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07008172 bottom_edge = AOMMAX(top_edge, bottom_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008173 }
8174
8175 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
8176 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
8177 is_active_h_edge = 1;
8178 }
8179 return is_active_h_edge;
8180}
8181
8182// Checks to see if a super block is on a vertical image edge.
8183// In most cases this is the "real" edge unless there are formatting
8184// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07008185int av1_active_v_edge(const AV1_COMP *cpi, int mi_col, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008186 int left_edge = 0;
8187 int right_edge = cpi->common.mi_cols;
8188 int is_active_v_edge = 0;
8189
8190 // For two pass account for any formatting bars detected.
8191 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07008192 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008193
8194 // The inactive region is specified in MBs not mi units.
8195 // The image edge is in the following MB row.
8196 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
8197
8198 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07008199 right_edge = AOMMAX(left_edge, right_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008200 }
8201
8202 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
8203 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
8204 is_active_v_edge = 1;
8205 }
8206 return is_active_v_edge;
8207}
8208
8209// Checks to see if a super block is at the edge of the active image.
8210// In most cases this is the "real" edge unless there are formatting
8211// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07008212int av1_active_edge_sb(const AV1_COMP *cpi, int mi_row, int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008213 return av1_active_h_edge(cpi, mi_row, cpi->common.mib_size) ||
8214 av1_active_v_edge(cpi, mi_col, cpi->common.mib_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008215}
8216
Urvang Joshib100db72016-10-12 16:28:56 -07008217#if CONFIG_PALETTE
Urvang Joshi52648442016-10-13 17:27:51 -07008218static void restore_uv_color_map(const AV1_COMP *const cpi, MACROBLOCK *x) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008219 MACROBLOCKD *const xd = &x->e_mbd;
8220 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
8221 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
8222 const BLOCK_SIZE bsize = mbmi->sb_type;
Jingning Hanae5cfde2016-11-30 12:01:44 -08008223 const int rows = block_size_high[bsize] >> (xd->plane[1].subsampling_y);
8224 const int cols = block_size_wide[bsize] >> (xd->plane[1].subsampling_x);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008225 int src_stride = x->plane[1].src.stride;
8226 const uint8_t *const src_u = x->plane[1].src.buf;
8227 const uint8_t *const src_v = x->plane[2].src.buf;
8228 float *const data = x->palette_buffer->kmeans_data_buf;
8229 float centroids[2 * PALETTE_MAX_SIZE];
8230 uint8_t *const color_map = xd->plane[1].color_index_map;
8231 int r, c;
Yaowu Xuf883b422016-08-30 14:01:10 -07008232#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008233 const uint16_t *const src_u16 = CONVERT_TO_SHORTPTR(src_u);
8234 const uint16_t *const src_v16 = CONVERT_TO_SHORTPTR(src_v);
Yaowu Xuf883b422016-08-30 14:01:10 -07008235#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008236 (void)cpi;
8237
8238 for (r = 0; r < rows; ++r) {
8239 for (c = 0; c < cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008240#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008241 if (cpi->common.use_highbitdepth) {
8242 data[(r * cols + c) * 2] = src_u16[r * src_stride + c];
8243 data[(r * cols + c) * 2 + 1] = src_v16[r * src_stride + c];
8244 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07008245#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008246 data[(r * cols + c) * 2] = src_u[r * src_stride + c];
8247 data[(r * cols + c) * 2 + 1] = src_v[r * src_stride + c];
Yaowu Xuf883b422016-08-30 14:01:10 -07008248#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008249 }
Yaowu Xuf883b422016-08-30 14:01:10 -07008250#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008251 }
8252 }
8253
8254 for (r = 1; r < 3; ++r) {
8255 for (c = 0; c < pmi->palette_size[1]; ++c) {
8256 centroids[c * 2 + r - 1] = pmi->palette_colors[r * PALETTE_MAX_SIZE + c];
8257 }
8258 }
8259
Yaowu Xuf883b422016-08-30 14:01:10 -07008260 av1_calc_indices(data, centroids, color_map, rows * cols,
8261 pmi->palette_size[1], 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008262}
Urvang Joshib100db72016-10-12 16:28:56 -07008263#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008264
hui su5db97432016-10-14 16:10:14 -07008265#if CONFIG_FILTER_INTRA
8266static void pick_filter_intra_interframe(
8267 const AV1_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
Urvang Joshi52648442016-10-13 17:27:51 -07008268 BLOCK_SIZE bsize, int *rate_uv_intra, int *rate_uv_tokenonly,
8269 int64_t *dist_uv, int *skip_uv, PREDICTION_MODE *mode_uv,
hui su5db97432016-10-14 16:10:14 -07008270 FILTER_INTRA_MODE_INFO *filter_intra_mode_info_uv,
8271#if CONFIG_EXT_INTRA
8272 int8_t *uv_angle_delta,
8273#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07008274#if CONFIG_PALETTE
8275 PALETTE_MODE_INFO *pmi_uv, int palette_ctx,
8276#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008277 int skip_mask, unsigned int *ref_costs_single, int64_t *best_rd,
8278 int64_t *best_intra_rd, PREDICTION_MODE *best_intra_mode,
8279 int *best_mode_index, int *best_skip2, int *best_mode_skippable,
8280#if CONFIG_SUPERTX
8281 int *returnrate_nocoef,
8282#endif // CONFIG_SUPERTX
8283 int64_t *best_pred_rd, MB_MODE_INFO *best_mbmode, RD_COST *rd_cost) {
Urvang Joshi52648442016-10-13 17:27:51 -07008284 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008285 MACROBLOCKD *const xd = &x->e_mbd;
8286 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008287#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008288 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07008289#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008290 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
8291 int rate2 = 0, rate_y = INT_MAX, skippable = 0, rate_uv, rate_dummy, i;
8292 int dc_mode_index;
8293 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
8294 int64_t distortion2 = 0, distortion_y = 0, this_rd = *best_rd, distortion_uv;
8295 TX_SIZE uv_tx;
8296
8297 for (i = 0; i < MAX_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07008298 if (av1_mode_order[i].mode == DC_PRED &&
8299 av1_mode_order[i].ref_frame[0] == INTRA_FRAME)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008300 break;
8301 dc_mode_index = i;
8302 assert(i < MAX_MODES);
8303
8304 // TODO(huisu): use skip_mask for further speedup.
8305 (void)skip_mask;
8306 mbmi->mode = DC_PRED;
8307 mbmi->uv_mode = DC_PRED;
8308 mbmi->ref_frame[0] = INTRA_FRAME;
8309 mbmi->ref_frame[1] = NONE;
hui su5db97432016-10-14 16:10:14 -07008310 if (!rd_pick_filter_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
8311 &skippable, bsize, intra_mode_cost[mbmi->mode],
8312 &this_rd, 0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008313 return;
hui su5db97432016-10-14 16:10:14 -07008314 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008315 if (rate_y == INT_MAX) return;
8316
Debargha Mukherjee2f123402016-08-30 17:43:38 -07008317 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
8318 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008319 if (rate_uv_intra[uv_tx] == INT_MAX) {
8320 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
8321 &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx],
8322 &skip_uv[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07008323#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008324 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008325#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07008326 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
8327#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008328 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui su5db97432016-10-14 16:10:14 -07008329#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008330 }
8331
8332 rate_uv = rate_uv_tokenonly[uv_tx];
8333 distortion_uv = dist_uv[uv_tx];
8334 skippable = skippable && skip_uv[uv_tx];
8335 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07008336#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008337 if (cm->allow_screen_content_tools) {
8338 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
8339 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
8340 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
8341 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
8342 }
Urvang Joshib100db72016-10-12 16:28:56 -07008343#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07008344#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008345 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui su5db97432016-10-14 16:10:14 -07008346#endif // CONFIG_EXT_INTRA
8347 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
8348 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
8349 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
8350 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
8351 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008352 }
8353
8354 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
8355 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07008356#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008357 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07008358 rate2 += av1_cost_bit(
8359 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07008360#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008361
8362 if (!xd->lossless[mbmi->segment_id]) {
8363 // super_block_yrd above includes the cost of the tx_size in the
8364 // tokenonly rate, but for intra blocks, tx_size is always coded
8365 // (prediction granularity), so we account for it in the full rate,
8366 // not the tokenonly rate.
clang-format67948d32016-09-07 22:40:40 -07008367 rate_y -= cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
Jingning Hanb0a71302016-10-25 16:28:49 -07008368 [tx_size_to_depth(mbmi->tx_size)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008369 }
8370
hui su5db97432016-10-14 16:10:14 -07008371 rate2 += av1_cost_bit(cm->fc->filter_intra_probs[0],
8372 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
8373 rate2 += write_uniform_cost(
8374 FILTER_INTRA_MODES, mbmi->filter_intra_mode_info.filter_intra_mode[0]);
8375#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008376 if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
8377 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
8378 MAX_ANGLE_DELTAS + mbmi->angle_delta[1]);
8379 }
hui su5db97432016-10-14 16:10:14 -07008380#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008381 if (mbmi->mode == DC_PRED) {
hui su5db97432016-10-14 16:10:14 -07008382 rate2 +=
8383 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
8384 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
8385 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
8386 rate2 +=
8387 write_uniform_cost(FILTER_INTRA_MODES,
8388 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008389 }
8390 distortion2 = distortion_y + distortion_uv;
Angie Chiangff6d8902016-10-21 11:02:09 -07008391 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07008392#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008393 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008394 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008395 cpi, &xd->plane[0].dst, bsize, xd->bd);
8396 } else {
8397 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008398 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008399 }
8400#else
8401 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008402 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
8403#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008404
8405 rate2 += ref_costs_single[INTRA_FRAME];
8406
8407 if (skippable) {
8408 rate2 -= (rate_y + rate_uv);
8409 rate_y = 0;
8410 rate_uv = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07008411 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008412 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07008413 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008414 }
8415 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008416
8417 if (this_rd < *best_intra_rd) {
8418 *best_intra_rd = this_rd;
8419 *best_intra_mode = mbmi->mode;
8420 }
8421 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07008422 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008423
8424 if (this_rd < *best_rd) {
8425 *best_mode_index = dc_mode_index;
8426 mbmi->mv[0].as_int = 0;
8427 rd_cost->rate = rate2;
8428#if CONFIG_SUPERTX
8429 if (x->skip)
8430 *returnrate_nocoef = rate2;
8431 else
8432 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07008433 *returnrate_nocoef -= av1_cost_bit(av1_get_skip_prob(cm, xd), skippable);
8434 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
8435 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008436#endif // CONFIG_SUPERTX
8437 rd_cost->dist = distortion2;
8438 rd_cost->rdcost = this_rd;
8439 *best_rd = this_rd;
8440 *best_mbmode = *mbmi;
8441 *best_skip2 = 0;
8442 *best_mode_skippable = skippable;
8443 }
8444}
hui su5db97432016-10-14 16:10:14 -07008445#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008446
Yue Chencb60b182016-10-13 15:18:22 -07008447#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008448static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
8449 const MACROBLOCKD *xd, int mi_row,
8450 int mi_col, const uint8_t *above,
8451 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -07008452 int left_stride);
Yue Chencb60b182016-10-13 15:18:22 -07008453#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008454
Urvang Joshi52648442016-10-13 17:27:51 -07008455void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
Yaowu Xuf883b422016-08-30 14:01:10 -07008456 MACROBLOCK *x, int mi_row, int mi_col,
8457 RD_COST *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008458#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07008459 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008460#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07008461 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
8462 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07008463 const AV1_COMMON *const cm = &cpi->common;
8464 const RD_OPT *const rd_opt = &cpi->rd;
8465 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008466 MACROBLOCKD *const xd = &x->e_mbd;
8467 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008468#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008469 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07008470#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008471 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
8472 const struct segmentation *const seg = &cm->seg;
8473 PREDICTION_MODE this_mode;
8474 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
8475 unsigned char segment_id = mbmi->segment_id;
8476 int comp_pred, i, k;
8477 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8478 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
8479#if CONFIG_EXT_INTER
8480 int_mv single_newmvs[2][TOTAL_REFS_PER_FRAME] = { { { 0 } }, { { 0 } } };
8481 int single_newmvs_rate[2][TOTAL_REFS_PER_FRAME] = { { 0 }, { 0 } };
8482 int64_t modelled_rd[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8483#else
8484 int_mv single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
8485#endif // CONFIG_EXT_INTER
James Zern7b9407a2016-05-18 23:48:05 -07008486 InterpFilter single_inter_filter[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008487 int single_skippable[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8488 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
8489 0,
Yaowu Xuf883b422016-08-30 14:01:10 -07008490 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008491#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008492 AOM_LAST2_FLAG,
8493 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008494#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008495 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008496#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008497 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008498#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008499 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07008500 };
8501 int64_t best_rd = best_rd_so_far;
8502 int best_rate_y = INT_MAX, best_rate_uv = INT_MAX;
8503 int64_t best_pred_diff[REFERENCE_MODES];
8504 int64_t best_pred_rd[REFERENCE_MODES];
8505 MB_MODE_INFO best_mbmode;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07008506#if CONFIG_REF_MV
8507 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
8508 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8509#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008510 int best_mode_skippable = 0;
8511 int midx, best_mode_index = -1;
8512 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
8513 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -07008514 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008515 int64_t best_intra_rd = INT64_MAX;
8516 unsigned int best_pred_sse = UINT_MAX;
8517 PREDICTION_MODE best_intra_mode = DC_PRED;
8518 int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES];
Urvang Joshi368fbc92016-10-17 16:31:34 -07008519 int64_t dist_uvs[TX_SIZES];
8520 int skip_uvs[TX_SIZES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008521 PREDICTION_MODE mode_uv[TX_SIZES];
Urvang Joshib100db72016-10-12 16:28:56 -07008522#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008523 PALETTE_MODE_INFO pmi_uv[TX_SIZES];
Urvang Joshib100db72016-10-12 16:28:56 -07008524#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008525#if CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008526 int8_t uv_angle_delta[TX_SIZES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008527 int is_directional_mode, angle_stats_ready = 0;
8528 int rate_overhead, rate_dummy;
8529 uint8_t directional_mode_skip_mask[INTRA_MODES];
8530#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008531#if CONFIG_FILTER_INTRA
8532 int8_t dc_skipped = 1;
8533 FILTER_INTRA_MODE_INFO filter_intra_mode_info_uv[TX_SIZES];
8534#endif // CONFIG_FILTER_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07008535 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008536 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
8537 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
8538 int best_skip2 = 0;
8539 uint8_t ref_frame_skip_mask[2] = { 0 };
8540#if CONFIG_EXT_INTER
8541 uint32_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
8542 MV_REFERENCE_FRAME best_single_inter_ref = LAST_FRAME;
8543 int64_t best_single_inter_rd = INT64_MAX;
8544#else
8545 uint16_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
8546#endif // CONFIG_EXT_INTER
8547 int mode_skip_start = sf->mode_skip_start + 1;
8548 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
8549 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
8550 int64_t mode_threshold[MAX_MODES];
8551 int *mode_map = tile_data->mode_map[bsize];
8552 const int mode_search_skip_flags = sf->mode_search_skip_flags;
8553 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
Yushin Cho77bba8d2016-11-04 16:36:56 -07008554#if CONFIG_PVQ
8555 od_rollback_buffer pre_buf;
8556#endif
8557
Urvang Joshib100db72016-10-12 16:28:56 -07008558#if CONFIG_PALETTE || CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08008559 const int rows = block_size_high[bsize];
8560 const int cols = block_size_wide[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07008561#endif // CONFIG_PALETTE || CONFIG_EXT_INTRA
8562#if CONFIG_PALETTE
8563 int palette_ctx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008564 const MODE_INFO *above_mi = xd->above_mi;
8565 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshib100db72016-10-12 16:28:56 -07008566#endif // CONFIG_PALETTE
Yue Chencb60b182016-10-13 15:18:22 -07008567#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008568#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008569 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8570 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8571#else
8572 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
8573 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07008574#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008575 DECLARE_ALIGNED(16, int32_t, weighted_src_buf[MAX_SB_SQUARE]);
8576 DECLARE_ALIGNED(16, int32_t, mask2d_buf[MAX_SB_SQUARE]);
8577 uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
8578 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8579 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8580 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8581 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8582 int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8583 int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8584
Yaowu Xuf883b422016-08-30 14:01:10 -07008585#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008586 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
8587 int len = sizeof(uint16_t);
8588 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
8589 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
8590 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_SB_SQUARE * len);
8591 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
8592 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
8593 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_SB_SQUARE * len);
8594 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07008595#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008596 dst_buf1[0] = tmp_buf1;
8597 dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
8598 dst_buf1[2] = tmp_buf1 + 2 * MAX_SB_SQUARE;
8599 dst_buf2[0] = tmp_buf2;
8600 dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
8601 dst_buf2[2] = tmp_buf2 + 2 * MAX_SB_SQUARE;
Yaowu Xuf883b422016-08-30 14:01:10 -07008602#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008603 }
Yaowu Xuf883b422016-08-30 14:01:10 -07008604#endif // CONFIG_AOM_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07008605#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008606
Yaowu Xuf883b422016-08-30 14:01:10 -07008607 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008608
Urvang Joshib100db72016-10-12 16:28:56 -07008609#if CONFIG_PALETTE
8610 av1_zero(pmi_uv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008611 if (cm->allow_screen_content_tools) {
8612 if (above_mi)
8613 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
8614 if (left_mi)
8615 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
8616 }
Urvang Joshib100db72016-10-12 16:28:56 -07008617#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008618
8619#if CONFIG_EXT_INTRA
8620 memset(directional_mode_skip_mask, 0,
8621 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
8622#endif // CONFIG_EXT_INTRA
8623
8624 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
8625 &comp_mode_p);
8626
8627 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
8628 for (i = 0; i < TX_SIZES; i++) rate_uv_intra[i] = INT_MAX;
8629 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
8630 for (i = 0; i < MB_MODE_COUNT; ++i) {
8631 for (k = 0; k < TOTAL_REFS_PER_FRAME; ++k) {
8632 single_inter_filter[i][k] = SWITCHABLE;
8633 single_skippable[i][k] = 0;
8634 }
8635 }
8636
8637 rd_cost->rate = INT_MAX;
8638#if CONFIG_SUPERTX
8639 *returnrate_nocoef = INT_MAX;
8640#endif // CONFIG_SUPERTX
8641
8642 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
8643 x->pred_mv_sad[ref_frame] = INT_MAX;
8644 x->mbmi_ext->mode_context[ref_frame] = 0;
8645#if CONFIG_REF_MV && CONFIG_EXT_INTER
8646 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
8647#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
8648 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
8649 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
8650 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
8651 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
8652 }
8653 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkere5299862016-08-16 14:57:37 -07008654#if CONFIG_GLOBAL_MOTION
8655 frame_mv[ZEROMV][ref_frame].as_int =
David Barkercdcac6d2016-12-01 17:04:16 +00008656 gm_get_motion_vector(&cm->global_motion[ref_frame],
8657 cm->allow_high_precision_mv)
8658 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07008659#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008660 frame_mv[ZEROMV][ref_frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07008661#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008662#if CONFIG_EXT_INTER
8663 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
8664 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
8665 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
8666#endif // CONFIG_EXT_INTER
8667 }
8668
8669#if CONFIG_REF_MV
8670 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
8671 MODE_INFO *const mi = xd->mi[0];
8672 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
8673 x->mbmi_ext->mode_context[ref_frame] = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07008674 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
8675 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07008676#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008677 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008678#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008679 candidates, mi_row, mi_col, NULL, NULL,
8680 mbmi_ext->mode_context);
Jingning Han731af492016-11-17 11:53:23 -08008681 if (mbmi_ext->ref_mv_count[ref_frame] < 2) {
8682 MV_REFERENCE_FRAME rf[2];
8683 av1_set_ref_frame(rf, ref_frame);
David Barkercdcac6d2016-12-01 17:04:16 +00008684 if (mbmi_ext->ref_mvs[rf[0]][0].as_int !=
8685 frame_mv[ZEROMV][rf[0]].as_int ||
8686 mbmi_ext->ref_mvs[rf[0]][1].as_int !=
8687 frame_mv[ZEROMV][rf[0]].as_int ||
8688 mbmi_ext->ref_mvs[rf[1]][0].as_int !=
8689 frame_mv[ZEROMV][rf[1]].as_int ||
8690 mbmi_ext->ref_mvs[rf[1]][1].as_int != frame_mv[ZEROMV][rf[1]].as_int)
Jingning Han731af492016-11-17 11:53:23 -08008691 mbmi_ext->mode_context[ref_frame] &= ~(1 << ALL_ZERO_FLAG_OFFSET);
8692 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008693 }
8694#endif // CONFIG_REF_MV
8695
Yue Chencb60b182016-10-13 15:18:22 -07008696#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008697 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1,
8698 dst_width1, dst_height1, dst_stride1);
8699 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2,
8700 dst_width2, dst_height2, dst_stride2);
8701 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yue Chene9638cc2016-10-10 12:37:54 -07008702 x->mask_buf = mask2d_buf;
8703 x->wsrc_buf = weighted_src_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008704 calc_target_weighted_pred(cm, x, xd, mi_row, mi_col, dst_buf1[0],
Yue Chene9638cc2016-10-10 12:37:54 -07008705 dst_stride1[0], dst_buf2[0], dst_stride2[0]);
Yue Chencb60b182016-10-13 15:18:22 -07008706#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008707
8708 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
8709 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
8710// Skip checking missing references in both single and compound reference
8711// modes. Note that a mode will be skipped iff both reference frames
8712// are masked out.
8713#if CONFIG_EXT_REFS
8714 if (ref_frame == BWDREF_FRAME || ref_frame == ALTREF_FRAME) {
8715 ref_frame_skip_mask[0] |= (1 << ref_frame);
8716 ref_frame_skip_mask[1] |= ((1 << ref_frame) | 0x01);
8717 } else {
8718#endif // CONFIG_EXT_REFS
8719 ref_frame_skip_mask[0] |= (1 << ref_frame);
8720 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8721#if CONFIG_EXT_REFS
8722 }
8723#endif // CONFIG_EXT_REFS
8724 } else {
8725 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
8726 // Skip fixed mv modes for poor references
8727 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
8728 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
8729 break;
8730 }
8731 }
8732 }
8733 // If the segment reference frame feature is enabled....
8734 // then do nothing if the current ref frame is not allowed..
8735 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
8736 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
8737 ref_frame_skip_mask[0] |= (1 << ref_frame);
8738 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8739 }
8740 }
8741
8742 // Disable this drop out case if the ref frame
8743 // segment level feature is enabled for this segment. This is to
8744 // prevent the possibility that we end up unable to pick any mode.
8745 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
8746 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
8747 // unless ARNR filtering is enabled in which case we want
8748 // an unfiltered alternative. We allow near/nearest as well
8749 // because they may result in zero-zero MVs but be cheaper.
8750 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Sarah Parkere5299862016-08-16 14:57:37 -07008751 int_mv zeromv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008752 ref_frame_skip_mask[0] = (1 << LAST_FRAME) |
8753#if CONFIG_EXT_REFS
8754 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
8755 (1 << BWDREF_FRAME) |
8756#endif // CONFIG_EXT_REFS
8757 (1 << GOLDEN_FRAME);
8758 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
8759 // TODO(zoeliu): To further explore whether following needs to be done for
8760 // BWDREF_FRAME as well.
8761 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
Sarah Parkere5299862016-08-16 14:57:37 -07008762#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +00008763 zeromv.as_int = gm_get_motion_vector(&cm->global_motion[ALTREF_FRAME],
8764 cm->allow_high_precision_mv)
8765 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07008766#else
8767 zeromv.as_int = 0;
8768#endif // CONFIG_GLOBAL_MOTION
8769 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008770 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008771 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008772 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
8773#if CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07008774 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008775 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008776 if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008777 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008778 if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008779 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008780 if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008781 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV);
8782#endif // CONFIG_EXT_INTER
8783 }
8784 }
8785
8786 if (cpi->rc.is_src_frame_alt_ref) {
8787 if (sf->alt_ref_search_fp) {
8788 assert(cpi->ref_frame_flags & flag_list[ALTREF_FRAME]);
8789 mode_skip_mask[ALTREF_FRAME] = 0;
8790 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
8791 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
8792 }
8793 }
8794
8795 if (sf->alt_ref_search_fp)
8796 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
8797 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
8798 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
8799
8800 if (sf->adaptive_mode_search) {
8801 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
8802 cpi->rc.frames_since_golden >= 3)
8803 if (x->pred_mv_sad[GOLDEN_FRAME] > (x->pred_mv_sad[LAST_FRAME] << 1))
8804 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
8805 }
8806
8807 if (bsize > sf->max_intra_bsize) {
8808 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
8809 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
8810 }
8811
8812 mode_skip_mask[INTRA_FRAME] |=
8813 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
8814
8815 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i) mode_threshold[i] = 0;
8816 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
8817 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
8818
8819 midx = sf->schedule_mode_search ? mode_skip_start : 0;
8820 while (midx > 4) {
8821 uint8_t end_pos = 0;
8822 for (i = 5; i < midx; ++i) {
8823 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
8824 uint8_t tmp = mode_map[i];
8825 mode_map[i] = mode_map[i - 1];
8826 mode_map[i - 1] = tmp;
8827 end_pos = i;
8828 }
8829 }
8830 midx = end_pos;
8831 }
8832
8833 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
8834 x->use_default_intra_tx_type = 1;
8835 else
8836 x->use_default_intra_tx_type = 0;
8837
8838 if (cpi->sf.tx_type_search.fast_inter_tx_type_search)
8839 x->use_default_inter_tx_type = 1;
8840 else
8841 x->use_default_inter_tx_type = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07008842#if CONFIG_PVQ
8843 od_encode_checkpoint(&x->daala_enc, &pre_buf);
8844#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008845#if CONFIG_EXT_INTER
8846 for (i = 0; i < MB_MODE_COUNT; ++i)
8847 for (ref_frame = 0; ref_frame < TOTAL_REFS_PER_FRAME; ++ref_frame)
8848 modelled_rd[i][ref_frame] = INT64_MAX;
8849#endif // CONFIG_EXT_INTER
8850
8851 for (midx = 0; midx < MAX_MODES; ++midx) {
8852 int mode_index;
8853 int mode_excluded = 0;
8854 int64_t this_rd = INT64_MAX;
8855 int disable_skip = 0;
8856 int compmode_cost = 0;
8857#if CONFIG_EXT_INTER
8858 int compmode_interintra_cost = 0;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008859 int compmode_interinter_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008860#endif // CONFIG_EXT_INTER
8861 int rate2 = 0, rate_y = 0, rate_uv = 0;
8862 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
8863 int skippable = 0;
8864 int this_skip2 = 0;
8865 int64_t total_sse = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008866#if CONFIG_REF_MV
8867 uint8_t ref_frame_type;
8868#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07008869#if CONFIG_PVQ
8870 od_encode_rollback(&x->daala_enc, &pre_buf);
8871#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008872 mode_index = mode_map[midx];
Yaowu Xuf883b422016-08-30 14:01:10 -07008873 this_mode = av1_mode_order[mode_index].mode;
8874 ref_frame = av1_mode_order[mode_index].ref_frame[0];
8875 second_ref_frame = av1_mode_order[mode_index].ref_frame[1];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07008876#if CONFIG_REF_MV
8877 mbmi->ref_mv_idx = 0;
8878#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008879
8880#if CONFIG_EXT_INTER
8881 if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
8882 // Mode must by compatible
8883 assert(is_interintra_allowed_mode(this_mode));
8884
8885 if (!is_interintra_allowed_bsize(bsize)) continue;
8886 }
8887
8888 if (is_inter_compound_mode(this_mode)) {
8889 frame_mv[this_mode][ref_frame].as_int =
8890 frame_mv[compound_ref0_mode(this_mode)][ref_frame].as_int;
8891 frame_mv[this_mode][second_ref_frame].as_int =
8892 frame_mv[compound_ref1_mode(this_mode)][second_ref_frame].as_int;
8893 }
8894#endif // CONFIG_EXT_INTER
8895
8896 // Look at the reference frame of the best mode so far and set the
8897 // skip mask to look at a subset of the remaining modes.
8898 if (midx == mode_skip_start && best_mode_index >= 0) {
8899 switch (best_mbmode.ref_frame[0]) {
8900 case INTRA_FRAME: break;
8901 case LAST_FRAME:
8902 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
8903 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8904 break;
8905#if CONFIG_EXT_REFS
8906 case LAST2_FRAME:
8907 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
8908 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8909 break;
8910 case LAST3_FRAME:
8911 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
8912 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8913 break;
8914#endif // CONFIG_EXT_REFS
8915 case GOLDEN_FRAME:
8916 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
8917 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8918 break;
8919#if CONFIG_EXT_REFS
8920 case BWDREF_FRAME:
8921 ref_frame_skip_mask[0] |= BWDREF_FRAME_MODE_MASK;
8922 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8923 break;
8924#endif // CONFIG_EXT_REFS
8925 case ALTREF_FRAME: ref_frame_skip_mask[0] |= ALTREF_FRAME_MODE_MASK;
8926#if CONFIG_EXT_REFS
8927 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8928#endif // CONFIG_EXT_REFS
8929 break;
8930 case NONE:
8931 case TOTAL_REFS_PER_FRAME:
8932 assert(0 && "Invalid Reference frame");
8933 break;
8934 }
8935 }
8936
8937 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -07008938 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -07008939 continue;
8940
8941 if (mode_skip_mask[ref_frame] & (1 << this_mode)) continue;
8942
8943 // Test best rd so far against threshold for trying this mode.
8944 if (best_mode_skippable && sf->schedule_mode_search)
8945 mode_threshold[mode_index] <<= 1;
8946
8947 if (best_rd < mode_threshold[mode_index]) continue;
8948
8949 comp_pred = second_ref_frame > INTRA_FRAME;
8950 if (comp_pred) {
8951 if (!cpi->allow_comp_inter_inter) continue;
8952
8953 // Skip compound inter modes if ARF is not available.
8954 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
8955
8956 // Do not allow compound prediction if the segment level reference frame
8957 // feature is in use as in this case there can only be one reference.
8958 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
8959
8960 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
8961 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
8962 continue;
8963
8964 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
8965 } else {
8966 if (ref_frame != INTRA_FRAME)
8967 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
8968 }
8969
8970 if (ref_frame == INTRA_FRAME) {
8971 if (sf->adaptive_mode_search)
8972 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
8973 continue;
8974
8975 if (this_mode != DC_PRED) {
8976 // Disable intra modes other than DC_PRED for blocks with low variance
8977 // Threshold for intra skipping based on source variance
8978 // TODO(debargha): Specialize the threshold for super block sizes
8979 const unsigned int skip_intra_var_thresh = 64;
8980 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
8981 x->source_variance < skip_intra_var_thresh)
8982 continue;
8983 // Only search the oblique modes if the best so far is
8984 // one of the neighboring directional modes
8985 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
8986 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
8987 if (best_mode_index >= 0 && best_mbmode.ref_frame[0] > INTRA_FRAME)
8988 continue;
8989 }
8990 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
8991 if (conditional_skipintra(this_mode, best_intra_mode)) continue;
8992 }
8993 }
Sarah Parkere5299862016-08-16 14:57:37 -07008994#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +00008995 } else if (cm->global_motion[ref_frame].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -07008996 (!comp_pred ||
David Barkercf3d0b02016-11-10 10:14:49 +00008997 cm->global_motion[second_ref_frame].wmtype == IDENTITY)) {
Sarah Parkere5299862016-08-16 14:57:37 -07008998#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008999 } else {
Sarah Parkere5299862016-08-16 14:57:37 -07009000#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009001 const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame };
9002 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
9003#if CONFIG_REF_MV && CONFIG_EXT_INTER
9004 mbmi_ext->compound_mode_context,
9005#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
9006 frame_mv, this_mode, ref_frames, bsize, -1))
9007 continue;
9008 }
9009
9010 mbmi->mode = this_mode;
9011 mbmi->uv_mode = DC_PRED;
9012 mbmi->ref_frame[0] = ref_frame;
9013 mbmi->ref_frame[1] = second_ref_frame;
Urvang Joshib100db72016-10-12 16:28:56 -07009014#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009015 pmi->palette_size[0] = 0;
9016 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07009017#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009018#if CONFIG_FILTER_INTRA
9019 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
9020 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
9021#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009022 // Evaluate all sub-pel filters irrespective of whether we can use
9023 // them for this frame.
9024#if CONFIG_DUAL_FILTER
9025 for (i = 0; i < 4; ++i) {
9026 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
9027 ? EIGHTTAP_REGULAR
9028 : cm->interp_filter;
9029 }
9030#else
9031 mbmi->interp_filter =
9032 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
9033#endif
9034 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chencb60b182016-10-13 15:18:22 -07009035 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009036
9037 x->skip = 0;
9038 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
9039
9040 // Select prediction reference frames.
9041 for (i = 0; i < MAX_MB_PLANE; i++) {
9042 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
9043 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
9044 }
9045
9046#if CONFIG_EXT_INTER
Debargha Mukherjeecb603792016-10-04 13:10:23 -07009047 mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009048#endif // CONFIG_EXT_INTER
9049
9050 if (ref_frame == INTRA_FRAME) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009051 RD_STATS rd_stats_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009052 TX_SIZE uv_tx;
9053 struct macroblockd_plane *const pd = &xd->plane[1];
9054#if CONFIG_EXT_INTRA
9055 is_directional_mode = (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED);
9056 if (is_directional_mode) {
9057 if (!angle_stats_ready) {
9058 const int src_stride = x->plane[0].src.stride;
9059 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuf883b422016-08-30 14:01:10 -07009060#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009061 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
9062 highbd_angle_estimation(src, src_stride, rows, cols,
9063 directional_mode_skip_mask);
9064 else
9065#endif
9066 angle_estimation(src, src_stride, rows, cols,
9067 directional_mode_skip_mask);
9068 angle_stats_ready = 1;
9069 }
9070 if (directional_mode_skip_mask[mbmi->mode]) continue;
9071 rate_overhead = write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0) +
9072 intra_mode_cost[mbmi->mode];
9073 rate_y = INT_MAX;
9074 this_rd =
9075 rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
9076 &skippable, bsize, rate_overhead, best_rd);
9077 } else {
9078 mbmi->angle_delta[0] = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009079 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
9080 rate_y = rd_stats_y.rate;
9081 distortion_y = rd_stats_y.dist;
9082 skippable = rd_stats_y.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009083 }
9084#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009085 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
9086 rate_y = rd_stats_y.rate;
9087 distortion_y = rd_stats_y.dist;
9088 skippable = rd_stats_y.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009089#endif // CONFIG_EXT_INTRA
9090
9091 if (rate_y == INT_MAX) continue;
9092
hui su5db97432016-10-14 16:10:14 -07009093#if CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009094 if (mbmi->mode == DC_PRED) dc_skipped = 0;
hui su5db97432016-10-14 16:10:14 -07009095#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009096
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009097 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][pd->subsampling_x]
9098 [pd->subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009099 if (rate_uv_intra[uv_tx] == INT_MAX) {
9100 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -07009101 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
9102 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07009103#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009104 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009105#endif // CONFIG_PALETTE
9106
Yaowu Xuc27fc142016-08-22 16:08:15 -07009107#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009108 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
9109#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009110#if CONFIG_FILTER_INTRA
9111 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9112#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009113 }
9114
9115 rate_uv = rate_uv_tokenonly[uv_tx];
Urvang Joshi368fbc92016-10-17 16:31:34 -07009116 distortion_uv = dist_uvs[uv_tx];
9117 skippable = skippable && skip_uvs[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009118 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07009119#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009120 if (cm->allow_screen_content_tools) {
9121 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9122 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9123 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9124 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9125 }
Urvang Joshib100db72016-10-12 16:28:56 -07009126#endif // CONFIG_PALETTE
9127
Yaowu Xuc27fc142016-08-22 16:08:15 -07009128#if CONFIG_EXT_INTRA
9129 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009130#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009131#if CONFIG_FILTER_INTRA
9132 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9133 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9134 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9135 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9136 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
9137 }
9138#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009139
9140 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
9141 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07009142#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009143 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07009144 rate2 += av1_cost_bit(
9145 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07009146#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009147
9148 if (!xd->lossless[mbmi->segment_id]) {
9149 // super_block_yrd above includes the cost of the tx_size in the
9150 // tokenonly rate, but for intra blocks, tx_size is always coded
9151 // (prediction granularity), so we account for it in the full rate,
9152 // not the tokenonly rate.
Jingning Hanb0a71302016-10-25 16:28:49 -07009153 rate_y -=
9154 cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
9155 [tx_size_to_depth(mbmi->tx_size)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009156 }
9157#if CONFIG_EXT_INTRA
9158 if (is_directional_mode) {
9159 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07009160 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009161 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
9162 MAX_ANGLE_DELTAS + mbmi->angle_delta[0]);
9163 p_angle =
9164 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07009165 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07009166 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
9167 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009168 if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
9169 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
9170 MAX_ANGLE_DELTAS + mbmi->angle_delta[1]);
9171 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009172#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009173#if CONFIG_FILTER_INTRA
9174 if (mbmi->mode == DC_PRED) {
9175 rate2 +=
9176 av1_cost_bit(cm->fc->filter_intra_probs[0],
9177 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
9178 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
9179 rate2 += write_uniform_cost(
9180 FILTER_INTRA_MODES,
9181 mbmi->filter_intra_mode_info.filter_intra_mode[0]);
9182 }
9183 }
9184 if (mbmi->uv_mode == DC_PRED) {
9185 rate2 +=
9186 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
9187 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
9188 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
9189 rate2 += write_uniform_cost(
9190 FILTER_INTRA_MODES,
9191 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
9192 }
9193#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009194 if (this_mode != DC_PRED && this_mode != TM_PRED)
9195 rate2 += intra_cost_penalty;
9196 distortion2 = distortion_y + distortion_uv;
Angie Chiangff6d8902016-10-21 11:02:09 -07009197 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 1);
Yaowu Xuf883b422016-08-30 14:01:10 -07009198#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009199 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009200 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009201 cpi, &xd->plane[0].dst, bsize, xd->bd);
9202 } else {
9203 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07009204 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009205 }
9206#else
9207 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07009208 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
9209#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009210 } else {
9211#if CONFIG_REF_MV
9212 int_mv backup_ref_mv[2];
9213
9214 backup_ref_mv[0] = mbmi_ext->ref_mvs[ref_frame][0];
9215 if (comp_pred) backup_ref_mv[1] = mbmi_ext->ref_mvs[second_ref_frame][0];
9216#endif
9217#if CONFIG_EXT_INTER
9218 if (second_ref_frame == INTRA_FRAME) {
9219 if (best_single_inter_ref != ref_frame) continue;
Debargha Mukherjeecb603792016-10-04 13:10:23 -07009220 mbmi->interintra_mode = intra_to_interintra_mode[best_intra_mode];
hui su5db97432016-10-14 16:10:14 -07009221// TODO(debargha|geza.lore):
9222// Should we use ext_intra modes for interintra?
Yaowu Xuc27fc142016-08-22 16:08:15 -07009223#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009224 mbmi->angle_delta[0] = 0;
9225 mbmi->angle_delta[1] = 0;
9226 mbmi->intra_filter = INTRA_FILTER_LINEAR;
9227#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009228#if CONFIG_FILTER_INTRA
9229 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
9230 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
9231#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009232 }
9233#endif // CONFIG_EXT_INTER
9234#if CONFIG_REF_MV
9235 mbmi->ref_mv_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009236 ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009237
9238 if (this_mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
9239 int ref;
9240 for (ref = 0; ref < 1 + comp_pred; ++ref) {
9241 int_mv this_mv =
9242 (ref == 0) ? mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv
9243 : mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
9244 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << 3, xd->n8_h << 3, xd);
9245 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
9246 }
9247 }
9248#endif
Angie Chiang76159122016-11-09 12:13:22 -08009249 {
9250 RD_STATS rd_stats, rd_stats_y, rd_stats_uv;
9251 av1_init_rd_stats(&rd_stats);
9252 rd_stats.rate = rate2;
9253 this_rd = handle_inter_mode(
9254 cpi, x, bsize, &rd_stats, &rd_stats_y, &rd_stats_uv, &disable_skip,
9255 frame_mv, mi_row, mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07009256#if CONFIG_MOTION_VAR
Angie Chiang76159122016-11-09 12:13:22 -08009257 dst_buf1, dst_stride1, dst_buf2, dst_stride2,
Yue Chencb60b182016-10-13 15:18:22 -07009258#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009259#if CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08009260 single_newmvs, single_newmvs_rate, &compmode_interintra_cost,
Sarah Parker6fdc8532016-11-16 17:47:13 -08009261 &compmode_interinter_cost, modelled_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009262#else
Angie Chiang76159122016-11-09 12:13:22 -08009263 single_newmv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009264#endif // CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08009265 single_inter_filter, single_skippable, best_rd);
9266
9267 rate2 = rd_stats.rate;
9268 skippable = rd_stats.skip;
9269 distortion2 = rd_stats.dist;
9270 total_sse = rd_stats.sse;
9271 rate_y = rd_stats_y.rate;
9272 rate_uv = rd_stats_uv.rate;
9273 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009274
9275#if CONFIG_REF_MV
9276 // TODO(jingning): This needs some refactoring to improve code quality
9277 // and reduce redundant steps.
9278 if ((mbmi->mode == NEARMV &&
9279 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
9280 (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
9281 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
9282 MB_MODE_INFO backup_mbmi = *mbmi;
9283 int backup_skip = x->skip;
9284 int64_t tmp_ref_rd = this_rd;
9285 int ref_idx;
9286
9287 // TODO(jingning): This should be deprecated shortly.
9288 int idx_offset = (mbmi->mode == NEARMV) ? 1 : 0;
9289 int ref_set =
Yaowu Xuf883b422016-08-30 14:01:10 -07009290 AOMMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 1 - idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009291
9292 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07009293 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009294 // Dummy
9295 int_mv backup_fmv[2];
9296 backup_fmv[0] = frame_mv[NEWMV][ref_frame];
9297 if (comp_pred) backup_fmv[1] = frame_mv[NEWMV][second_ref_frame];
9298
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07009299 rate2 += (rate2 < INT_MAX ? cpi->drl_mode_cost0[drl_ctx][0] : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009300
9301 if (this_rd < INT64_MAX) {
9302 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
9303 RDCOST(x->rdmult, x->rddiv, 0, total_sse))
9304 tmp_ref_rd =
9305 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -07009306 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Yaowu Xuc27fc142016-08-22 16:08:15 -07009307 distortion2);
9308 else
9309 tmp_ref_rd =
9310 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -07009311 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
Yaowu Xuc27fc142016-08-22 16:08:15 -07009312 rate_y - rate_uv,
9313 total_sse);
9314 }
9315#if CONFIG_VAR_TX
9316 for (i = 0; i < MAX_MB_PLANE; ++i)
9317 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
9318 sizeof(uint8_t) * ctx->num_4x4_blk);
9319#endif
9320
9321 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
9322 int64_t tmp_alt_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009323 int dummy_disable_skip = 0;
9324 int ref;
9325 int_mv cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -08009326 RD_STATS tmp_rd_stats, tmp_rd_stats_y, tmp_rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009327
Yaowu Xu5bfbfdf2016-11-22 16:43:34 -08009328 av1_invalid_rd_stats(&tmp_rd_stats);
9329
Yaowu Xuc27fc142016-08-22 16:08:15 -07009330 mbmi->ref_mv_idx = 1 + ref_idx;
9331
9332 for (ref = 0; ref < 1 + comp_pred; ++ref) {
9333 int_mv this_mv =
9334 (ref == 0)
9335 ? mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
9336 .this_mv
9337 : mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
9338 .comp_mv;
9339 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << 3, xd->n8_h << 3, xd);
9340 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
9341 }
9342
9343 cur_mv =
9344 mbmi_ext->ref_mv_stack[ref_frame][mbmi->ref_mv_idx + idx_offset]
9345 .this_mv;
9346 clamp_mv2(&cur_mv.as_mv, xd);
9347
9348 if (!mv_check_bounds(x, &cur_mv.as_mv)) {
clang-format67948d32016-09-07 22:40:40 -07009349 int dummy_single_skippable[MB_MODE_COUNT]
9350 [TOTAL_REFS_PER_FRAME] = { { 0 } };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009351#if CONFIG_EXT_INTER
9352 int_mv dummy_single_newmvs[2][TOTAL_REFS_PER_FRAME] = { { { 0 } },
9353 { { 0 } } };
9354 int dummy_single_newmvs_rate[2][TOTAL_REFS_PER_FRAME] = { { 0 },
9355 { 0 } };
9356 int dummy_compmode_interintra_cost = 0;
Sarah Parker6fdc8532016-11-16 17:47:13 -08009357 int dummy_compmode_interinter_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009358#else
9359 int_mv dummy_single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
9360#endif
9361
9362 frame_mv[NEARMV][ref_frame] = cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -08009363 av1_init_rd_stats(&tmp_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009364 tmp_alt_rd = handle_inter_mode(
Angie Chiang76159122016-11-09 12:13:22 -08009365 cpi, x, bsize, &tmp_rd_stats, &tmp_rd_stats_y, &tmp_rd_stats_uv,
9366 &dummy_disable_skip, frame_mv, mi_row, mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07009367#if CONFIG_MOTION_VAR
Yue Chene9638cc2016-10-10 12:37:54 -07009368 dst_buf1, dst_stride1, dst_buf2, dst_stride2,
Yue Chencb60b182016-10-13 15:18:22 -07009369#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009370#if CONFIG_EXT_INTER
9371 dummy_single_newmvs, dummy_single_newmvs_rate,
Sarah Parker6fdc8532016-11-16 17:47:13 -08009372 &dummy_compmode_interintra_cost,
9373 &dummy_compmode_interinter_cost, NULL,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009374#else
9375 dummy_single_newmv,
9376#endif
Angie Chiang76159122016-11-09 12:13:22 -08009377 single_inter_filter, dummy_single_skippable, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009378 }
9379
9380 for (i = 0; i < mbmi->ref_mv_idx; ++i) {
9381 uint8_t drl1_ctx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009382 drl1_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
9383 i + idx_offset);
Angie Chiang76159122016-11-09 12:13:22 -08009384 tmp_rd_stats.rate +=
9385 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][1]
9386 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009387 }
9388
9389 if (mbmi_ext->ref_mv_count[ref_frame_type] >
9390 mbmi->ref_mv_idx + idx_offset + 1 &&
9391 ref_idx < ref_set - 1) {
9392 uint8_t drl1_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07009393 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
9394 mbmi->ref_mv_idx + idx_offset);
Yaowu Xu83ed6fe2016-11-22 11:15:29 -08009395 tmp_rd_stats.rate +=
9396 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][0]
9397 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009398 }
9399
9400 if (tmp_alt_rd < INT64_MAX) {
Yue Chen69f18e12016-09-08 14:48:15 -07009401#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08009402 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv, tmp_rd_stats.rate,
9403 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009404#else
Angie Chiang76159122016-11-09 12:13:22 -08009405 if (RDCOST(x->rdmult, x->rddiv,
9406 tmp_rd_stats_y.rate + tmp_rd_stats_uv.rate,
9407 tmp_rd_stats.dist) <
9408 RDCOST(x->rdmult, x->rddiv, 0, tmp_rd_stats.sse))
Yaowu Xuf883b422016-08-30 14:01:10 -07009409 tmp_alt_rd =
9410 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08009411 tmp_rd_stats.rate +
9412 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
9413 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009414 else
Yaowu Xuf883b422016-08-30 14:01:10 -07009415 tmp_alt_rd =
9416 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08009417 tmp_rd_stats.rate +
9418 av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
9419 tmp_rd_stats_y.rate - tmp_rd_stats_uv.rate,
9420 tmp_rd_stats.sse);
Yue Chen69f18e12016-09-08 14:48:15 -07009421#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009422 }
9423
9424 if (tmp_ref_rd > tmp_alt_rd) {
Angie Chiang76159122016-11-09 12:13:22 -08009425 rate2 = tmp_rd_stats.rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009426 disable_skip = dummy_disable_skip;
Angie Chiang76159122016-11-09 12:13:22 -08009427 distortion2 = tmp_rd_stats.dist;
9428 skippable = tmp_rd_stats.skip;
9429 rate_y = tmp_rd_stats_y.rate;
9430 rate_uv = tmp_rd_stats_uv.rate;
9431 total_sse = tmp_rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009432 this_rd = tmp_alt_rd;
9433 tmp_ref_rd = tmp_alt_rd;
9434 backup_mbmi = *mbmi;
9435 backup_skip = x->skip;
9436#if CONFIG_VAR_TX
9437 for (i = 0; i < MAX_MB_PLANE; ++i)
9438 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
9439 sizeof(uint8_t) * ctx->num_4x4_blk);
9440#endif
9441 } else {
9442 *mbmi = backup_mbmi;
9443 x->skip = backup_skip;
9444 }
9445 }
9446
9447 frame_mv[NEARMV][ref_frame] = backup_mv;
9448 frame_mv[NEWMV][ref_frame] = backup_fmv[0];
9449 if (comp_pred) frame_mv[NEWMV][second_ref_frame] = backup_fmv[1];
9450#if CONFIG_VAR_TX
9451 for (i = 0; i < MAX_MB_PLANE; ++i)
9452 memcpy(x->blk_skip[i], x->blk_skip_drl[i],
9453 sizeof(uint8_t) * ctx->num_4x4_blk);
9454#endif
9455 }
9456 mbmi_ext->ref_mvs[ref_frame][0] = backup_ref_mv[0];
9457 if (comp_pred) mbmi_ext->ref_mvs[second_ref_frame][0] = backup_ref_mv[1];
9458#endif // CONFIG_REF_MV
9459
9460 if (this_rd == INT64_MAX) continue;
9461
Yaowu Xuf883b422016-08-30 14:01:10 -07009462 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009463
9464 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
9465 }
9466
9467#if CONFIG_EXT_INTER
9468 rate2 += compmode_interintra_cost;
9469 if (cm->reference_mode != SINGLE_REFERENCE && comp_pred)
Yue Chencb60b182016-10-13 15:18:22 -07009470#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
9471 if (mbmi->motion_mode == SIMPLE_TRANSLATION)
9472#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parker6fdc8532016-11-16 17:47:13 -08009473 rate2 += compmode_interinter_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009474#endif // CONFIG_EXT_INTER
9475
9476 // Estimate the reference frame signaling cost and add it
9477 // to the rolling cost variable.
9478 if (comp_pred) {
9479 rate2 += ref_costs_comp[ref_frame];
9480#if CONFIG_EXT_REFS
9481 rate2 += ref_costs_comp[second_ref_frame];
9482#endif // CONFIG_EXT_REFS
9483 } else {
9484 rate2 += ref_costs_single[ref_frame];
9485 }
9486
Yue Chen69f18e12016-09-08 14:48:15 -07009487#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009488 if (ref_frame == INTRA_FRAME) {
9489#else
9490 if (!disable_skip) {
Yue Chen69f18e12016-09-08 14:48:15 -07009491#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009492 if (skippable) {
9493 // Back out the coefficient coding costs
9494 rate2 -= (rate_y + rate_uv);
9495 rate_y = 0;
9496 rate_uv = 0;
9497 // Cost the skip mb case
Yaowu Xuf883b422016-08-30 14:01:10 -07009498 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009499 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009500#if CONFIG_REF_MV
9501 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv + rate_skip0,
9502 distortion2) <
9503 RDCOST(x->rdmult, x->rddiv, rate_skip1, total_sse)) {
9504#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009505 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
9506 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009507#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009508 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -07009509 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009510 } else {
9511 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -07009512 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009513 distortion2 = total_sse;
9514 assert(total_sse >= 0);
9515 rate2 -= (rate_y + rate_uv);
9516 this_skip2 = 1;
9517 rate_y = 0;
9518 rate_uv = 0;
9519 }
9520 } else {
9521 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -07009522 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009523 }
9524
9525 // Calculate the final RD estimate for this mode.
9526 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yue Chen69f18e12016-09-08 14:48:15 -07009527#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009528 } else {
9529 this_skip2 = mbmi->skip;
9530 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
9531 if (this_skip2) {
9532 rate_y = 0;
9533 rate_uv = 0;
9534 }
Yue Chen69f18e12016-09-08 14:48:15 -07009535#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009536 }
9537
Yaowu Xuc27fc142016-08-22 16:08:15 -07009538 if (ref_frame == INTRA_FRAME) {
9539 // Keep record of best intra rd
9540 if (this_rd < best_intra_rd) {
9541 best_intra_rd = this_rd;
9542 best_intra_mode = mbmi->mode;
9543 }
9544#if CONFIG_EXT_INTER
9545 } else if (second_ref_frame == NONE) {
9546 if (this_rd < best_single_inter_rd) {
9547 best_single_inter_rd = this_rd;
9548 best_single_inter_ref = mbmi->ref_frame[0];
9549 }
9550#endif // CONFIG_EXT_INTER
9551 }
9552
9553 if (!disable_skip && ref_frame == INTRA_FRAME) {
9554 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009555 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009556 }
9557
9558 // Did this mode help.. i.e. is it the new best mode
9559 if (this_rd < best_rd || x->skip) {
9560 if (!mode_excluded) {
9561 // Note index of best mode so far
9562 best_mode_index = mode_index;
9563
9564 if (ref_frame == INTRA_FRAME) {
9565 /* required for left and above block mv */
9566 mbmi->mv[0].as_int = 0;
9567 } else {
9568 best_pred_sse = x->pred_sse[ref_frame];
9569 }
9570
9571 rd_cost->rate = rate2;
9572#if CONFIG_SUPERTX
9573 if (x->skip)
9574 *returnrate_nocoef = rate2;
9575 else
9576 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07009577 *returnrate_nocoef -= av1_cost_bit(
9578 av1_get_skip_prob(cm, xd), disable_skip || skippable || this_skip2);
9579 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
9580 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chencb60b182016-10-13 15:18:22 -07009581#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yue Chen69f18e12016-09-08 14:48:15 -07009582#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
9583 if (motion_mode_allowed(mbmi) == WARPED_CAUSAL)
9584#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07009585 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Yue Chen69f18e12016-09-08 14:48:15 -07009586#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
9587 else if (motion_mode_allowed(mbmi) == OBMC_CAUSAL)
9588 *returnrate_nocoef -=
9589 cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
9590#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07009591#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009592#endif // CONFIG_SUPERTX
9593 rd_cost->dist = distortion2;
9594 rd_cost->rdcost = this_rd;
9595 best_rd = this_rd;
9596 best_mbmode = *mbmi;
9597 best_skip2 = this_skip2;
9598 best_mode_skippable = skippable;
Yaowu Xuf883b422016-08-30 14:01:10 -07009599 best_rate_y = rate_y + av1_cost_bit(av1_get_skip_prob(cm, xd),
9600 this_skip2 || skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009601 best_rate_uv = rate_uv;
9602
9603#if CONFIG_VAR_TX
9604 for (i = 0; i < MAX_MB_PLANE; ++i)
9605 memcpy(ctx->blk_skip[i], x->blk_skip[i],
9606 sizeof(uint8_t) * ctx->num_4x4_blk);
9607#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009608 }
9609 }
9610
9611 /* keep record of best compound/single-only prediction */
9612 if (!disable_skip && ref_frame != INTRA_FRAME) {
9613 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
9614
9615 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
9616 single_rate = rate2 - compmode_cost;
9617 hybrid_rate = rate2;
9618 } else {
9619 single_rate = rate2;
9620 hybrid_rate = rate2 + compmode_cost;
9621 }
9622
9623 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
9624 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
9625
9626 if (!comp_pred) {
9627 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
9628 best_pred_rd[SINGLE_REFERENCE] = single_rd;
9629 } else {
9630 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
9631 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
9632 }
9633 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
9634 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
9635 }
9636
Yaowu Xuc27fc142016-08-22 16:08:15 -07009637 if (x->skip && !comp_pred) break;
9638 }
9639
9640 if (xd->lossless[mbmi->segment_id] == 0 && best_mode_index >= 0 &&
9641 ((sf->tx_type_search.fast_inter_tx_type_search == 1 &&
9642 is_inter_mode(best_mbmode.mode)) ||
9643 (sf->tx_type_search.fast_intra_tx_type_search == 1 &&
9644 !is_inter_mode(best_mbmode.mode)))) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009645 int skip_blk = 0;
9646 RD_STATS rd_stats_y, rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009647
9648 x->use_default_inter_tx_type = 0;
9649 x->use_default_intra_tx_type = 0;
9650
9651 *mbmi = best_mbmode;
9652
9653 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
9654
9655 // Select prediction reference frames.
9656 for (i = 0; i < MAX_MB_PLANE; i++) {
9657 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
9658 if (has_second_ref(mbmi))
9659 xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
9660 }
9661
9662 if (is_inter_mode(mbmi->mode)) {
Yue Chen69f18e12016-09-08 14:48:15 -07009663#if CONFIG_WARPED_MOTION
9664 if (mbmi->motion_mode == WARPED_CAUSAL) {
9665 int plane;
9666#if CONFIG_AOM_HIGHBITDEPTH
9667 int use_hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
9668#endif // CONFIG_AOM_HIGHBITDEPTH
9669 assert(!has_second_ref(mbmi));
9670
9671 for (plane = 0; plane < 3; ++plane) {
9672 const struct macroblockd_plane *pd = &xd->plane[plane];
9673
9674 av1_warp_plane(&mbmi->wm_params[0],
9675#if CONFIG_AOM_HIGHBITDEPTH
9676 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
9677#endif // CONFIG_AOM_HIGHBITDEPTH
9678 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
9679 pd->pre[0].stride, pd->dst.buf,
9680 ((mi_col * MI_SIZE) >> pd->subsampling_x),
9681 ((mi_row * MI_SIZE) >> pd->subsampling_y),
9682 xd->n8_w * (8 >> pd->subsampling_x),
9683 xd->n8_h * (8 >> pd->subsampling_y), pd->dst.stride,
9684 pd->subsampling_x, pd->subsampling_y, 16, 16, 0);
9685 }
9686 } else {
9687#endif // CONFIG_WARPED_MOTION
9688 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
9689#if CONFIG_WARPED_MOTION
9690 }
9691#endif // CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07009692#if CONFIG_MOTION_VAR
9693 if (mbmi->motion_mode == OBMC_CAUSAL)
Yaowu Xuf883b422016-08-30 14:01:10 -07009694 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1,
9695 dst_stride1, dst_buf2, dst_stride2);
Yue Chencb60b182016-10-13 15:18:22 -07009696#endif // CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009697 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009698#if CONFIG_VAR_TX
9699 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
Angie Chiangb5dda482016-11-02 16:19:58 -07009700 select_tx_type_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009701 } else {
9702 int idx, idy;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009703 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009704 for (idy = 0; idy < xd->n8_h; ++idy)
9705 for (idx = 0; idx < xd->n8_w; ++idx)
9706 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009707 memset(x->blk_skip[0], rd_stats_y.skip,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009708 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
9709 }
9710
Angie Chiangb5dda482016-11-02 16:19:58 -07009711 inter_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009712#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009713 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -08009714 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009715#endif // CONFIG_VAR_TX
9716 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009717 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -08009718 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009719 }
9720
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009721 if (RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
9722 (rd_stats_y.dist + rd_stats_uv.dist)) >
9723 RDCOST(x->rdmult, x->rddiv, 0, (rd_stats_y.sse + rd_stats_uv.sse))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009724 skip_blk = 1;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009725 rd_stats_y.rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
9726 rd_stats_uv.rate = 0;
9727 rd_stats_y.dist = rd_stats_y.sse;
9728 rd_stats_uv.dist = rd_stats_uv.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009729 } else {
9730 skip_blk = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009731 rd_stats_y.rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009732 }
9733
9734 if (RDCOST(x->rdmult, x->rddiv, best_rate_y + best_rate_uv, rd_cost->dist) >
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009735 RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
9736 (rd_stats_y.dist + rd_stats_uv.dist))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009737#if CONFIG_VAR_TX
9738 int idx, idy;
9739#endif
9740 best_mbmode.tx_type = mbmi->tx_type;
9741 best_mbmode.tx_size = mbmi->tx_size;
9742#if CONFIG_VAR_TX
9743 for (idy = 0; idy < xd->n8_h; ++idy)
9744 for (idx = 0; idx < xd->n8_w; ++idx)
9745 best_mbmode.inter_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
9746
9747 for (i = 0; i < MAX_MB_PLANE; ++i)
9748 memcpy(ctx->blk_skip[i], x->blk_skip[i],
9749 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -07009750
9751 best_mbmode.min_tx_size = mbmi->min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009752#endif
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009753 rd_cost->rate +=
9754 (rd_stats_y.rate + rd_stats_uv.rate - best_rate_y - best_rate_uv);
9755 rd_cost->dist = rd_stats_y.dist + rd_stats_uv.dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009756 rd_cost->rdcost =
9757 RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
9758 best_skip2 = skip_blk;
9759 }
9760 }
9761
Urvang Joshib100db72016-10-12 16:28:56 -07009762#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009763 // Only try palette mode when the best mode so far is an intra mode.
9764 if (cm->allow_screen_content_tools && !is_inter_mode(best_mbmode.mode)) {
9765 PREDICTION_MODE mode_selected;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009766 int rate2 = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009767#if CONFIG_SUPERTX
9768 int best_rate_nocoef;
9769#endif
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009770 int64_t distortion2 = 0, dummy_rd = best_rd, this_rd;
Urvang Joshi626591d2016-10-24 14:13:55 -07009771 int skippable = 0, rate_overhead_palette = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009772 RD_STATS rd_stats_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009773 TX_SIZE best_tx_size, uv_tx;
9774 TX_TYPE best_tx_type;
9775 PALETTE_MODE_INFO palette_mode_info;
9776 uint8_t *const best_palette_color_map =
9777 x->palette_buffer->best_palette_color_map;
9778 uint8_t *const color_map = xd->plane[0].color_index_map;
9779
9780 mbmi->mode = DC_PRED;
9781 mbmi->uv_mode = DC_PRED;
9782 mbmi->ref_frame[0] = INTRA_FRAME;
9783 mbmi->ref_frame[1] = NONE;
9784 palette_mode_info.palette_size[0] = 0;
Urvang Joshi626591d2016-10-24 14:13:55 -07009785 rate_overhead_palette = rd_pick_palette_intra_sby(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009786 cpi, x, bsize, palette_ctx, intra_mode_cost[DC_PRED],
9787 &palette_mode_info, best_palette_color_map, &best_tx_size,
9788 &best_tx_type, &mode_selected, &dummy_rd);
9789 if (palette_mode_info.palette_size[0] == 0) goto PALETTE_EXIT;
9790
9791 pmi->palette_size[0] = palette_mode_info.palette_size[0];
9792 if (palette_mode_info.palette_size[0] > 0) {
9793 memcpy(pmi->palette_colors, palette_mode_info.palette_colors,
9794 PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
9795 memcpy(color_map, best_palette_color_map,
9796 rows * cols * sizeof(best_palette_color_map[0]));
9797 }
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009798 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
9799 if (rd_stats_y.rate == INT_MAX) goto PALETTE_EXIT;
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009800 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
9801 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009802 if (rate_uv_intra[uv_tx] == INT_MAX) {
9803 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -07009804 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
9805 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009806 pmi_uv[uv_tx] = *pmi;
9807#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009808 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
9809#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009810#if CONFIG_FILTER_INTRA
9811 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9812#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009813 }
9814 mbmi->uv_mode = mode_uv[uv_tx];
9815 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9816 if (pmi->palette_size[1] > 0)
9817 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9818 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9819 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9820#if CONFIG_EXT_INTRA
9821 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009822#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009823#if CONFIG_FILTER_INTRA
9824 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9825 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9826 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9827 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9828 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
9829 }
9830#endif // CONFIG_FILTER_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009831 skippable = rd_stats_y.skip && skip_uvs[uv_tx];
9832 distortion2 = rd_stats_y.dist + dist_uvs[uv_tx];
9833 rate2 = rd_stats_y.rate + rate_overhead_palette + rate_uv_intra[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009834 rate2 += ref_costs_single[INTRA_FRAME];
9835
9836 if (skippable) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009837 rate2 -= (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009838#if CONFIG_SUPERTX
9839 best_rate_nocoef = rate2;
9840#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07009841 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009842 } else {
9843#if CONFIG_SUPERTX
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009844 best_rate_nocoef = rate2 - (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009845#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07009846 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009847 }
9848 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
9849 if (this_rd < best_rd) {
9850 best_mode_index = 3;
9851 mbmi->mv[0].as_int = 0;
9852 rd_cost->rate = rate2;
9853#if CONFIG_SUPERTX
9854 *returnrate_nocoef = best_rate_nocoef;
9855#endif
9856 rd_cost->dist = distortion2;
9857 rd_cost->rdcost = this_rd;
9858 best_rd = this_rd;
9859 best_mbmode = *mbmi;
9860 best_skip2 = 0;
9861 best_mode_skippable = skippable;
9862 }
9863 }
9864PALETTE_EXIT:
Urvang Joshib100db72016-10-12 16:28:56 -07009865#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009866
hui su5db97432016-10-14 16:10:14 -07009867#if CONFIG_FILTER_INTRA
9868 // TODO(huisu): filter-intra is turned off in lossless mode for now to
Yaowu Xuc27fc142016-08-22 16:08:15 -07009869 // avoid a unit test failure
hui su5db97432016-10-14 16:10:14 -07009870 if (!xd->lossless[mbmi->segment_id] &&
Urvang Joshib100db72016-10-12 16:28:56 -07009871#if CONFIG_PALETTE
9872 mbmi->palette_mode_info.palette_size[0] == 0 &&
9873#endif // CONFIG_PALETTE
9874 !dc_skipped && best_mode_index >= 0 &&
9875 best_intra_rd < (best_rd + (best_rd >> 3))) {
hui su5db97432016-10-14 16:10:14 -07009876 pick_filter_intra_interframe(
Urvang Joshi368fbc92016-10-17 16:31:34 -07009877 cpi, x, ctx, bsize, rate_uv_intra, rate_uv_tokenonly, dist_uvs,
hui su5db97432016-10-14 16:10:14 -07009878 skip_uvs, mode_uv, filter_intra_mode_info_uv,
9879#if CONFIG_EXT_INTRA
9880 uv_angle_delta,
9881#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07009882#if CONFIG_PALETTE
9883 pmi_uv, palette_ctx,
9884#endif // CONFIG_PALETTE
9885 0, ref_costs_single, &best_rd, &best_intra_rd, &best_intra_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009886 &best_mode_index, &best_skip2, &best_mode_skippable,
9887#if CONFIG_SUPERTX
9888 returnrate_nocoef,
9889#endif // CONFIG_SUPERTX
9890 best_pred_rd, &best_mbmode, rd_cost);
9891 }
hui su5db97432016-10-14 16:10:14 -07009892#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009893
9894 // The inter modes' rate costs are not calculated precisely in some cases.
9895 // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
9896 // ZEROMV. Here, checks are added for those cases, and the mode decisions
9897 // are corrected.
9898 if (best_mbmode.mode == NEWMV
9899#if CONFIG_EXT_INTER
9900 || best_mbmode.mode == NEWFROMNEARMV || best_mbmode.mode == NEW_NEWMV
9901#endif // CONFIG_EXT_INTER
9902 ) {
9903 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
9904 best_mbmode.ref_frame[1] };
9905 int comp_pred_mode = refs[1] > INTRA_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -07009906 int_mv zeromv[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009907#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07009908 const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame);
Sarah Parkere5299862016-08-16 14:57:37 -07009909#endif // CONFIG_REF_MV
9910#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +00009911 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
9912 cm->allow_high_precision_mv)
9913 .as_int;
9914 zeromv[1].as_int = comp_pred_mode
9915 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
9916 cm->allow_high_precision_mv)
9917 .as_int
9918 : 0;
Sarah Parkere5299862016-08-16 14:57:37 -07009919#else
9920 zeromv[0].as_int = 0;
9921 zeromv[1].as_int = 0;
9922#endif // CONFIG_GLOBAL_MOTION
9923#if CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07009924 if (!comp_pred_mode) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009925 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -07009926 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009927 : INT_MAX;
9928
9929 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
9930 int_mv cur_mv = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
9931 if (cur_mv.as_int == best_mbmode.mv[0].as_int) {
9932 best_mbmode.mode = NEARMV;
9933 best_mbmode.ref_mv_idx = i;
9934 }
9935 }
9936
9937 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
9938 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -07009939 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009940 best_mbmode.mode = ZEROMV;
9941 } else {
9942 int_mv nearestmv[2];
9943 int_mv nearmv[2];
9944
9945#if CONFIG_EXT_INTER
9946 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
9947 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][1].this_mv;
9948 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][1].comp_mv;
9949 } else {
9950 nearmv[0] = frame_mv[NEARMV][refs[0]];
9951 nearmv[1] = frame_mv[NEARMV][refs[1]];
9952 }
9953#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009954 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -07009955 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009956 : INT_MAX;
9957
9958 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
9959 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
9960 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
9961
9962 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
9963 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
9964 best_mbmode.mode = NEARMV;
9965 best_mbmode.ref_mv_idx = i;
9966 }
9967 }
9968#endif
9969 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
9970 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
9971 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
9972 } else {
9973 nearestmv[0] = frame_mv[NEARESTMV][refs[0]];
9974 nearestmv[1] = frame_mv[NEARESTMV][refs[1]];
9975 }
9976
9977 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
9978 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
9979#if CONFIG_EXT_INTER
9980 best_mbmode.mode = NEAREST_NEARESTMV;
9981 else if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
9982 nearmv[1].as_int == best_mbmode.mv[1].as_int)
9983 best_mbmode.mode = NEAREST_NEARMV;
9984 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
9985 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
9986 best_mbmode.mode = NEAR_NEARESTMV;
9987 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
9988 nearmv[1].as_int == best_mbmode.mv[1].as_int)
9989 best_mbmode.mode = NEAR_NEARMV;
9990 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
9991 best_mbmode.mode = ZERO_ZEROMV;
9992#else
9993 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -07009994 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
9995 best_mbmode.mv[1].as_int == zeromv[1].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009996 best_mbmode.mode = ZEROMV;
9997#endif // CONFIG_EXT_INTER
9998 }
9999#else
10000#if CONFIG_EXT_INTER
10001 if (!comp_pred_mode) {
10002#endif // CONFIG_EXT_INTER
10003 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
10004 ((comp_pred_mode &&
10005 frame_mv[NEARESTMV][refs[1]].as_int == best_mbmode.mv[1].as_int) ||
10006 !comp_pred_mode))
10007 best_mbmode.mode = NEARESTMV;
10008 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
10009 ((comp_pred_mode &&
10010 frame_mv[NEARMV][refs[1]].as_int ==
10011 best_mbmode.mv[1].as_int) ||
10012 !comp_pred_mode))
10013 best_mbmode.mode = NEARMV;
Sarah Parkere5299862016-08-16 14:57:37 -070010014 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
10015 ((comp_pred_mode &&
10016 best_mbmode.mv[1].as_int == zeromv[1].as_int) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -070010017 !comp_pred_mode))
10018 best_mbmode.mode = ZEROMV;
10019#if CONFIG_EXT_INTER
10020 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010021 if (frame_mv[NEAREST_NEARESTMV][refs[0]].as_int ==
10022 best_mbmode.mv[0].as_int &&
10023 frame_mv[NEAREST_NEARESTMV][refs[1]].as_int ==
10024 best_mbmode.mv[1].as_int)
10025 best_mbmode.mode = NEAREST_NEARESTMV;
10026 else if (frame_mv[NEAREST_NEARMV][refs[0]].as_int ==
10027 best_mbmode.mv[0].as_int &&
10028 frame_mv[NEAREST_NEARMV][refs[1]].as_int ==
10029 best_mbmode.mv[1].as_int)
10030 best_mbmode.mode = NEAREST_NEARMV;
10031 else if (frame_mv[NEAR_NEARESTMV][refs[0]].as_int ==
10032 best_mbmode.mv[0].as_int &&
10033 frame_mv[NEAR_NEARESTMV][refs[1]].as_int ==
10034 best_mbmode.mv[1].as_int)
10035 best_mbmode.mode = NEAR_NEARESTMV;
10036 else if (frame_mv[NEAR_NEARMV][refs[0]].as_int ==
10037 best_mbmode.mv[0].as_int &&
10038 frame_mv[NEAR_NEARMV][refs[1]].as_int ==
10039 best_mbmode.mv[1].as_int)
10040 best_mbmode.mode = NEAR_NEARMV;
10041 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
10042 best_mbmode.mode = ZERO_ZEROMV;
10043 }
10044#endif // CONFIG_EXT_INTER
10045#endif
10046 }
10047
10048#if CONFIG_REF_MV
David Barkercdcac6d2016-12-01 17:04:16 +000010049 {
Jingning Han731af492016-11-17 11:53:23 -080010050 int8_t ref_frame_type = av1_ref_frame_type(best_mbmode.ref_frame);
10051 int16_t mode_ctx = mbmi_ext->mode_context[ref_frame_type];
David Barker68e6e862016-11-24 15:10:15 +000010052 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) {
David Barkercdcac6d2016-12-01 17:04:16 +000010053 int_mv zeromv[2];
David Barker68e6e862016-11-24 15:10:15 +000010054#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +000010055 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
10056 best_mbmode.ref_frame[1] };
10057 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
10058 cm->allow_high_precision_mv)
10059 .as_int;
10060 zeromv[1].as_int = gm_get_motion_vector(&cm->global_motion[refs[1]],
10061 cm->allow_high_precision_mv)
10062 .as_int;
10063 lower_mv_precision(&zeromv[0].as_mv, cm->allow_high_precision_mv);
10064 lower_mv_precision(&zeromv[1].as_mv, cm->allow_high_precision_mv);
10065#else
10066 zeromv[0].as_int = zeromv[1].as_int = 0;
10067#endif // CONFIG_GLOBAL_MOTION
10068 if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
10069 best_mbmode.mv[0].as_int == zeromv[0].as_int &&
10070#if CONFIG_EXT_INTER
10071 (best_mbmode.ref_frame[1] <= INTRA_FRAME)
10072#else
10073 (best_mbmode.ref_frame[1] == NONE ||
10074 best_mbmode.mv[1].as_int == zeromv[1].as_int)
10075#endif // CONFIG_EXT_INTER
10076 ) {
10077 best_mbmode.mode = ZEROMV;
10078 }
David Barker68e6e862016-11-24 15:10:15 +000010079 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010080 }
10081#endif
10082
10083 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
10084 rd_cost->rate = INT_MAX;
10085 rd_cost->rdcost = INT64_MAX;
10086 return;
10087 }
10088
Yaowu Xuc27fc142016-08-22 16:08:15 -070010089#if CONFIG_DUAL_FILTER
10090 assert((cm->interp_filter == SWITCHABLE) ||
10091 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
10092 !is_inter_block(&best_mbmode));
10093 assert((cm->interp_filter == SWITCHABLE) ||
10094 (cm->interp_filter == best_mbmode.interp_filter[1]) ||
10095 !is_inter_block(&best_mbmode));
10096 if (best_mbmode.ref_frame[1] > INTRA_FRAME) {
10097 assert((cm->interp_filter == SWITCHABLE) ||
10098 (cm->interp_filter == best_mbmode.interp_filter[2]) ||
10099 !is_inter_block(&best_mbmode));
10100 assert((cm->interp_filter == SWITCHABLE) ||
10101 (cm->interp_filter == best_mbmode.interp_filter[3]) ||
10102 !is_inter_block(&best_mbmode));
10103 }
10104#else
10105 assert((cm->interp_filter == SWITCHABLE) ||
10106 (cm->interp_filter == best_mbmode.interp_filter) ||
10107 !is_inter_block(&best_mbmode));
10108#endif
10109
10110 if (!cpi->rc.is_src_frame_alt_ref)
Yaowu Xuf883b422016-08-30 14:01:10 -070010111 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
10112 sf->adaptive_rd_thresh, bsize, best_mode_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010113
10114 // macroblock modes
10115 *mbmi = best_mbmode;
10116 x->skip |= best_skip2;
10117
10118#if CONFIG_REF_MV
10119 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
10120 if (mbmi->mode != NEWMV)
10121 mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
10122 else
10123 mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
10124 }
10125#endif
10126
10127 for (i = 0; i < REFERENCE_MODES; ++i) {
10128 if (best_pred_rd[i] == INT64_MAX)
10129 best_pred_diff[i] = INT_MIN;
10130 else
10131 best_pred_diff[i] = best_rd - best_pred_rd[i];
10132 }
10133
10134 x->skip |= best_mode_skippable;
10135
10136 assert(best_mode_index >= 0);
10137
10138 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
10139 best_mode_skippable);
10140
Urvang Joshib100db72016-10-12 16:28:56 -070010141#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010142 if (cm->allow_screen_content_tools && pmi->palette_size[1] > 0) {
10143 restore_uv_color_map(cpi, x);
10144 }
Urvang Joshib100db72016-10-12 16:28:56 -070010145#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010146}
10147
Urvang Joshi52648442016-10-13 17:27:51 -070010148void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
10149 TileDataEnc *tile_data, MACROBLOCK *x,
10150 RD_COST *rd_cost, BLOCK_SIZE bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -070010151 PICK_MODE_CONTEXT *ctx,
10152 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070010153 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010154 MACROBLOCKD *const xd = &x->e_mbd;
10155 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
10156 unsigned char segment_id = mbmi->segment_id;
10157 const int comp_pred = 0;
10158 int i;
10159 int64_t best_pred_diff[REFERENCE_MODES];
10160 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
10161 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070010162 aom_prob comp_mode_p;
James Zern7b9407a2016-05-18 23:48:05 -070010163 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010164 int64_t this_rd = INT64_MAX;
10165 int rate2 = 0;
10166 const int64_t distortion2 = 0;
10167
10168 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
10169 &comp_mode_p);
10170
10171 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
10172 for (i = LAST_FRAME; i < TOTAL_REFS_PER_FRAME; ++i)
10173 x->pred_mv_sad[i] = INT_MAX;
10174
10175 rd_cost->rate = INT_MAX;
10176
10177 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
10178
Urvang Joshib100db72016-10-12 16:28:56 -070010179#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010180 mbmi->palette_mode_info.palette_size[0] = 0;
10181 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070010182#endif // CONFIG_PALETTE
10183
hui su5db97432016-10-14 16:10:14 -070010184#if CONFIG_FILTER_INTRA
10185 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10186 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10187#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010188 mbmi->mode = ZEROMV;
Yue Chencb60b182016-10-13 15:18:22 -070010189 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010190 mbmi->uv_mode = DC_PRED;
10191 mbmi->ref_frame[0] = LAST_FRAME;
10192 mbmi->ref_frame[1] = NONE;
Sarah Parkere5299862016-08-16 14:57:37 -070010193#if CONFIG_GLOBAL_MOTION
10194 mbmi->mv[0].as_int =
David Barkercdcac6d2016-12-01 17:04:16 +000010195 gm_get_motion_vector(&cm->global_motion[mbmi->ref_frame[0]],
10196 cm->allow_high_precision_mv)
10197 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -070010198#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010199 mbmi->mv[0].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -070010200#endif // CONFIG_GLOBAL_MOTION
Jingning Han64088952016-07-11 11:24:24 -070010201 mbmi->tx_size = max_txsize_lookup[bsize];
Yaowu Xuee775b12016-10-18 10:00:21 -070010202 x->skip = 1;
Sarah Parkere5299862016-08-16 14:57:37 -070010203
Yaowu Xuc27fc142016-08-22 16:08:15 -070010204#if CONFIG_REF_MV
10205 mbmi->ref_mv_idx = 0;
10206 mbmi->pred_mv[0].as_int = 0;
10207#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010208
10209 if (cm->interp_filter != BILINEAR) {
10210 best_filter = EIGHTTAP_REGULAR;
10211 if (cm->interp_filter == SWITCHABLE &&
10212#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -070010213 av1_is_interp_needed(xd) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010214#endif // CONFIG_EXT_INTERP
10215 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
10216 int rs;
10217 int best_rs = INT_MAX;
10218 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
10219#if CONFIG_DUAL_FILTER
10220 int k;
10221 for (k = 0; k < 4; ++k) mbmi->interp_filter[k] = i;
10222#else
10223 mbmi->interp_filter = i;
10224#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070010225 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010226 if (rs < best_rs) {
10227 best_rs = rs;
10228#if CONFIG_DUAL_FILTER
10229 best_filter = mbmi->interp_filter[0];
10230#else
10231 best_filter = mbmi->interp_filter;
10232#endif
10233 }
10234 }
10235 }
10236 }
10237 // Set the appropriate filter
10238 if (cm->interp_filter == SWITCHABLE) {
10239#if CONFIG_DUAL_FILTER
10240 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = best_filter;
10241#else
10242 mbmi->interp_filter = best_filter;
10243#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070010244 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010245 } else {
10246#if CONFIG_DUAL_FILTER
10247 for (i = 0; i < 4; ++i) mbmi->interp_filter[0] = cm->interp_filter;
10248#else
10249 mbmi->interp_filter = cm->interp_filter;
10250#endif
10251 }
10252
10253 if (cm->reference_mode == REFERENCE_MODE_SELECT)
Yaowu Xuf883b422016-08-30 14:01:10 -070010254 rate2 += av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010255
10256 // Estimate the reference frame signaling cost and add it
10257 // to the rolling cost variable.
10258 rate2 += ref_costs_single[LAST_FRAME];
10259 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10260
10261 rd_cost->rate = rate2;
10262 rd_cost->dist = distortion2;
10263 rd_cost->rdcost = this_rd;
10264
10265 if (this_rd >= best_rd_so_far) {
10266 rd_cost->rate = INT_MAX;
10267 rd_cost->rdcost = INT64_MAX;
10268 return;
10269 }
10270
10271#if CONFIG_DUAL_FILTER
10272 assert((cm->interp_filter == SWITCHABLE) ||
10273 (cm->interp_filter == mbmi->interp_filter[0]));
10274#else
10275 assert((cm->interp_filter == SWITCHABLE) ||
10276 (cm->interp_filter == mbmi->interp_filter));
10277#endif
10278
Yaowu Xuf883b422016-08-30 14:01:10 -070010279 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
10280 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010281
Yaowu Xuf883b422016-08-30 14:01:10 -070010282 av1_zero(best_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010283
10284 store_coding_context(x, ctx, THR_ZEROMV, best_pred_diff, 0);
10285}
10286
Urvang Joshi52648442016-10-13 17:27:51 -070010287void av1_rd_pick_inter_mode_sub8x8(const struct AV1_COMP *cpi,
10288 TileDataEnc *tile_data, struct macroblock *x,
10289 int mi_row, int mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -070010290 struct RD_COST *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010291#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010292 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010293#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010294 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
10295 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070010296 const AV1_COMMON *const cm = &cpi->common;
10297 const RD_OPT *const rd_opt = &cpi->rd;
10298 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010299 MACROBLOCKD *const xd = &x->e_mbd;
10300 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
10301 const struct segmentation *const seg = &cm->seg;
10302 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
10303 unsigned char segment_id = mbmi->segment_id;
10304 int comp_pred, i;
10305 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
10306 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
10307 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
10308 0,
Yaowu Xuf883b422016-08-30 14:01:10 -070010309 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010310#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070010311 AOM_LAST2_FLAG,
10312 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010313#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070010314 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010315#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070010316 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010317#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070010318 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -070010319 };
10320 int64_t best_rd = best_rd_so_far;
10321 int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
10322 int64_t best_pred_diff[REFERENCE_MODES];
10323 int64_t best_pred_rd[REFERENCE_MODES];
10324 MB_MODE_INFO best_mbmode;
10325 int ref_index, best_ref_index = 0;
10326 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
10327 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070010328 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010329#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -070010330 InterpFilter tmp_best_filter[4] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -070010331#else
James Zern7b9407a2016-05-18 23:48:05 -070010332 InterpFilter tmp_best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010333#endif
Jingning Han3f167252016-06-07 16:11:42 -070010334 int rate_uv_intra, rate_uv_tokenonly = INT_MAX;
10335 int64_t dist_uv = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010336 int skip_uv;
10337 PREDICTION_MODE mode_uv = DC_PRED;
Yaowu Xuf883b422016-08-30 14:01:10 -070010338 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -070010339 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
10340#if CONFIG_EXT_INTER
10341 int_mv seg_mvs[4][2][TOTAL_REFS_PER_FRAME];
10342#else
10343 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME];
10344#endif // CONFIG_EXT_INTER
10345 b_mode_info best_bmodes[4];
10346 int best_skip2 = 0;
10347 int ref_frame_skip_mask[2] = { 0 };
10348 int internal_active_edge =
Yaowu Xuf883b422016-08-30 14:01:10 -070010349 av1_active_edge_sb(cpi, mi_row, mi_col) && av1_internal_image_edge(cpi);
Yushin Cho77bba8d2016-11-04 16:36:56 -070010350#if CONFIG_PVQ
10351 od_rollback_buffer pre_buf;
10352
10353 od_encode_checkpoint(&x->daala_enc, &pre_buf);
10354#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010355
10356#if CONFIG_SUPERTX
10357 best_rd_so_far = INT64_MAX;
10358 best_rd = best_rd_so_far;
10359 best_yrd = best_rd_so_far;
10360#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010361 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010362
hui su5db97432016-10-14 16:10:14 -070010363#if CONFIG_FILTER_INTRA
10364 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10365 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10366#endif // CONFIG_FILTER_INTRA
Yue Chencb60b182016-10-13 15:18:22 -070010367 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010368#if CONFIG_EXT_INTER
Sarah Parker6fdc8532016-11-16 17:47:13 -080010369 mbmi->interinter_compound_data.type = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010370 mbmi->use_wedge_interintra = 0;
10371#endif // CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -070010372#if CONFIG_WARPED_MOTION
10373 mbmi->num_proj_ref[0] = 0;
10374 mbmi->num_proj_ref[1] = 0;
10375#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010376
10377 for (i = 0; i < 4; i++) {
10378 int j;
10379#if CONFIG_EXT_INTER
10380 int k;
10381
10382 for (k = 0; k < 2; k++)
10383 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
10384 seg_mvs[i][k][j].as_int = INVALID_MV;
10385#else
10386 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
10387 seg_mvs[i][j].as_int = INVALID_MV;
10388#endif // CONFIG_EXT_INTER
10389 }
10390
10391 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
10392 &comp_mode_p);
10393
10394 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
10395 rate_uv_intra = INT_MAX;
10396
10397 rd_cost->rate = INT_MAX;
10398#if CONFIG_SUPERTX
10399 *returnrate_nocoef = INT_MAX;
10400#endif
10401
10402 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
10403 x->mbmi_ext->mode_context[ref_frame] = 0;
10404#if CONFIG_REF_MV && CONFIG_EXT_INTER
10405 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
10406#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
10407 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
10408 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
10409 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
10410 } else {
10411 ref_frame_skip_mask[0] |= (1 << ref_frame);
10412 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10413 }
10414 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
10415#if CONFIG_EXT_INTER
10416 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
10417#endif // CONFIG_EXT_INTER
10418 frame_mv[ZEROMV][ref_frame].as_int = 0;
10419 }
10420
Urvang Joshib100db72016-10-12 16:28:56 -070010421#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010422 mbmi->palette_mode_info.palette_size[0] = 0;
10423 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070010424#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010425
10426 for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
10427 int mode_excluded = 0;
10428 int64_t this_rd = INT64_MAX;
10429 int disable_skip = 0;
10430 int compmode_cost = 0;
10431 int rate2 = 0, rate_y = 0, rate_uv = 0;
10432 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
10433 int skippable = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010434 int this_skip2 = 0;
10435 int64_t total_sse = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010436
Yushin Cho77bba8d2016-11-04 16:36:56 -070010437#if CONFIG_PVQ
10438 od_encode_rollback(&x->daala_enc, &pre_buf);
10439#endif
10440
Yaowu Xuf883b422016-08-30 14:01:10 -070010441 ref_frame = av1_ref_order[ref_index].ref_frame[0];
10442 second_ref_frame = av1_ref_order[ref_index].ref_frame[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010443
Yaowu Xu4306b6e2016-09-27 12:55:32 -070010444#if CONFIG_REF_MV
10445 mbmi->ref_mv_idx = 0;
10446#endif
10447
Yaowu Xuc27fc142016-08-22 16:08:15 -070010448 // Look at the reference frame of the best mode so far and set the
10449 // skip mask to look at a subset of the remaining modes.
10450 if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
10451 if (ref_index == 3) {
10452 switch (best_mbmode.ref_frame[0]) {
10453 case INTRA_FRAME: break;
10454 case LAST_FRAME:
10455 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
10456#if CONFIG_EXT_REFS
10457 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
10458 (1 << BWDREF_FRAME) |
10459#endif // CONFIG_EXT_REFS
10460 (1 << ALTREF_FRAME);
10461 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10462 break;
10463#if CONFIG_EXT_REFS
10464 case LAST2_FRAME:
10465 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST3_FRAME) |
10466 (1 << GOLDEN_FRAME) |
10467 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
10468 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10469 break;
10470 case LAST3_FRAME:
10471 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
10472 (1 << GOLDEN_FRAME) |
10473 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
10474 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10475 break;
10476#endif // CONFIG_EXT_REFS
10477 case GOLDEN_FRAME:
10478 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
10479#if CONFIG_EXT_REFS
10480 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
10481 (1 << BWDREF_FRAME) |
10482#endif // CONFIG_EXT_REFS
10483 (1 << ALTREF_FRAME);
10484 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10485 break;
10486#if CONFIG_EXT_REFS
10487 case BWDREF_FRAME:
10488 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
10489 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) |
10490 (1 << ALTREF_FRAME);
10491 ref_frame_skip_mask[1] |= (1 << ALTREF_FRAME) | 0x01;
10492 break;
10493#endif // CONFIG_EXT_REFS
10494 case ALTREF_FRAME:
10495 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
10496#if CONFIG_EXT_REFS
10497 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
10498 (1 << BWDREF_FRAME) |
10499#endif // CONFIG_EXT_REFS
10500 (1 << GOLDEN_FRAME);
10501#if CONFIG_EXT_REFS
10502 ref_frame_skip_mask[1] |= (1 << BWDREF_FRAME) | 0x01;
10503#endif // CONFIG_EXT_REFS
10504 break;
10505 case NONE:
10506 case TOTAL_REFS_PER_FRAME:
10507 assert(0 && "Invalid Reference frame");
10508 break;
10509 }
10510 }
10511 }
10512
10513 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010514 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010515 continue;
10516
10517 // Test best rd so far against threshold for trying this mode.
10518 if (!internal_active_edge &&
10519 rd_less_than_thresh(best_rd,
10520 rd_opt->threshes[segment_id][bsize][ref_index],
10521 tile_data->thresh_freq_fact[bsize][ref_index]))
10522 continue;
10523
10524 comp_pred = second_ref_frame > INTRA_FRAME;
10525 if (comp_pred) {
10526 if (!cpi->allow_comp_inter_inter) continue;
10527 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
10528 // Do not allow compound prediction if the segment level reference frame
10529 // feature is in use as in this case there can only be one reference.
10530 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
10531
10532 if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
10533 best_mbmode.ref_frame[0] == INTRA_FRAME)
10534 continue;
10535 }
10536
10537 // TODO(jingning, jkoleszar): scaling reference frame not supported for
10538 // sub8x8 blocks.
10539 if (ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010540 av1_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010541 continue;
10542
10543 if (second_ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010544 av1_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010545 continue;
10546
10547 if (comp_pred)
10548 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
10549 else if (ref_frame != INTRA_FRAME)
10550 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
10551
10552 // If the segment reference frame feature is enabled....
10553 // then do nothing if the current ref frame is not allowed..
10554 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
10555 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
10556 continue;
10557 // Disable this drop out case if the ref frame
10558 // segment level feature is enabled for this segment. This is to
10559 // prevent the possibility that we end up unable to pick any mode.
10560 } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
10561 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
10562 // unless ARNR filtering is enabled in which case we want
10563 // an unfiltered alternative. We allow near/nearest as well
10564 // because they may result in zero-zero MVs but be cheaper.
10565 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
10566 continue;
10567 }
10568
10569 mbmi->tx_size = TX_4X4;
10570 mbmi->uv_mode = DC_PRED;
10571 mbmi->ref_frame[0] = ref_frame;
10572 mbmi->ref_frame[1] = second_ref_frame;
10573// Evaluate all sub-pel filters irrespective of whether we can use
10574// them for this frame.
10575#if CONFIG_DUAL_FILTER
10576 for (i = 0; i < 4; ++i)
10577 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
10578 ? EIGHTTAP_REGULAR
10579 : cm->interp_filter;
10580#else
10581 mbmi->interp_filter =
10582 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
10583#endif
10584 x->skip = 0;
10585 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
10586
10587 // Select prediction reference frames.
10588 for (i = 0; i < MAX_MB_PLANE; i++) {
10589 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
10590 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
10591 }
10592
10593#if CONFIG_VAR_TX
10594 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -070010595 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010596#endif
10597
10598 if (ref_frame == INTRA_FRAME) {
10599 int rate;
10600 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y, &distortion_y,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -070010601 NULL, best_rd) >= best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010602 continue;
10603 rate2 += rate;
10604 rate2 += intra_cost_penalty;
10605 distortion2 += distortion_y;
10606
10607 if (rate_uv_intra == INT_MAX) {
10608 choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4, &rate_uv_intra,
10609 &rate_uv_tokenonly, &dist_uv, &skip_uv, &mode_uv);
10610 }
10611 rate2 += rate_uv_intra;
10612 rate_uv = rate_uv_tokenonly;
10613 distortion2 += dist_uv;
10614 distortion_uv = dist_uv;
10615 mbmi->uv_mode = mode_uv;
10616 } else {
10617 int rate;
10618 int64_t distortion;
10619 int64_t this_rd_thresh;
10620 int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
10621 int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
10622 int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
10623 int tmp_best_skippable = 0;
10624 int switchable_filter_index;
10625 int_mv *second_ref =
10626 comp_pred ? &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL;
10627 b_mode_info tmp_best_bmodes[16]; // Should this be 4 ?
10628 MB_MODE_INFO tmp_best_mbmode;
10629#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080010630 BEST_SEG_INFO bsi[DUAL_FILTER_SET_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010631#else
10632 BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
10633#endif
10634 int pred_exists = 0;
10635 int uv_skippable;
10636#if CONFIG_EXT_INTER
10637 int_mv compound_seg_newmvs[4][2];
10638 for (i = 0; i < 4; i++) {
10639 compound_seg_newmvs[i][0].as_int = INVALID_MV;
10640 compound_seg_newmvs[i][1].as_int = INVALID_MV;
10641 }
10642#endif // CONFIG_EXT_INTER
10643
10644 this_rd_thresh = (ref_frame == LAST_FRAME)
10645 ? rd_opt->threshes[segment_id][bsize][THR_LAST]
10646 : rd_opt->threshes[segment_id][bsize][THR_ALTR];
10647#if CONFIG_EXT_REFS
10648 this_rd_thresh = (ref_frame == LAST2_FRAME)
10649 ? rd_opt->threshes[segment_id][bsize][THR_LAST2]
10650 : this_rd_thresh;
10651 this_rd_thresh = (ref_frame == LAST3_FRAME)
10652 ? rd_opt->threshes[segment_id][bsize][THR_LAST3]
10653 : this_rd_thresh;
Zoe Liua6a6dd52016-10-18 13:03:12 -070010654 this_rd_thresh = (ref_frame == BWDREF_FRAME)
10655 ? rd_opt->threshes[segment_id][bsize][THR_BWDR]
10656 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010657#endif // CONFIG_EXT_REFS
10658 this_rd_thresh = (ref_frame == GOLDEN_FRAME)
10659 ? rd_opt->threshes[segment_id][bsize][THR_GOLD]
10660 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010661
10662 // TODO(any): Add search of the tx_type to improve rd performance at the
10663 // expense of speed.
10664 mbmi->tx_type = DCT_DCT;
10665
10666 if (cm->interp_filter != BILINEAR) {
10667#if CONFIG_DUAL_FILTER
10668 tmp_best_filter[0] = EIGHTTAP_REGULAR;
10669 tmp_best_filter[1] = EIGHTTAP_REGULAR;
10670 tmp_best_filter[2] = EIGHTTAP_REGULAR;
10671 tmp_best_filter[3] = EIGHTTAP_REGULAR;
10672#else
10673 tmp_best_filter = EIGHTTAP_REGULAR;
10674#endif
10675 if (x->source_variance < sf->disable_filter_search_var_thresh) {
10676#if CONFIG_DUAL_FILTER
10677 tmp_best_filter[0] = EIGHTTAP_REGULAR;
10678#else
10679 tmp_best_filter = EIGHTTAP_REGULAR;
10680#endif
10681 } else if (sf->adaptive_pred_interp_filter == 1 &&
10682 ctx->pred_interp_filter < SWITCHABLE) {
10683#if CONFIG_DUAL_FILTER
10684 tmp_best_filter[0] = ctx->pred_interp_filter;
10685#else
10686 tmp_best_filter = ctx->pred_interp_filter;
10687#endif
10688 } else if (sf->adaptive_pred_interp_filter == 2) {
10689#if CONFIG_DUAL_FILTER
10690 tmp_best_filter[0] = ctx->pred_interp_filter < SWITCHABLE
10691 ? ctx->pred_interp_filter
10692 : 0;
10693#else
10694 tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE
10695 ? ctx->pred_interp_filter
10696 : 0;
10697#endif
10698 } else {
10699#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080010700 const int filter_set_size = DUAL_FILTER_SET_SIZE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010701#else
Angie Chiang5678ad92016-11-21 09:38:40 -080010702 const int filter_set_size = SWITCHABLE_FILTERS;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010703#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010704 for (switchable_filter_index = 0;
Angie Chiang5678ad92016-11-21 09:38:40 -080010705 switchable_filter_index < filter_set_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010706 ++switchable_filter_index) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010707 int newbest, rs;
10708 int64_t rs_rd;
10709 MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
10710#if CONFIG_DUAL_FILTER
10711 mbmi->interp_filter[0] = filter_sets[switchable_filter_index][0];
10712 mbmi->interp_filter[1] = filter_sets[switchable_filter_index][1];
10713 mbmi->interp_filter[2] = filter_sets[switchable_filter_index][0];
10714 mbmi->interp_filter[3] = filter_sets[switchable_filter_index][1];
10715#else
10716 mbmi->interp_filter = switchable_filter_index;
10717#endif
10718 tmp_rd = rd_pick_best_sub8x8_mode(
10719 cpi, x, &mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
10720 &rate, &rate_y, &distortion, &skippable, &total_sse,
10721 (int)this_rd_thresh, seg_mvs,
10722#if CONFIG_EXT_INTER
10723 compound_seg_newmvs,
10724#endif // CONFIG_EXT_INTER
10725 bsi, switchable_filter_index, mi_row, mi_col);
10726#if CONFIG_EXT_INTERP
10727#if CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070010728 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010729 (mbmi->interp_filter[0] != EIGHTTAP_REGULAR ||
10730 mbmi->interp_filter[1] != EIGHTTAP_REGULAR)) // invalid config
10731 continue;
10732#else
Yaowu Xuf883b422016-08-30 14:01:10 -070010733 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010734 mbmi->interp_filter != EIGHTTAP_REGULAR) // invalid config
10735 continue;
10736#endif
10737#endif // CONFIG_EXT_INTERP
10738 if (tmp_rd == INT64_MAX) continue;
Yaowu Xuf883b422016-08-30 14:01:10 -070010739 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010740 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
10741 if (cm->interp_filter == SWITCHABLE) tmp_rd += rs_rd;
10742
10743 newbest = (tmp_rd < tmp_best_rd);
10744 if (newbest) {
10745#if CONFIG_DUAL_FILTER
10746 tmp_best_filter[0] = mbmi->interp_filter[0];
10747 tmp_best_filter[1] = mbmi->interp_filter[1];
10748 tmp_best_filter[2] = mbmi->interp_filter[2];
10749 tmp_best_filter[3] = mbmi->interp_filter[3];
10750#else
10751 tmp_best_filter = mbmi->interp_filter;
10752#endif
10753 tmp_best_rd = tmp_rd;
10754 }
10755 if ((newbest && cm->interp_filter == SWITCHABLE) ||
10756 (
10757#if CONFIG_DUAL_FILTER
10758 mbmi->interp_filter[0] == cm->interp_filter
10759#else
10760 mbmi->interp_filter == cm->interp_filter
10761#endif
10762 && cm->interp_filter != SWITCHABLE)) {
10763 tmp_best_rdu = tmp_rd;
10764 tmp_best_rate = rate;
10765 tmp_best_ratey = rate_y;
10766 tmp_best_distortion = distortion;
10767 tmp_best_sse = total_sse;
10768 tmp_best_skippable = skippable;
10769 tmp_best_mbmode = *mbmi;
10770 for (i = 0; i < 4; i++) {
10771 tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
10772 }
10773 pred_exists = 1;
10774 }
10775 } // switchable_filter_index loop
10776 }
10777 }
10778
10779 if (tmp_best_rdu == INT64_MAX && pred_exists) continue;
10780
10781#if CONFIG_DUAL_FILTER
10782 mbmi->interp_filter[0] =
10783 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[0]
10784 : cm->interp_filter);
10785 mbmi->interp_filter[1] =
10786 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[1]
10787 : cm->interp_filter);
10788 mbmi->interp_filter[2] =
10789 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[2]
10790 : cm->interp_filter);
10791 mbmi->interp_filter[3] =
10792 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[3]
10793 : cm->interp_filter);
10794#else
10795 mbmi->interp_filter =
10796 (cm->interp_filter == SWITCHABLE ? tmp_best_filter
10797 : cm->interp_filter);
10798#endif
10799
10800 if (!pred_exists) {
10801 // Handles the special case when a filter that is not in the
10802 // switchable list (bilinear) is indicated at the frame level
10803 tmp_rd = rd_pick_best_sub8x8_mode(
10804 cpi, x, &x->mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
10805 &rate, &rate_y, &distortion, &skippable, &total_sse,
10806 (int)this_rd_thresh, seg_mvs,
10807#if CONFIG_EXT_INTER
10808 compound_seg_newmvs,
10809#endif // CONFIG_EXT_INTER
10810 bsi, 0, mi_row, mi_col);
10811#if CONFIG_EXT_INTERP
10812#if CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070010813 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010814 (mbmi->interp_filter[0] != EIGHTTAP_REGULAR ||
10815 mbmi->interp_filter[1] != EIGHTTAP_REGULAR)) {
10816 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
10817 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
10818 }
10819#else
Yaowu Xuf883b422016-08-30 14:01:10 -070010820 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010821 mbmi->interp_filter != EIGHTTAP_REGULAR)
10822 mbmi->interp_filter = EIGHTTAP_REGULAR;
10823#endif // CONFIG_DUAL_FILTER
10824#endif // CONFIG_EXT_INTERP
10825 if (tmp_rd == INT64_MAX) continue;
10826 } else {
10827 total_sse = tmp_best_sse;
10828 rate = tmp_best_rate;
10829 rate_y = tmp_best_ratey;
10830 distortion = tmp_best_distortion;
10831 skippable = tmp_best_skippable;
10832 *mbmi = tmp_best_mbmode;
10833 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
10834 }
10835 // Add in the cost of the transform type
10836 if (!xd->lossless[mbmi->segment_id]) {
10837 int rate_tx_type = 0;
10838#if CONFIG_EXT_TX
10839 if (get_ext_tx_types(mbmi->tx_size, bsize, 1) > 1) {
10840 const int eset = get_ext_tx_set(mbmi->tx_size, bsize, 1);
10841 rate_tx_type =
10842 cpi->inter_tx_type_costs[eset][mbmi->tx_size][mbmi->tx_type];
10843 }
10844#else
10845 if (mbmi->tx_size < TX_32X32) {
10846 rate_tx_type = cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
10847 }
10848#endif
10849 rate += rate_tx_type;
10850 rate_y += rate_tx_type;
10851 }
10852
10853 rate2 += rate;
10854 distortion2 += distortion;
10855
10856 if (cm->interp_filter == SWITCHABLE)
Yaowu Xuf883b422016-08-30 14:01:10 -070010857 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010858
10859 if (!mode_excluded)
10860 mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
10861 : cm->reference_mode == COMPOUND_REFERENCE;
10862
Yaowu Xuf883b422016-08-30 14:01:10 -070010863 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010864
10865 tmp_best_rdu =
Yaowu Xuf883b422016-08-30 14:01:10 -070010866 best_rd - AOMMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
Yaowu Xuc27fc142016-08-22 16:08:15 -070010867 RDCOST(x->rdmult, x->rddiv, 0, total_sse));
10868
10869 if (tmp_best_rdu > 0) {
10870 // If even the 'Y' rd value of split is higher than best so far
10871 // then dont bother looking at UV
Angie Chiangb5dda482016-11-02 16:19:58 -070010872 int is_cost_valid_uv;
Angie Chiangb5dda482016-11-02 16:19:58 -070010873 RD_STATS rd_stats_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -070010874 av1_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col, BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010875#if CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -070010876 is_cost_valid_uv =
10877 inter_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
Angie Chiang284d7772016-11-08 11:06:45 -080010878#else
10879 is_cost_valid_uv =
10880 super_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
10881#endif
Angie Chiangb5dda482016-11-02 16:19:58 -070010882 rate_uv = rd_stats_uv.rate;
10883 distortion_uv = rd_stats_uv.dist;
10884 uv_skippable = rd_stats_uv.skip;
10885 uv_sse = rd_stats_uv.sse;
Angie Chiang284d7772016-11-08 11:06:45 -080010886
Angie Chiangb5dda482016-11-02 16:19:58 -070010887 if (!is_cost_valid_uv) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010888 rate2 += rate_uv;
10889 distortion2 += distortion_uv;
10890 skippable = skippable && uv_skippable;
10891 total_sse += uv_sse;
10892 } else {
10893 continue;
10894 }
10895 }
10896
10897 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
10898
10899 // Estimate the reference frame signaling cost and add it
10900 // to the rolling cost variable.
10901 if (second_ref_frame > INTRA_FRAME) {
10902 rate2 += ref_costs_comp[ref_frame];
10903#if CONFIG_EXT_REFS
10904 rate2 += ref_costs_comp[second_ref_frame];
10905#endif // CONFIG_EXT_REFS
10906 } else {
10907 rate2 += ref_costs_single[ref_frame];
10908 }
10909
10910 if (!disable_skip) {
10911 // Skip is never coded at the segment level for sub8x8 blocks and instead
10912 // always coded in the bitstream at the mode info level.
10913
10914 if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
10915 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
10916 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
10917 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010918 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010919 } else {
10920 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070010921 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010922 distortion2 = total_sse;
10923 assert(total_sse >= 0);
10924 rate2 -= (rate_y + rate_uv);
10925 rate_y = 0;
10926 rate_uv = 0;
10927 this_skip2 = 1;
10928 }
10929 } else {
10930 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010931 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010932 }
10933
10934 // Calculate the final RD estimate for this mode.
10935 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10936 }
10937
10938 if (!disable_skip && ref_frame == INTRA_FRAME) {
10939 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070010940 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010941 }
10942
10943 // Did this mode help.. i.e. is it the new best mode
10944 if (this_rd < best_rd || x->skip) {
10945 if (!mode_excluded) {
10946 // Note index of best mode so far
10947 best_ref_index = ref_index;
10948
10949 if (ref_frame == INTRA_FRAME) {
10950 /* required for left and above block mv */
10951 mbmi->mv[0].as_int = 0;
10952 }
10953
10954 rd_cost->rate = rate2;
10955#if CONFIG_SUPERTX
10956 *returnrate_nocoef = rate2 - rate_y - rate_uv;
10957 if (!disable_skip)
10958 *returnrate_nocoef -=
Yaowu Xuf883b422016-08-30 14:01:10 -070010959 av1_cost_bit(av1_get_skip_prob(cm, xd), this_skip2);
10960 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
10961 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010962 assert(*returnrate_nocoef > 0);
10963#endif // CONFIG_SUPERTX
10964 rd_cost->dist = distortion2;
10965 rd_cost->rdcost = this_rd;
10966 best_rd = this_rd;
10967 best_yrd =
10968 best_rd - RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
10969 best_mbmode = *mbmi;
10970 best_skip2 = this_skip2;
10971
10972#if CONFIG_VAR_TX
10973 for (i = 0; i < MAX_MB_PLANE; ++i)
10974 memset(ctx->blk_skip[i], 0, sizeof(uint8_t) * ctx->num_4x4_blk);
10975#endif
10976
10977 for (i = 0; i < 4; i++) best_bmodes[i] = xd->mi[0]->bmi[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010978 }
10979 }
10980
10981 /* keep record of best compound/single-only prediction */
10982 if (!disable_skip && ref_frame != INTRA_FRAME) {
10983 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
10984
10985 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
10986 single_rate = rate2 - compmode_cost;
10987 hybrid_rate = rate2;
10988 } else {
10989 single_rate = rate2;
10990 hybrid_rate = rate2 + compmode_cost;
10991 }
10992
10993 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
10994 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
10995
10996 if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE])
10997 best_pred_rd[SINGLE_REFERENCE] = single_rd;
10998 else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE])
10999 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
11000
11001 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
11002 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
11003 }
11004
Yaowu Xuc27fc142016-08-22 16:08:15 -070011005 if (x->skip && !comp_pred) break;
11006 }
11007
11008 if (best_rd >= best_rd_so_far) {
11009 rd_cost->rate = INT_MAX;
11010 rd_cost->rdcost = INT64_MAX;
11011#if CONFIG_SUPERTX
11012 *returnrate_nocoef = INT_MAX;
11013#endif // CONFIG_SUPERTX
11014 return;
11015 }
11016
Yaowu Xuc27fc142016-08-22 16:08:15 -070011017 if (best_rd == INT64_MAX) {
11018 rd_cost->rate = INT_MAX;
11019 rd_cost->dist = INT64_MAX;
11020 rd_cost->rdcost = INT64_MAX;
11021#if CONFIG_SUPERTX
11022 *returnrate_nocoef = INT_MAX;
11023#endif // CONFIG_SUPERTX
11024 return;
11025 }
11026
11027#if CONFIG_DUAL_FILTER
11028 assert((cm->interp_filter == SWITCHABLE) ||
11029 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
11030 !is_inter_block(&best_mbmode));
11031#else
11032 assert((cm->interp_filter == SWITCHABLE) ||
11033 (cm->interp_filter == best_mbmode.interp_filter) ||
11034 !is_inter_block(&best_mbmode));
11035#endif
11036
Yaowu Xuf883b422016-08-30 14:01:10 -070011037 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
11038 sf->adaptive_rd_thresh, bsize, best_ref_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011039
11040 // macroblock modes
11041 *mbmi = best_mbmode;
Jingning Hanfe45b212016-11-22 10:30:23 -080011042#if CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011043 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
Jingning Hanfe45b212016-11-22 10:30:23 -080011044#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070011045
11046 x->skip |= best_skip2;
11047 if (!is_inter_block(&best_mbmode)) {
11048 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
11049 } else {
11050 for (i = 0; i < 4; ++i)
11051 memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
11052
Yaowu Xuc27fc142016-08-22 16:08:15 -070011053#if CONFIG_REF_MV
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -070011054 mbmi->pred_mv[0].as_int = xd->mi[0]->bmi[3].pred_mv[0].as_int;
11055 mbmi->pred_mv[1].as_int = xd->mi[0]->bmi[3].pred_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011056#endif
Yaowu Xu4306b6e2016-09-27 12:55:32 -070011057 mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
11058 mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011059 }
11060
11061 for (i = 0; i < REFERENCE_MODES; ++i) {
11062 if (best_pred_rd[i] == INT64_MAX)
11063 best_pred_diff[i] = INT_MIN;
11064 else
11065 best_pred_diff[i] = best_rd - best_pred_rd[i];
11066 }
11067
11068 store_coding_context(x, ctx, best_ref_index, best_pred_diff, 0);
11069}
11070
Yue Chencb60b182016-10-13 15:18:22 -070011071#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070011072// This function has a structure similar to av1_build_obmc_inter_prediction
Yaowu Xuc27fc142016-08-22 16:08:15 -070011073//
11074// The OBMC predictor is computed as:
11075//
11076// PObmc(x,y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070011077// AOM_BLEND_A64(Mh(x),
11078// AOM_BLEND_A64(Mv(y), P(x,y), PAbove(x,y)),
Yaowu Xuc27fc142016-08-22 16:08:15 -070011079// PLeft(x, y))
11080//
Yaowu Xuf883b422016-08-30 14:01:10 -070011081// Scaling up by AOM_BLEND_A64_MAX_ALPHA ** 2 and omitting the intermediate
Yaowu Xuc27fc142016-08-22 16:08:15 -070011082// rounding, this can be written as:
11083//
Yaowu Xuf883b422016-08-30 14:01:10 -070011084// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * Pobmc(x,y) =
Yaowu Xuc27fc142016-08-22 16:08:15 -070011085// Mh(x) * Mv(y) * P(x,y) +
11086// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070011087// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011088//
11089// Where :
11090//
Yaowu Xuf883b422016-08-30 14:01:10 -070011091// Cv(y) = AOM_BLEND_A64_MAX_ALPHA - Mv(y)
11092// Ch(y) = AOM_BLEND_A64_MAX_ALPHA - Mh(y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011093//
11094// This function computes 'wsrc' and 'mask' as:
11095//
11096// wsrc(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070011097// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * src(x, y) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070011098// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070011099// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011100//
11101// mask(x, y) = Mh(x) * Mv(y)
11102//
11103// These can then be used to efficiently approximate the error for any
11104// predictor P in the context of the provided neighbouring predictors by
11105// computing:
11106//
11107// error(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070011108// wsrc(x, y) - mask(x, y) * P(x, y) / (AOM_BLEND_A64_MAX_ALPHA ** 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011109//
Yaowu Xuf883b422016-08-30 14:01:10 -070011110static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011111 const MACROBLOCKD *xd, int mi_row,
11112 int mi_col, const uint8_t *above,
11113 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -070011114 int left_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011115 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
11116 int row, col, i;
11117 const int bw = 8 * xd->n8_w;
11118 const int bh = 8 * xd->n8_h;
Yue Chene9638cc2016-10-10 12:37:54 -070011119 int32_t *mask_buf = x->mask_buf;
11120 int32_t *wsrc_buf = x->wsrc_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011121 const int wsrc_stride = bw;
11122 const int mask_stride = bw;
Yaowu Xuf883b422016-08-30 14:01:10 -070011123 const int src_scale = AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA;
11124#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011125 const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
11126#else
11127 const int is_hbd = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070011128#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011129
11130 // plane 0 should not be subsampled
11131 assert(xd->plane[0].subsampling_x == 0);
11132 assert(xd->plane[0].subsampling_y == 0);
11133
Yaowu Xuf883b422016-08-30 14:01:10 -070011134 av1_zero_array(wsrc_buf, bw * bh);
11135 for (i = 0; i < bw * bh; ++i) mask_buf[i] = AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011136
11137 // handle above row
11138 if (xd->up_available) {
11139 const int overlap = num_4x4_blocks_high_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070011140 const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011141 const int mi_row_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070011142 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011143
11144 assert(miw > 0);
11145
11146 i = 0;
11147 do { // for each mi in the above row
11148 const int mi_col_offset = i;
11149 const MB_MODE_INFO *const above_mbmi =
11150 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
11151 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -070011152 AOMMIN(xd->n8_w, num_8x8_blocks_wide_lookup[above_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011153 const int neighbor_bw = mi_step * MI_SIZE;
11154
11155 if (is_neighbor_overlappable(above_mbmi)) {
11156 const int tmp_stride = above_stride;
11157 int32_t *wsrc = wsrc_buf + (i * MI_SIZE);
11158 int32_t *mask = mask_buf + (i * MI_SIZE);
11159
11160 if (!is_hbd) {
11161 const uint8_t *tmp = above;
11162
11163 for (row = 0; row < overlap; ++row) {
11164 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070011165 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011166 for (col = 0; col < neighbor_bw; ++col) {
11167 wsrc[col] = m1 * tmp[col];
11168 mask[col] = m0;
11169 }
11170 wsrc += wsrc_stride;
11171 mask += mask_stride;
11172 tmp += tmp_stride;
11173 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011174#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011175 } else {
11176 const uint16_t *tmp = CONVERT_TO_SHORTPTR(above);
11177
11178 for (row = 0; row < overlap; ++row) {
11179 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070011180 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011181 for (col = 0; col < neighbor_bw; ++col) {
11182 wsrc[col] = m1 * tmp[col];
11183 mask[col] = m0;
11184 }
11185 wsrc += wsrc_stride;
11186 mask += mask_stride;
11187 tmp += tmp_stride;
11188 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011189#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011190 }
11191 }
11192
11193 above += neighbor_bw;
11194 i += mi_step;
11195 } while (i < miw);
11196 }
11197
11198 for (i = 0; i < bw * bh; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -070011199 wsrc_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
11200 mask_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011201 }
11202
11203 // handle left column
11204 if (xd->left_available) {
11205 const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070011206 const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011207 const int mi_col_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070011208 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011209
11210 assert(mih > 0);
11211
11212 i = 0;
11213 do { // for each mi in the left column
11214 const int mi_row_offset = i;
11215 const MB_MODE_INFO *const left_mbmi =
11216 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
11217 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -070011218 AOMMIN(xd->n8_h, num_8x8_blocks_high_lookup[left_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011219 const int neighbor_bh = mi_step * MI_SIZE;
11220
11221 if (is_neighbor_overlappable(left_mbmi)) {
11222 const int tmp_stride = left_stride;
11223 int32_t *wsrc = wsrc_buf + (i * MI_SIZE * wsrc_stride);
11224 int32_t *mask = mask_buf + (i * MI_SIZE * mask_stride);
11225
11226 if (!is_hbd) {
11227 const uint8_t *tmp = left;
11228
11229 for (row = 0; row < neighbor_bh; ++row) {
11230 for (col = 0; col < overlap; ++col) {
11231 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070011232 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
11233 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
11234 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
11235 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011236 }
11237 wsrc += wsrc_stride;
11238 mask += mask_stride;
11239 tmp += tmp_stride;
11240 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011241#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011242 } else {
11243 const uint16_t *tmp = CONVERT_TO_SHORTPTR(left);
11244
11245 for (row = 0; row < neighbor_bh; ++row) {
11246 for (col = 0; col < overlap; ++col) {
11247 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070011248 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
11249 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
11250 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
11251 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011252 }
11253 wsrc += wsrc_stride;
11254 mask += mask_stride;
11255 tmp += tmp_stride;
11256 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011257#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011258 }
11259 }
11260
11261 left += neighbor_bh * left_stride;
11262 i += mi_step;
11263 } while (i < mih);
11264 }
11265
11266 if (!is_hbd) {
11267 const uint8_t *src = x->plane[0].src.buf;
11268
11269 for (row = 0; row < bh; ++row) {
11270 for (col = 0; col < bw; ++col) {
11271 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
11272 }
11273 wsrc_buf += wsrc_stride;
11274 src += x->plane[0].src.stride;
11275 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011276#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011277 } else {
11278 const uint16_t *src = CONVERT_TO_SHORTPTR(x->plane[0].src.buf);
11279
11280 for (row = 0; row < bh; ++row) {
11281 for (col = 0; col < bw; ++col) {
11282 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
11283 }
11284 wsrc_buf += wsrc_stride;
11285 src += x->plane[0].src.stride;
11286 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011287#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011288 }
11289}
Yue Chencb60b182016-10-13 15:18:22 -070011290#endif // CONFIG_MOTION_VAR