blob: 46dbae49a68e670c748a8a70de3203d11ca3007e [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"
36
Jingning Han1aab8182016-06-03 11:09:06 -070037#include "av1/encoder/aq_variance.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070038#include "av1/encoder/cost.h"
39#include "av1/encoder/encodemb.h"
40#include "av1/encoder/encodemv.h"
41#include "av1/encoder/encoder.h"
42#include "av1/encoder/hybrid_fwd_txfm.h"
43#include "av1/encoder/mcomp.h"
Urvang Joshib100db72016-10-12 16:28:56 -070044#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070045#include "av1/encoder/palette.h"
Urvang Joshib100db72016-10-12 16:28:56 -070046#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070047#include "av1/encoder/quantize.h"
48#include "av1/encoder/ratectrl.h"
49#include "av1/encoder/rd.h"
50#include "av1/encoder/rdopt.h"
Debargha Mukherjeeceebb702016-10-11 05:26:50 -070051#include "av1/encoder/tokenize.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070052
53#if CONFIG_DUAL_FILTER
54#if CONFIG_EXT_INTERP
55static const int filter_sets[25][2] = {
56 { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 0, 4 }, { 1, 0 }, { 1, 1 },
57 { 1, 2 }, { 1, 3 }, { 1, 4 }, { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 },
58 { 2, 4 }, { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 }, { 3, 4 }, { 4, 0 },
59 { 4, 1 }, { 4, 2 }, { 4, 3 }, { 4, 4 },
60};
61#else
62static const int filter_sets[9][2] = {
63 { 0, 0 }, { 0, 1 }, { 0, 2 }, { 1, 0 }, { 1, 1 },
64 { 1, 2 }, { 2, 0 }, { 2, 1 }, { 2, 2 },
65};
66#endif
67#endif
68
69#if CONFIG_EXT_REFS
70
71#define LAST_FRAME_MODE_MASK \
72 ((1 << INTRA_FRAME) | (1 << LAST2_FRAME) | (1 << LAST3_FRAME) | \
73 (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
74#define LAST2_FRAME_MODE_MASK \
75 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST3_FRAME) | \
76 (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
77#define LAST3_FRAME_MODE_MASK \
78 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
79 (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
80#define GOLDEN_FRAME_MODE_MASK \
81 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
82 (1 << LAST3_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
83#define BWDREF_FRAME_MODE_MASK \
84 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
85 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME))
86#define ALTREF_FRAME_MODE_MASK \
87 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
88 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME))
89
90#else
91
92#define LAST_FRAME_MODE_MASK \
93 ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | (1 << INTRA_FRAME))
94#define GOLDEN_FRAME_MODE_MASK \
95 ((1 << LAST_FRAME) | (1 << ALTREF_FRAME) | (1 << INTRA_FRAME))
96#define ALTREF_FRAME_MODE_MASK \
97 ((1 << LAST_FRAME) | (1 << GOLDEN_FRAME) | (1 << INTRA_FRAME))
98
99#endif // CONFIG_EXT_REFS
100
101#if CONFIG_EXT_REFS
102#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | (1 << BWDREF_FRAME) | 0x01)
103#else
104#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | 0x01)
105#endif // CONFIG_EXT_REFS
106
107#define MIN_EARLY_TERM_INDEX 3
108#define NEW_MV_DISCOUNT_FACTOR 8
109
110#if CONFIG_EXT_INTRA
111#define ANGLE_FAST_SEARCH 1
112#define ANGLE_SKIP_THRESH 10
113#define FILTER_FAST_SEARCH 1
114#endif // CONFIG_EXT_INTRA
115
116const double ADST_FLIP_SVM[8] = { -6.6623, -2.8062, -3.2531, 3.1671, // vert
117 -7.7051, -3.2234, -3.6193, 3.4533 }; // horz
118
119typedef struct {
120 PREDICTION_MODE mode;
121 MV_REFERENCE_FRAME ref_frame[2];
122} MODE_DEFINITION;
123
124typedef struct { MV_REFERENCE_FRAME ref_frame[2]; } REF_DEFINITION;
125
126struct rdcost_block_args {
Yaowu Xuf883b422016-08-30 14:01:10 -0700127 const AV1_COMP *cpi;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700128 MACROBLOCK *x;
129 ENTROPY_CONTEXT t_above[2 * MAX_MIB_SIZE];
130 ENTROPY_CONTEXT t_left[2 * MAX_MIB_SIZE];
131 int this_rate;
132 int64_t this_dist;
133 int64_t this_sse;
134 int64_t this_rd;
135 int64_t best_rd;
136 int exit_early;
137 int use_fast_coef_costing;
Urvang Joshi03f6fdc2016-10-14 15:53:39 -0700138 const SCAN_ORDER *scan_order;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700139 uint8_t skippable;
140};
141
142#define LAST_NEW_MV_INDEX 6
Yaowu Xuf883b422016-08-30 14:01:10 -0700143static const MODE_DEFINITION av1_mode_order[MAX_MODES] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700144 { NEARESTMV, { LAST_FRAME, NONE } },
145#if CONFIG_EXT_REFS
146 { NEARESTMV, { LAST2_FRAME, NONE } },
147 { NEARESTMV, { LAST3_FRAME, NONE } },
148 { NEARESTMV, { BWDREF_FRAME, NONE } },
149#endif // CONFIG_EXT_REFS
150 { NEARESTMV, { ALTREF_FRAME, NONE } },
151 { NEARESTMV, { GOLDEN_FRAME, NONE } },
152
153 { DC_PRED, { INTRA_FRAME, NONE } },
154
155 { NEWMV, { LAST_FRAME, NONE } },
156#if CONFIG_EXT_REFS
157 { NEWMV, { LAST2_FRAME, NONE } },
158 { NEWMV, { LAST3_FRAME, NONE } },
159 { NEWMV, { BWDREF_FRAME, NONE } },
160#endif // CONFIG_EXT_REFS
161 { NEWMV, { ALTREF_FRAME, NONE } },
162 { NEWMV, { GOLDEN_FRAME, NONE } },
163
164 { NEARMV, { LAST_FRAME, NONE } },
165#if CONFIG_EXT_REFS
166 { NEARMV, { LAST2_FRAME, NONE } },
167 { NEARMV, { LAST3_FRAME, NONE } },
168 { NEARMV, { BWDREF_FRAME, NONE } },
169#endif // CONFIG_EXT_REFS
170 { NEARMV, { ALTREF_FRAME, NONE } },
171 { NEARMV, { GOLDEN_FRAME, NONE } },
172
173#if CONFIG_EXT_INTER
174 { NEWFROMNEARMV, { LAST_FRAME, NONE } },
175#if CONFIG_EXT_REFS
176 { NEWFROMNEARMV, { LAST2_FRAME, NONE } },
177 { NEWFROMNEARMV, { LAST3_FRAME, NONE } },
178 { NEWFROMNEARMV, { BWDREF_FRAME, NONE } },
179#endif // CONFIG_EXT_REFS
180 { NEWFROMNEARMV, { ALTREF_FRAME, NONE } },
181 { NEWFROMNEARMV, { GOLDEN_FRAME, NONE } },
182#endif // CONFIG_EXT_INTER
183
184 { ZEROMV, { LAST_FRAME, NONE } },
185#if CONFIG_EXT_REFS
186 { ZEROMV, { LAST2_FRAME, NONE } },
187 { ZEROMV, { LAST3_FRAME, NONE } },
188 { ZEROMV, { BWDREF_FRAME, NONE } },
189#endif // CONFIG_EXT_REFS
190 { ZEROMV, { GOLDEN_FRAME, NONE } },
191 { ZEROMV, { ALTREF_FRAME, NONE } },
192
193// TODO(zoeliu): May need to reconsider the order on the modes to check
194
195#if CONFIG_EXT_INTER
196 { NEAREST_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
197#if CONFIG_EXT_REFS
198 { NEAREST_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
199 { NEAREST_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
200#endif // CONFIG_EXT_REFS
201 { NEAREST_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
202#if CONFIG_EXT_REFS
203 { NEAREST_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
204 { NEAREST_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
205 { NEAREST_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
206 { NEAREST_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
207#endif // CONFIG_EXT_REFS
208
209#else // CONFIG_EXT_INTER
210
211 { NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
212#if CONFIG_EXT_REFS
213 { NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
214 { NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
215#endif // CONFIG_EXT_REFS
216 { NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
217#if CONFIG_EXT_REFS
218 { NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
219 { NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
220 { NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
221 { NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
222#endif // CONFIG_EXT_REFS
223#endif // CONFIG_EXT_INTER
224
225 { TM_PRED, { INTRA_FRAME, NONE } },
226
227#if CONFIG_EXT_INTER
228 { NEAR_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
229 { NEAREST_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
230 { NEAR_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
231 { NEW_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
232 { NEAREST_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
233 { NEW_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
234 { NEAR_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
235 { NEW_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
236 { ZERO_ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
237
238#if CONFIG_EXT_REFS
239 { NEAR_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
240 { NEAREST_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
241 { NEAR_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
242 { NEW_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
243 { NEAREST_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
244 { NEW_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
245 { NEAR_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
246 { NEW_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
247 { ZERO_ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
248
249 { NEAR_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
250 { NEAREST_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
251 { NEAR_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
252 { NEW_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
253 { NEAREST_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
254 { NEW_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
255 { NEAR_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
256 { NEW_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
257 { ZERO_ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
258#endif // CONFIG_EXT_REFS
259
260 { NEAR_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
261 { NEAREST_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
262 { NEAR_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
263 { NEW_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
264 { NEAREST_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
265 { NEW_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
266 { NEAR_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
267 { NEW_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
268 { ZERO_ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
269
270#if CONFIG_EXT_REFS
271 { NEAR_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
272 { NEAREST_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
273 { NEAR_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
274 { NEW_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
275 { NEAREST_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
276 { NEW_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
277 { NEAR_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
278 { NEW_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
279 { ZERO_ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
280
281 { NEAR_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
282 { NEAREST_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
283 { NEAR_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
284 { NEW_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
285 { NEAREST_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
286 { NEW_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
287 { NEAR_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
288 { NEW_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
289 { ZERO_ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
290
291 { NEAR_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
292 { NEAREST_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
293 { NEAR_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
294 { NEW_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
295 { NEAREST_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
296 { NEW_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
297 { NEAR_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
298 { NEW_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
299 { ZERO_ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
300
301 { NEAR_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
302 { NEAREST_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
303 { NEAR_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
304 { NEW_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
305 { NEAREST_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
306 { NEW_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
307 { NEAR_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
308 { NEW_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
309 { ZERO_ZEROMV, { GOLDEN_FRAME, BWDREF_FRAME } },
310#endif // CONFIG_EXT_REFS
311
312#else // CONFIG_EXT_INTER
313
314 { NEARMV, { LAST_FRAME, ALTREF_FRAME } },
315 { NEWMV, { LAST_FRAME, ALTREF_FRAME } },
316#if CONFIG_EXT_REFS
317 { NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
318 { NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
319 { NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
320 { NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
321#endif // CONFIG_EXT_REFS
322 { NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
323 { NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
324
325#if CONFIG_EXT_REFS
326 { NEARMV, { LAST_FRAME, BWDREF_FRAME } },
327 { NEWMV, { LAST_FRAME, BWDREF_FRAME } },
328 { NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
329 { NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
330 { NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
331 { NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
332 { NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
333 { NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
334#endif // CONFIG_EXT_REFS
335
336 { ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
337#if CONFIG_EXT_REFS
338 { ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
339 { ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
340#endif // CONFIG_EXT_REFS
341 { ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
342
343#if CONFIG_EXT_REFS
344 { ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
345 { ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
346 { ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
347 { ZEROMV, { GOLDEN_FRAME, BWDREF_FRAME } },
348#endif // CONFIG_EXT_REFS
349
350#endif // CONFIG_EXT_INTER
351
352 { H_PRED, { INTRA_FRAME, NONE } },
353 { V_PRED, { INTRA_FRAME, NONE } },
354 { D135_PRED, { INTRA_FRAME, NONE } },
355 { D207_PRED, { INTRA_FRAME, NONE } },
356 { D153_PRED, { INTRA_FRAME, NONE } },
357 { D63_PRED, { INTRA_FRAME, NONE } },
358 { D117_PRED, { INTRA_FRAME, NONE } },
359 { D45_PRED, { INTRA_FRAME, NONE } },
360
361#if CONFIG_EXT_INTER
362 { ZEROMV, { LAST_FRAME, INTRA_FRAME } },
363 { NEARESTMV, { LAST_FRAME, INTRA_FRAME } },
364 { NEARMV, { LAST_FRAME, INTRA_FRAME } },
365 { NEWMV, { LAST_FRAME, INTRA_FRAME } },
366
367#if CONFIG_EXT_REFS
368 { ZEROMV, { LAST2_FRAME, INTRA_FRAME } },
369 { NEARESTMV, { LAST2_FRAME, INTRA_FRAME } },
370 { NEARMV, { LAST2_FRAME, INTRA_FRAME } },
371 { NEWMV, { LAST2_FRAME, INTRA_FRAME } },
372
373 { ZEROMV, { LAST3_FRAME, INTRA_FRAME } },
374 { NEARESTMV, { LAST3_FRAME, INTRA_FRAME } },
375 { NEARMV, { LAST3_FRAME, INTRA_FRAME } },
376 { NEWMV, { LAST3_FRAME, INTRA_FRAME } },
377#endif // CONFIG_EXT_REFS
378
379 { ZEROMV, { GOLDEN_FRAME, INTRA_FRAME } },
380 { NEARESTMV, { GOLDEN_FRAME, INTRA_FRAME } },
381 { NEARMV, { GOLDEN_FRAME, INTRA_FRAME } },
382 { NEWMV, { GOLDEN_FRAME, INTRA_FRAME } },
383
384#if CONFIG_EXT_REFS
385 { ZEROMV, { BWDREF_FRAME, INTRA_FRAME } },
386 { NEARESTMV, { BWDREF_FRAME, INTRA_FRAME } },
387 { NEARMV, { BWDREF_FRAME, INTRA_FRAME } },
388 { NEWMV, { BWDREF_FRAME, INTRA_FRAME } },
389#endif // CONFIG_EXT_REFS
390
391 { ZEROMV, { ALTREF_FRAME, INTRA_FRAME } },
392 { NEARESTMV, { ALTREF_FRAME, INTRA_FRAME } },
393 { NEARMV, { ALTREF_FRAME, INTRA_FRAME } },
394 { NEWMV, { ALTREF_FRAME, INTRA_FRAME } },
395#endif // CONFIG_EXT_INTER
396};
397
Yaowu Xuf883b422016-08-30 14:01:10 -0700398static const REF_DEFINITION av1_ref_order[MAX_REFS] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700399 { { LAST_FRAME, NONE } },
400#if CONFIG_EXT_REFS
401 { { LAST2_FRAME, NONE } }, { { LAST3_FRAME, NONE } },
402 { { BWDREF_FRAME, NONE } },
403#endif // CONFIG_EXT_REFS
404 { { GOLDEN_FRAME, NONE } }, { { ALTREF_FRAME, NONE } },
405
406 { { LAST_FRAME, ALTREF_FRAME } },
407#if CONFIG_EXT_REFS
408 { { LAST2_FRAME, ALTREF_FRAME } }, { { LAST3_FRAME, ALTREF_FRAME } },
409#endif // CONFIG_EXT_REFS
410 { { GOLDEN_FRAME, ALTREF_FRAME } },
411
412#if CONFIG_EXT_REFS
413 { { LAST_FRAME, BWDREF_FRAME } }, { { LAST2_FRAME, BWDREF_FRAME } },
414 { { LAST3_FRAME, BWDREF_FRAME } }, { { GOLDEN_FRAME, BWDREF_FRAME } },
415#endif // CONFIG_EXT_REFS
416
417 { { INTRA_FRAME, NONE } },
418};
419
hui su5db97432016-10-14 16:10:14 -0700420#if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700421static INLINE int write_uniform_cost(int n, int v) {
422 int l = get_unsigned_bits(n), m = (1 << l) - n;
423 if (l == 0) return 0;
424 if (v < m)
Yaowu Xuf883b422016-08-30 14:01:10 -0700425 return (l - 1) * av1_cost_bit(128, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700426 else
Yaowu Xuf883b422016-08-30 14:01:10 -0700427 return l * av1_cost_bit(128, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700428}
hui su5db97432016-10-14 16:10:14 -0700429#endif // CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700430
431// constants for prune 1 and prune 2 decision boundaries
432#define FAST_EXT_TX_CORR_MID 0.0
433#define FAST_EXT_TX_EDST_MID 0.1
434#define FAST_EXT_TX_CORR_MARGIN 0.5
435#define FAST_EXT_TX_EDST_MARGIN 0.3
436
437static const TX_TYPE_1D vtx_tab[TX_TYPES] = {
438 DCT_1D, ADST_1D, DCT_1D, ADST_1D,
439#if CONFIG_EXT_TX
440 FLIPADST_1D, DCT_1D, FLIPADST_1D, ADST_1D, FLIPADST_1D, IDTX_1D,
441 DCT_1D, IDTX_1D, ADST_1D, IDTX_1D, FLIPADST_1D, IDTX_1D,
442#endif // CONFIG_EXT_TX
443};
444
445static const TX_TYPE_1D htx_tab[TX_TYPES] = {
446 DCT_1D, DCT_1D, ADST_1D, ADST_1D,
447#if CONFIG_EXT_TX
448 DCT_1D, FLIPADST_1D, FLIPADST_1D, FLIPADST_1D, ADST_1D, IDTX_1D,
449 IDTX_1D, DCT_1D, IDTX_1D, ADST_1D, IDTX_1D, FLIPADST_1D,
450#endif // CONFIG_EXT_TX
451};
452
Yaowu Xuf883b422016-08-30 14:01:10 -0700453static void get_energy_distribution_fine(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700454 uint8_t *src, int src_stride,
455 uint8_t *dst, int dst_stride,
456 double *hordist, double *verdist) {
457 int bw = 4 << (b_width_log2_lookup[bsize]);
458 int bh = 4 << (b_height_log2_lookup[bsize]);
459 unsigned int esq[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
460 unsigned int var[16];
461 double total = 0;
462
463 const int f_index = bsize - BLOCK_16X16;
464 if (f_index < 0) {
465 int i, j, index;
466 int w_shift = bw == 8 ? 1 : 2;
467 int h_shift = bh == 8 ? 1 : 2;
Yaowu Xuf883b422016-08-30 14:01:10 -0700468#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700469 if (cpi->common.use_highbitdepth) {
470 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
471 uint16_t *dst16 = CONVERT_TO_SHORTPTR(dst);
472 for (i = 0; i < bh; ++i)
473 for (j = 0; j < bw; ++j) {
474 index = (j >> w_shift) + ((i >> h_shift) << 2);
475 esq[index] +=
476 (src16[j + i * src_stride] - dst16[j + i * dst_stride]) *
477 (src16[j + i * src_stride] - dst16[j + i * dst_stride]);
478 }
479 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700480#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700481
482 for (i = 0; i < bh; ++i)
483 for (j = 0; j < bw; ++j) {
484 index = (j >> w_shift) + ((i >> h_shift) << 2);
485 esq[index] += (src[j + i * src_stride] - dst[j + i * dst_stride]) *
486 (src[j + i * src_stride] - dst[j + i * dst_stride]);
487 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700488#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700489 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700490#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700491 } else {
492 var[0] = cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[0]);
493 var[1] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
494 dst_stride, &esq[1]);
495 var[2] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
496 dst_stride, &esq[2]);
497 var[3] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
498 dst + 3 * bw / 4, dst_stride, &esq[3]);
499 src += bh / 4 * src_stride;
500 dst += bh / 4 * dst_stride;
501
502 var[4] = cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[4]);
503 var[5] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
504 dst_stride, &esq[5]);
505 var[6] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
506 dst_stride, &esq[6]);
507 var[7] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
508 dst + 3 * bw / 4, dst_stride, &esq[7]);
509 src += bh / 4 * src_stride;
510 dst += bh / 4 * dst_stride;
511
512 var[8] = cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[8]);
513 var[9] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
514 dst_stride, &esq[9]);
515 var[10] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
516 dst_stride, &esq[10]);
517 var[11] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
518 dst + 3 * bw / 4, dst_stride, &esq[11]);
519 src += bh / 4 * src_stride;
520 dst += bh / 4 * dst_stride;
521
522 var[12] =
523 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[12]);
524 var[13] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
525 dst_stride, &esq[13]);
526 var[14] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
527 dst_stride, &esq[14]);
528 var[15] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
529 dst + 3 * bw / 4, dst_stride, &esq[15]);
530 }
531
532 total = esq[0] + esq[1] + esq[2] + esq[3] + esq[4] + esq[5] + esq[6] +
533 esq[7] + esq[8] + esq[9] + esq[10] + esq[11] + esq[12] + esq[13] +
534 esq[14] + esq[15];
535 if (total > 0) {
536 const double e_recip = 1.0 / total;
537 hordist[0] =
538 ((double)esq[0] + (double)esq[4] + (double)esq[8] + (double)esq[12]) *
539 e_recip;
540 hordist[1] =
541 ((double)esq[1] + (double)esq[5] + (double)esq[9] + (double)esq[13]) *
542 e_recip;
543 hordist[2] =
544 ((double)esq[2] + (double)esq[6] + (double)esq[10] + (double)esq[14]) *
545 e_recip;
546 verdist[0] =
547 ((double)esq[0] + (double)esq[1] + (double)esq[2] + (double)esq[3]) *
548 e_recip;
549 verdist[1] =
550 ((double)esq[4] + (double)esq[5] + (double)esq[6] + (double)esq[7]) *
551 e_recip;
552 verdist[2] =
553 ((double)esq[8] + (double)esq[9] + (double)esq[10] + (double)esq[11]) *
554 e_recip;
555 } else {
556 hordist[0] = verdist[0] = 0.25;
557 hordist[1] = verdist[1] = 0.25;
558 hordist[2] = verdist[2] = 0.25;
559 }
560 (void)var[0];
561 (void)var[1];
562 (void)var[2];
563 (void)var[3];
564 (void)var[4];
565 (void)var[5];
566 (void)var[6];
567 (void)var[7];
568 (void)var[8];
569 (void)var[9];
570 (void)var[10];
571 (void)var[11];
572 (void)var[12];
573 (void)var[13];
574 (void)var[14];
575 (void)var[15];
576}
577
Yaowu Xuf883b422016-08-30 14:01:10 -0700578static int adst_vs_flipadst(const AV1_COMP *cpi, BLOCK_SIZE bsize, uint8_t *src,
579 int src_stride, uint8_t *dst, int dst_stride,
580 double *hdist, double *vdist) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700581 int prune_bitmask = 0;
582 double svm_proj_h = 0, svm_proj_v = 0;
583 get_energy_distribution_fine(cpi, bsize, src, src_stride, dst, dst_stride,
584 hdist, vdist);
585
586 svm_proj_v = vdist[0] * ADST_FLIP_SVM[0] + vdist[1] * ADST_FLIP_SVM[1] +
587 vdist[2] * ADST_FLIP_SVM[2] + ADST_FLIP_SVM[3];
588 svm_proj_h = hdist[0] * ADST_FLIP_SVM[4] + hdist[1] * ADST_FLIP_SVM[5] +
589 hdist[2] * ADST_FLIP_SVM[6] + ADST_FLIP_SVM[7];
590 if (svm_proj_v > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
591 prune_bitmask |= 1 << FLIPADST_1D;
592 else if (svm_proj_v < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
593 prune_bitmask |= 1 << ADST_1D;
594
595 if (svm_proj_h > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
596 prune_bitmask |= 1 << (FLIPADST_1D + 8);
597 else if (svm_proj_h < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
598 prune_bitmask |= 1 << (ADST_1D + 8);
599
600 return prune_bitmask;
601}
602
603#if CONFIG_EXT_TX
604static void get_horver_correlation(int16_t *diff, int stride, int w, int h,
605 double *hcorr, double *vcorr) {
606 // Returns hor/ver correlation coefficient
607 const int num = (h - 1) * (w - 1);
608 double num_r;
609 int i, j;
610 int64_t xy_sum = 0, xz_sum = 0;
611 int64_t x_sum = 0, y_sum = 0, z_sum = 0;
612 int64_t x2_sum = 0, y2_sum = 0, z2_sum = 0;
613 double x_var_n, y_var_n, z_var_n, xy_var_n, xz_var_n;
614 *hcorr = *vcorr = 1;
615
616 assert(num > 0);
617 num_r = 1.0 / num;
618 for (i = 1; i < h; ++i) {
619 for (j = 1; j < w; ++j) {
620 const int16_t x = diff[i * stride + j];
621 const int16_t y = diff[i * stride + j - 1];
622 const int16_t z = diff[(i - 1) * stride + j];
623 xy_sum += x * y;
624 xz_sum += x * z;
625 x_sum += x;
626 y_sum += y;
627 z_sum += z;
628 x2_sum += x * x;
629 y2_sum += y * y;
630 z2_sum += z * z;
631 }
632 }
633 x_var_n = x2_sum - (x_sum * x_sum) * num_r;
634 y_var_n = y2_sum - (y_sum * y_sum) * num_r;
635 z_var_n = z2_sum - (z_sum * z_sum) * num_r;
636 xy_var_n = xy_sum - (x_sum * y_sum) * num_r;
637 xz_var_n = xz_sum - (x_sum * z_sum) * num_r;
638 if (x_var_n > 0 && y_var_n > 0) {
639 *hcorr = xy_var_n / sqrt(x_var_n * y_var_n);
640 *hcorr = *hcorr < 0 ? 0 : *hcorr;
641 }
642 if (x_var_n > 0 && z_var_n > 0) {
643 *vcorr = xz_var_n / sqrt(x_var_n * z_var_n);
644 *vcorr = *vcorr < 0 ? 0 : *vcorr;
645 }
646}
647
648int dct_vs_idtx(int16_t *diff, int stride, int w, int h, double *hcorr,
649 double *vcorr) {
650 int prune_bitmask = 0;
651 get_horver_correlation(diff, stride, w, h, hcorr, vcorr);
652
653 if (*vcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
654 prune_bitmask |= 1 << IDTX_1D;
655 else if (*vcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
656 prune_bitmask |= 1 << DCT_1D;
657
658 if (*hcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
659 prune_bitmask |= 1 << (IDTX_1D + 8);
660 else if (*hcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
661 prune_bitmask |= 1 << (DCT_1D + 8);
662 return prune_bitmask;
663}
664
665// Performance drop: 0.5%, Speed improvement: 24%
Yaowu Xuf883b422016-08-30 14:01:10 -0700666static int prune_two_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700667 MACROBLOCK *x, MACROBLOCKD *xd, int adst_flipadst,
668 int dct_idtx) {
669 struct macroblock_plane *const p = &x->plane[0];
670 struct macroblockd_plane *const pd = &xd->plane[0];
671 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
672 const int bw = 4 << (b_width_log2_lookup[bs]);
673 const int bh = 4 << (b_height_log2_lookup[bs]);
674 double hdist[3] = { 0, 0, 0 }, vdist[3] = { 0, 0, 0 };
675 double hcorr, vcorr;
676 int prune = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700677 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700678
679 if (adst_flipadst)
680 prune |= adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride,
681 pd->dst.buf, pd->dst.stride, hdist, vdist);
682 if (dct_idtx) prune |= dct_vs_idtx(p->src_diff, bw, bw, bh, &hcorr, &vcorr);
683
684 return prune;
685}
686#endif // CONFIG_EXT_TX
687
688// Performance drop: 0.3%, Speed improvement: 5%
Yaowu Xuf883b422016-08-30 14:01:10 -0700689static int prune_one_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700690 MACROBLOCK *x, MACROBLOCKD *xd) {
691 struct macroblock_plane *const p = &x->plane[0];
692 struct macroblockd_plane *const pd = &xd->plane[0];
693 double hdist[3] = { 0, 0, 0 }, vdist[3] = { 0, 0, 0 };
Yaowu Xuf883b422016-08-30 14:01:10 -0700694 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700695 return adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride, pd->dst.buf,
696 pd->dst.stride, hdist, vdist);
697}
698
Yaowu Xuf883b422016-08-30 14:01:10 -0700699static int prune_tx_types(const AV1_COMP *cpi, BLOCK_SIZE bsize, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700700 MACROBLOCKD *xd, int tx_set) {
701#if CONFIG_EXT_TX
702 const int *tx_set_1D = ext_tx_used_inter_1D[tx_set];
703#else
704 const int tx_set_1D[TX_TYPES_1D] = { 0 };
705#endif
706
707 switch (cpi->sf.tx_type_search.prune_mode) {
708 case NO_PRUNE: return 0; break;
709 case PRUNE_ONE:
Sarah Parker68a26b62016-10-28 13:19:33 -0700710 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700711 return 0;
712 return prune_one_for_sby(cpi, bsize, x, xd);
713 break;
714#if CONFIG_EXT_TX
715 case PRUNE_TWO:
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 if (!(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D])) return 0;
718 return prune_two_for_sby(cpi, bsize, x, xd, 0, 1);
719 }
Sarah Parker68a26b62016-10-28 13:19:33 -0700720 if ((tx_set >= 0) && !(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700721 return prune_two_for_sby(cpi, bsize, x, xd, 1, 0);
722 return prune_two_for_sby(cpi, bsize, x, xd, 1, 1);
723 break;
724#endif
725 }
726 assert(0);
727 return 0;
728}
729
730static int do_tx_type_search(TX_TYPE tx_type, int prune) {
731// TODO(sarahparker) implement for non ext tx
732#if CONFIG_EXT_TX
733 return !(((prune >> vtx_tab[tx_type]) & 1) |
734 ((prune >> (htx_tab[tx_type] + 8)) & 1));
735#else
736 // temporary to avoid compiler warnings
737 (void)vtx_tab;
738 (void)htx_tab;
739 (void)tx_type;
740 (void)prune;
741 return 1;
742#endif
743}
744
Yaowu Xuf883b422016-08-30 14:01:10 -0700745static void model_rd_from_sse(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700746 const MACROBLOCKD *const xd, BLOCK_SIZE bsize,
747 int plane, int64_t sse, int *rate,
748 int64_t *dist) {
749 const struct macroblockd_plane *const pd = &xd->plane[plane];
750 const int dequant_shift =
Yaowu Xuf883b422016-08-30 14:01:10 -0700751#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700752 (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd - 5 :
Yaowu Xuf883b422016-08-30 14:01:10 -0700753#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700754 3;
755
756 // Fast approximate the modelling function.
757 if (cpi->sf.simple_model_rd_from_var) {
758 const int64_t square_error = sse;
759 int quantizer = (pd->dequant[1] >> dequant_shift);
760
761 if (quantizer < 120)
762 *rate = (int)((square_error * (280 - quantizer)) >>
Yaowu Xuf883b422016-08-30 14:01:10 -0700763 (16 - AV1_PROB_COST_SHIFT));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700764 else
765 *rate = 0;
766 *dist = (square_error * quantizer) >> 8;
767 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700768 av1_model_rd_from_var_lapndz(sse, num_pels_log2_lookup[bsize],
769 pd->dequant[1] >> dequant_shift, rate, dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700770 }
771
772 *dist <<= 4;
773}
774
Yaowu Xuf883b422016-08-30 14:01:10 -0700775static void model_rd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700776 MACROBLOCK *x, MACROBLOCKD *xd, int plane_from,
777 int plane_to, int *out_rate_sum,
778 int64_t *out_dist_sum, int *skip_txfm_sb,
779 int64_t *skip_sse_sb) {
780 // Note our transform coeffs are 8 times an orthogonal transform.
781 // Hence quantizer step is also 8 times. To get effective quantizer
782 // we need to divide by 8 before sending to modeling function.
783 int plane;
784 const int ref = xd->mi[0]->mbmi.ref_frame[0];
785
786 int64_t rate_sum = 0;
787 int64_t dist_sum = 0;
788 int64_t total_sse = 0;
789
790 x->pred_sse[ref] = 0;
791
792 for (plane = plane_from; plane <= plane_to; ++plane) {
793 struct macroblock_plane *const p = &x->plane[plane];
794 struct macroblockd_plane *const pd = &xd->plane[plane];
795 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
796
797 unsigned int sse;
798 int rate;
799 int64_t dist;
800
801 // TODO(geza): Write direct sse functions that do not compute
802 // variance as well.
803 cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride, pd->dst.buf, pd->dst.stride,
804 &sse);
805
806 if (plane == 0) x->pred_sse[ref] = sse;
807
808 total_sse += sse;
809
810 model_rd_from_sse(cpi, xd, bs, plane, sse, &rate, &dist);
811
812 rate_sum += rate;
813 dist_sum += dist;
814 }
815
816 *skip_txfm_sb = total_sse == 0;
817 *skip_sse_sb = total_sse << 4;
818 *out_rate_sum = (int)rate_sum;
819 *out_dist_sum = dist_sum;
820}
821
Yaowu Xuf883b422016-08-30 14:01:10 -0700822int64_t av1_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff,
823 intptr_t block_size, int64_t *ssz) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700824 int i;
825 int64_t error = 0, sqcoeff = 0;
826
827 for (i = 0; i < block_size; i++) {
828 const int diff = coeff[i] - dqcoeff[i];
829 error += diff * diff;
830 sqcoeff += coeff[i] * coeff[i];
831 }
832
833 *ssz = sqcoeff;
834 return error;
835}
836
Yaowu Xuf883b422016-08-30 14:01:10 -0700837int64_t av1_block_error_fp_c(const int16_t *coeff, const int16_t *dqcoeff,
838 int block_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700839 int i;
840 int64_t error = 0;
841
842 for (i = 0; i < block_size; i++) {
843 const int diff = coeff[i] - dqcoeff[i];
844 error += diff * diff;
845 }
846
847 return error;
848}
849
Yaowu Xuf883b422016-08-30 14:01:10 -0700850#if CONFIG_AOM_HIGHBITDEPTH
851int64_t av1_highbd_block_error_c(const tran_low_t *coeff,
852 const tran_low_t *dqcoeff, intptr_t block_size,
853 int64_t *ssz, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700854 int i;
855 int64_t error = 0, sqcoeff = 0;
856 int shift = 2 * (bd - 8);
857 int rounding = shift > 0 ? 1 << (shift - 1) : 0;
858
859 for (i = 0; i < block_size; i++) {
860 const int64_t diff = coeff[i] - dqcoeff[i];
861 error += diff * diff;
862 sqcoeff += (int64_t)coeff[i] * (int64_t)coeff[i];
863 }
864 assert(error >= 0 && sqcoeff >= 0);
865 error = (error + rounding) >> shift;
866 sqcoeff = (sqcoeff + rounding) >> shift;
867
868 *ssz = sqcoeff;
869 return error;
870}
Yaowu Xuf883b422016-08-30 14:01:10 -0700871#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700872
Debargha Mukherjeeceebb702016-10-11 05:26:50 -0700873/* The trailing '0' is a terminator which is used inside av1_cost_coeffs() to
Yaowu Xuc27fc142016-08-22 16:08:15 -0700874 * decide whether to include cost of a trailing EOB node or not (i.e. we
875 * can skip this if the last coefficient in this transform block, e.g. the
876 * 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block,
877 * were non-zero). */
Angie Chiang22ba7512016-10-20 17:10:33 -0700878int av1_cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
879 int block, int coeff_ctx, TX_SIZE tx_size,
880 const int16_t *scan, const int16_t *nb,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -0700881 int use_fast_coef_costing) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700882 MACROBLOCKD *const xd = &x->e_mbd;
883 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
884 const struct macroblock_plane *p = &x->plane[plane];
885 const struct macroblockd_plane *pd = &xd->plane[plane];
886 const PLANE_TYPE type = pd->plane_type;
887 const uint16_t *band_count = &band_count_table[tx_size][1];
888 const int eob = p->eobs[block];
889 const tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
890 const int tx_size_ctx = txsize_sqr_map[tx_size];
891 unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
892 x->token_costs[tx_size_ctx][type][is_inter_block(mbmi)];
893 uint8_t token_cache[MAX_TX_SQUARE];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700894 int pt = coeff_ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700895 int c, cost;
Yaowu Xuf883b422016-08-30 14:01:10 -0700896#if CONFIG_AOM_HIGHBITDEPTH
897 const int *cat6_high_cost = av1_get_high_cost_table(xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700898#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700899 const int *cat6_high_cost = av1_get_high_cost_table(8);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700900#endif
901
902#if !CONFIG_VAR_TX && !CONFIG_SUPERTX
903 // Check for consistency of tx_size with mode info
904 assert(type == PLANE_TYPE_Y ? mbmi->tx_size == tx_size
905 : get_uv_tx_size(mbmi, pd) == tx_size);
906#endif // !CONFIG_VAR_TX && !CONFIG_SUPERTX
Angie Chiang22ba7512016-10-20 17:10:33 -0700907 (void)cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700908
909 if (eob == 0) {
910 // single eob token
911 cost = token_costs[0][0][pt][EOB_TOKEN];
912 c = 0;
913 } else {
914 if (use_fast_coef_costing) {
915 int band_left = *band_count++;
916
917 // dc token
918 int v = qcoeff[0];
919 int16_t prev_t;
Yaowu Xuf883b422016-08-30 14:01:10 -0700920 cost = av1_get_token_cost(v, &prev_t, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700921 cost += (*token_costs)[0][pt][prev_t];
922
Yaowu Xuf883b422016-08-30 14:01:10 -0700923 token_cache[0] = av1_pt_energy_class[prev_t];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700924 ++token_costs;
925
926 // ac tokens
927 for (c = 1; c < eob; c++) {
928 const int rc = scan[c];
929 int16_t t;
930
931 v = qcoeff[rc];
Yaowu Xuf883b422016-08-30 14:01:10 -0700932 cost += av1_get_token_cost(v, &t, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700933 cost += (*token_costs)[!prev_t][!prev_t][t];
934 prev_t = t;
935 if (!--band_left) {
936 band_left = *band_count++;
937 ++token_costs;
938 }
939 }
940
941 // eob token
942 if (band_left) cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
943
944 } else { // !use_fast_coef_costing
945 int band_left = *band_count++;
946
947 // dc token
948 int v = qcoeff[0];
949 int16_t tok;
950 unsigned int(*tok_cost_ptr)[COEFF_CONTEXTS][ENTROPY_TOKENS];
Yaowu Xuf883b422016-08-30 14:01:10 -0700951 cost = av1_get_token_cost(v, &tok, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700952 cost += (*token_costs)[0][pt][tok];
953
Yaowu Xuf883b422016-08-30 14:01:10 -0700954 token_cache[0] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700955 ++token_costs;
956
957 tok_cost_ptr = &((*token_costs)[!tok]);
958
959 // ac tokens
960 for (c = 1; c < eob; c++) {
961 const int rc = scan[c];
962
963 v = qcoeff[rc];
Yaowu Xuf883b422016-08-30 14:01:10 -0700964 cost += av1_get_token_cost(v, &tok, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700965 pt = get_coef_context(nb, token_cache, c);
966 cost += (*tok_cost_ptr)[pt][tok];
Yaowu Xuf883b422016-08-30 14:01:10 -0700967 token_cache[rc] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700968 if (!--band_left) {
969 band_left = *band_count++;
970 ++token_costs;
971 }
972 tok_cost_ptr = &((*token_costs)[!tok]);
973 }
974
975 // eob token
976 if (band_left) {
977 pt = get_coef_context(nb, token_cache, c);
978 cost += (*token_costs)[0][pt][EOB_TOKEN];
979 }
980 }
981 }
982
Yaowu Xuc27fc142016-08-22 16:08:15 -0700983 return cost;
984}
985
Yaowu Xuf883b422016-08-30 14:01:10 -0700986static void dist_block(const AV1_COMP *cpi, MACROBLOCK *x, int plane, int block,
987 int blk_row, int blk_col, TX_SIZE tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700988 int64_t *out_dist, int64_t *out_sse) {
989 MACROBLOCKD *const xd = &x->e_mbd;
990 const struct macroblock_plane *const p = &x->plane[plane];
991 const struct macroblockd_plane *const pd = &xd->plane[plane];
992 if (cpi->sf.use_transform_domain_distortion) {
993 // Transform domain distortion computation is more accurate as it does
994 // not involve an inverse transform, but it is less accurate.
Jingning Hanb9c57272016-10-25 10:15:39 -0700995 const int buffer_length = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700996 int64_t this_sse;
997 int tx_type = get_tx_type(pd->plane_type, xd, block, tx_size);
998 int shift = (MAX_TX_SCALE - get_tx_scale(xd, tx_type, tx_size)) * 2;
999 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
1000 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Yaowu Xuf883b422016-08-30 14:01:10 -07001001#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001002 const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
Jingning Hanb9c57272016-10-25 10:15:39 -07001003 *out_dist =
1004 av1_highbd_block_error(coeff, dqcoeff, buffer_length, &this_sse, bd) >>
1005 shift;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001006#else
1007 *out_dist =
Jingning Hanb9c57272016-10-25 10:15:39 -07001008 av1_block_error(coeff, dqcoeff, buffer_length, &this_sse) >> shift;
Yaowu Xuf883b422016-08-30 14:01:10 -07001009#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001010 *out_sse = this_sse >> shift;
1011 } else {
1012 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Jingning Hanb9c57272016-10-25 10:15:39 -07001013 const int bsw = block_size_wide[tx_bsize];
1014 const int bsh = block_size_high[tx_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001015 const int src_stride = x->plane[plane].src.stride;
1016 const int dst_stride = xd->plane[plane].dst.stride;
Jingning Hanb9c57272016-10-25 10:15:39 -07001017 // Scale the transform block index to pixel unit.
1018 const int src_idx = (blk_row * src_stride + blk_col)
1019 << tx_size_wide_log2[0];
1020 const int dst_idx = (blk_row * dst_stride + blk_col)
1021 << tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001022 const uint8_t *src = &x->plane[plane].src.buf[src_idx];
1023 const uint8_t *dst = &xd->plane[plane].dst.buf[dst_idx];
1024 const tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1025 const uint16_t eob = p->eobs[block];
1026
1027 unsigned int tmp;
1028
1029 assert(cpi != NULL);
Jingning Hanb9c57272016-10-25 10:15:39 -07001030 assert(tx_size_wide_log2[0] == tx_size_high_log2[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001031
1032 cpi->fn_ptr[tx_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
1033 *out_sse = (int64_t)tmp * 16;
1034
1035 if (eob) {
1036 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Yaowu Xuf883b422016-08-30 14:01:10 -07001037#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001038 DECLARE_ALIGNED(16, uint16_t, recon16[MAX_TX_SQUARE]);
1039 uint8_t *recon = (uint8_t *)recon16;
1040#else
1041 DECLARE_ALIGNED(16, uint8_t, recon[MAX_TX_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07001042#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001043
1044 const PLANE_TYPE plane_type = plane == 0 ? PLANE_TYPE_Y : PLANE_TYPE_UV;
1045
1046 INV_TXFM_PARAM inv_txfm_param;
1047
1048 inv_txfm_param.tx_type = get_tx_type(plane_type, xd, block, tx_size);
1049 inv_txfm_param.tx_size = tx_size;
1050 inv_txfm_param.eob = eob;
1051 inv_txfm_param.lossless = xd->lossless[mbmi->segment_id];
1052
Yaowu Xuf883b422016-08-30 14:01:10 -07001053#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001054 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1055 recon = CONVERT_TO_BYTEPTR(recon);
1056 inv_txfm_param.bd = xd->bd;
Yaowu Xuf883b422016-08-30 14:01:10 -07001057 aom_highbd_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001058 NULL, 0, bsw, bsh, xd->bd);
1059 highbd_inv_txfm_add(dqcoeff, recon, MAX_TX_SIZE, &inv_txfm_param);
1060 } else
Yaowu Xuf883b422016-08-30 14:01:10 -07001061#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001062 {
Yaowu Xuf883b422016-08-30 14:01:10 -07001063 aom_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001064 bsw, bsh);
1065 inv_txfm_add(dqcoeff, recon, MAX_TX_SIZE, &inv_txfm_param);
1066 }
1067
1068 cpi->fn_ptr[tx_bsize].vf(src, src_stride, recon, MAX_TX_SIZE, &tmp);
1069 }
1070
1071 *out_dist = (int64_t)tmp * 16;
1072 }
1073}
1074
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001075static int rate_block(int plane, int block, int coeff_ctx, TX_SIZE tx_size,
Debargha Mukherjee29630542016-09-06 13:15:31 -07001076 struct rdcost_block_args *args) {
Angie Chiang22ba7512016-10-20 17:10:33 -07001077 return av1_cost_coeffs(&args->cpi->common, args->x, plane, block, coeff_ctx,
1078 tx_size, args->scan_order->scan,
1079 args->scan_order->neighbors,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001080 args->use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001081}
1082
1083static uint64_t sum_squares_2d(const int16_t *diff, int diff_stride,
1084 TX_SIZE tx_size) {
1085 uint64_t sse;
1086 switch (tx_size) {
1087#if CONFIG_EXT_TX
1088 case TX_4X8:
Yaowu Xuf883b422016-08-30 14:01:10 -07001089 sse = aom_sum_squares_2d_i16(diff, diff_stride, 4) +
1090 aom_sum_squares_2d_i16(diff + 4 * diff_stride, diff_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001091 break;
1092 case TX_8X4:
Yaowu Xuf883b422016-08-30 14:01:10 -07001093 sse = aom_sum_squares_2d_i16(diff, diff_stride, 4) +
1094 aom_sum_squares_2d_i16(diff + 4, diff_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001095 break;
1096 case TX_8X16:
Yaowu Xuf883b422016-08-30 14:01:10 -07001097 sse = aom_sum_squares_2d_i16(diff, diff_stride, 8) +
1098 aom_sum_squares_2d_i16(diff + 8 * diff_stride, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001099 break;
1100 case TX_16X8:
Yaowu Xuf883b422016-08-30 14:01:10 -07001101 sse = aom_sum_squares_2d_i16(diff, diff_stride, 8) +
1102 aom_sum_squares_2d_i16(diff + 8, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001103 break;
1104 case TX_16X32:
Yaowu Xuf883b422016-08-30 14:01:10 -07001105 sse = aom_sum_squares_2d_i16(diff, diff_stride, 16) +
1106 aom_sum_squares_2d_i16(diff + 16 * diff_stride, diff_stride, 16);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001107 break;
1108 case TX_32X16:
Yaowu Xuf883b422016-08-30 14:01:10 -07001109 sse = aom_sum_squares_2d_i16(diff, diff_stride, 16) +
1110 aom_sum_squares_2d_i16(diff + 16, diff_stride, 16);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001111 break;
1112#endif // CONFIG_EXT_TX
1113 default:
1114 assert(tx_size < TX_SIZES);
Jingning Hanc598cf82016-10-25 10:37:34 -07001115 sse = aom_sum_squares_2d_i16(diff, diff_stride, tx_size_wide[tx_size]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001116 break;
1117 }
1118 return sse;
1119}
1120
1121static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
1122 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
1123 struct rdcost_block_args *args = arg;
1124 MACROBLOCK *const x = args->x;
1125 MACROBLOCKD *const xd = &x->e_mbd;
1126 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -07001127 const AV1_COMMON *cm = &args->cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001128 int64_t rd1, rd2, rd;
1129 int rate;
1130 int64_t dist;
1131 int64_t sse;
Debargha Mukherjee29630542016-09-06 13:15:31 -07001132
Yaowu Xuc27fc142016-08-22 16:08:15 -07001133 int coeff_ctx = combine_entropy_contexts(*(args->t_above + blk_col),
1134 *(args->t_left + blk_row));
1135
1136 if (args->exit_early) return;
1137
1138 if (!is_inter_block(mbmi)) {
Urvang Joshi454280d2016-10-14 16:51:44 -07001139 struct encode_b_args b_args = {
Angie Chiangff6d8902016-10-21 11:02:09 -07001140 (AV1_COMMON *)cm, x, NULL, &mbmi->skip, args->t_above, args->t_left, 1
Yaowu Xuc27fc142016-08-22 16:08:15 -07001141 };
Yaowu Xuf883b422016-08-30 14:01:10 -07001142 av1_encode_block_intra(plane, block, blk_row, blk_col, plane_bsize, tx_size,
Urvang Joshi454280d2016-10-14 16:51:44 -07001143 &b_args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001144
1145 if (args->cpi->sf.use_transform_domain_distortion) {
1146 dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size, &dist,
1147 &sse);
1148 } else {
1149 // Note that the encode block_intra call above already calls
1150 // inv_txfm_add, so we can't just call dist_block here.
1151 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Yaowu Xuf883b422016-08-30 14:01:10 -07001152 const aom_variance_fn_t variance = args->cpi->fn_ptr[tx_bsize].vf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001153
1154 const struct macroblock_plane *const p = &x->plane[plane];
1155 const struct macroblockd_plane *const pd = &xd->plane[plane];
1156
1157 const int src_stride = p->src.stride;
1158 const int dst_stride = pd->dst.stride;
Jingning Hanc598cf82016-10-25 10:37:34 -07001159 const int diff_stride = block_size_wide[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001160
1161 const uint8_t *src = &p->src.buf[4 * (blk_row * src_stride + blk_col)];
1162 const uint8_t *dst = &pd->dst.buf[4 * (blk_row * dst_stride + blk_col)];
1163 const int16_t *diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
1164
1165 unsigned int tmp;
1166 sse = sum_squares_2d(diff, diff_stride, tx_size);
1167
Yaowu Xuf883b422016-08-30 14:01:10 -07001168#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001169 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
1170 sse = ROUND_POWER_OF_TWO(sse, (xd->bd - 8) * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07001171#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001172 sse = (int64_t)sse * 16;
1173
1174 variance(src, src_stride, dst, dst_stride, &tmp);
1175 dist = (int64_t)tmp * 16;
1176 }
1177 } else {
1178// full forward transform and quantization
1179#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07001180 av1_xform_quant_fp_nuq(cm, x, plane, block, blk_row, blk_col, plane_bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -07001181 tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001182#else
Angie Chiangff6d8902016-10-21 11:02:09 -07001183 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Yaowu Xuf883b422016-08-30 14:01:10 -07001184 AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001185#endif // CONFIG_NEW_QUANT
1186 if (x->plane[plane].eobs[block])
Angie Chiangff6d8902016-10-21 11:02:09 -07001187 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001188 dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size, &dist,
1189 &sse);
1190 }
1191
1192 rd = RDCOST(x->rdmult, x->rddiv, 0, dist);
1193 if (args->this_rd + rd > args->best_rd) {
1194 args->exit_early = 1;
1195 return;
1196 }
1197
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001198 rate = rate_block(plane, block, coeff_ctx, tx_size, args);
1199 args->t_above[blk_col] = (x->plane[plane].eobs[block] > 0);
1200 args->t_left[blk_row] = (x->plane[plane].eobs[block] > 0);
1201
Yaowu Xuc27fc142016-08-22 16:08:15 -07001202 rd1 = RDCOST(x->rdmult, x->rddiv, rate, dist);
1203 rd2 = RDCOST(x->rdmult, x->rddiv, 0, sse);
1204
1205 // TODO(jingning): temporarily enabled only for luma component
Yaowu Xuf883b422016-08-30 14:01:10 -07001206 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001207
1208 args->this_rate += rate;
1209 args->this_dist += dist;
1210 args->this_sse += sse;
1211 args->this_rd += rd;
1212
1213 if (args->this_rd > args->best_rd) {
1214 args->exit_early = 1;
1215 return;
1216 }
1217
1218 args->skippable &= !x->plane[plane].eobs[block];
1219}
1220
Yaowu Xuf883b422016-08-30 14:01:10 -07001221static void txfm_rd_in_plane(MACROBLOCK *x, const AV1_COMP *cpi, int *rate,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001222 int64_t *distortion, int *skippable, int64_t *sse,
1223 int64_t ref_best_rd, int plane, BLOCK_SIZE bsize,
1224 TX_SIZE tx_size, int use_fast_coef_casting) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001225 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001226 MACROBLOCKD *const xd = &x->e_mbd;
1227 const struct macroblockd_plane *const pd = &xd->plane[plane];
1228 TX_TYPE tx_type;
1229 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001230 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001231 args.x = x;
1232 args.cpi = cpi;
1233 args.best_rd = ref_best_rd;
1234 args.use_fast_coef_costing = use_fast_coef_casting;
1235 args.skippable = 1;
1236
1237 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1238
Yaowu Xuf883b422016-08-30 14:01:10 -07001239 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001240
1241 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001242 args.scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07001243 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001244
Yaowu Xuf883b422016-08-30 14:01:10 -07001245 av1_foreach_transformed_block_in_plane(xd, bsize, plane, block_rd_txfm,
1246 &args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001247 if (args.exit_early) {
1248 *rate = INT_MAX;
1249 *distortion = INT64_MAX;
1250 *sse = INT64_MAX;
1251 *skippable = 0;
1252 } else {
1253 *distortion = args.this_dist;
1254 *rate = args.this_rate;
1255 *sse = args.this_sse;
1256 *skippable = args.skippable;
1257 }
1258}
1259
1260#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001261void av1_txfm_rd_in_plane_supertx(MACROBLOCK *x, const AV1_COMP *cpi, int *rate,
1262 int64_t *distortion, int *skippable,
1263 int64_t *sse, int64_t ref_best_rd, int plane,
1264 BLOCK_SIZE bsize, TX_SIZE tx_size,
1265 int use_fast_coef_casting) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001266 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001267 MACROBLOCKD *const xd = &x->e_mbd;
1268 const struct macroblockd_plane *const pd = &xd->plane[plane];
1269 struct rdcost_block_args args;
1270 TX_TYPE tx_type;
1271
Yaowu Xuf883b422016-08-30 14:01:10 -07001272 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001273 args.cpi = cpi;
1274 args.x = x;
1275 args.best_rd = ref_best_rd;
1276 args.use_fast_coef_costing = use_fast_coef_casting;
1277
1278#if CONFIG_EXT_TX
1279 assert(tx_size < TX_SIZES);
1280#endif // CONFIG_EXT_TX
1281
1282 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1283
Yaowu Xuf883b422016-08-30 14:01:10 -07001284 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001285
1286 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001287 args.scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07001288 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001289
1290 block_rd_txfm(plane, 0, 0, 0, get_plane_block_size(bsize, pd), tx_size,
1291 &args);
1292
1293 if (args.exit_early) {
1294 *rate = INT_MAX;
1295 *distortion = INT64_MAX;
1296 *sse = INT64_MAX;
1297 *skippable = 0;
1298 } else {
1299 *distortion = args.this_dist;
1300 *rate = args.this_rate;
1301 *sse = args.this_sse;
1302 *skippable = !x->plane[plane].eobs[0];
1303 }
1304}
1305#endif // CONFIG_SUPERTX
1306
Urvang Joshi52648442016-10-13 17:27:51 -07001307static int64_t txfm_yrd(const AV1_COMP *const cpi, MACROBLOCK *x, int *r,
1308 int64_t *d, int *s, int64_t *sse, int64_t ref_best_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001309 BLOCK_SIZE bs, TX_TYPE tx_type, int tx_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07001310 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001311 MACROBLOCKD *const xd = &x->e_mbd;
1312 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1313 int64_t rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001314 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001315 int s0, s1;
1316 const int is_inter = is_inter_block(mbmi);
1317 const int tx_size_ctx = get_tx_size_context(xd);
1318 const int tx_size_cat =
1319 is_inter ? inter_tx_size_cat_lookup[bs] : intra_tx_size_cat_lookup[bs];
1320 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
Jingning Hanb0a71302016-10-25 16:28:49 -07001321 const int depth = tx_size_to_depth(coded_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001322 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
Jingning Hanb0a71302016-10-25 16:28:49 -07001323 const int r_tx_size = cpi->tx_size_cost[tx_size_cat][tx_size_ctx][depth];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001324
1325 assert(skip_prob > 0);
1326#if CONFIG_EXT_TX && CONFIG_RECT_TX
1327 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed_bsize(bs)));
1328#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1329
Yaowu Xuf883b422016-08-30 14:01:10 -07001330 s0 = av1_cost_bit(skip_prob, 0);
1331 s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001332
1333 mbmi->tx_type = tx_type;
1334 mbmi->tx_size = tx_size;
1335 txfm_rd_in_plane(x, cpi, r, d, s, sse, ref_best_rd, 0, bs, tx_size,
1336 cpi->sf.use_fast_coef_costing);
1337 if (*r == INT_MAX) return INT64_MAX;
1338#if CONFIG_EXT_TX
1339 if (get_ext_tx_types(tx_size, bs, is_inter) > 1 &&
1340 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
1341 const int ext_tx_set = get_ext_tx_set(tx_size, bs, is_inter);
1342 if (is_inter) {
1343 if (ext_tx_set > 0)
clang-format67948d32016-09-07 22:40:40 -07001344 *r +=
1345 cpi->inter_tx_type_costs[ext_tx_set][txsize_sqr_map[mbmi->tx_size]]
1346 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001347 } else {
1348 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
1349 *r += cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->mode]
1350 [mbmi->tx_type];
1351 }
1352 }
1353#else
1354 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1355 !FIXED_TX_TYPE) {
1356 if (is_inter) {
1357 *r += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
1358 } else {
1359 *r += cpi->intra_tx_type_costs[mbmi->tx_size]
1360 [intra_mode_to_tx_type_context[mbmi->mode]]
1361 [mbmi->tx_type];
1362 }
1363 }
1364#endif // CONFIG_EXT_TX
1365
1366 if (*s) {
1367 if (is_inter) {
1368 rd = RDCOST(x->rdmult, x->rddiv, s1, *sse);
1369 } else {
1370 rd = RDCOST(x->rdmult, x->rddiv, s1 + r_tx_size * tx_select, *sse);
1371 }
1372 } else {
1373 rd = RDCOST(x->rdmult, x->rddiv, *r + s0 + r_tx_size * tx_select, *d);
1374 }
1375
1376 if (tx_select) *r += r_tx_size;
1377
1378 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] && !(*s))
Yaowu Xuf883b422016-08-30 14:01:10 -07001379 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, *sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001380
1381 return rd;
1382}
1383
Urvang Joshi52648442016-10-13 17:27:51 -07001384static int64_t choose_tx_size_fix_type(const AV1_COMP *const cpi, BLOCK_SIZE bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001385 MACROBLOCK *x, int *rate,
1386 int64_t *distortion, int *skip,
1387 int64_t *psse, int64_t ref_best_rd,
1388 TX_TYPE tx_type, int prune) {
Urvang Joshi52648442016-10-13 17:27:51 -07001389 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001390 MACROBLOCKD *const xd = &x->e_mbd;
1391 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1392 int r, s;
1393 int64_t d, sse;
1394 int64_t rd = INT64_MAX;
1395 int n;
1396 int start_tx, end_tx;
1397 int64_t best_rd = INT64_MAX, last_rd = INT64_MAX;
1398 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
1399 TX_SIZE best_tx_size = max_tx_size;
1400 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
1401 const int is_inter = is_inter_block(mbmi);
1402#if CONFIG_EXT_TX
1403#if CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001404 int evaluate_rect_tx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001405#endif // CONFIG_RECT_TX
1406 int ext_tx_set;
1407#endif // CONFIG_EXT_TX
1408
1409 if (tx_select) {
1410#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001411 evaluate_rect_tx = is_rect_tx_allowed(xd, mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001412#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1413 start_tx = max_tx_size;
Hui Sueafb2e62016-10-18 10:21:36 -07001414 end_tx = (max_tx_size == TX_32X32) ? TX_8X8 : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001415 } else {
1416 const TX_SIZE chosen_tx_size =
1417 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
1418#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001419 evaluate_rect_tx = is_rect_tx(chosen_tx_size);
1420 assert(IMPLIES(evaluate_rect_tx, is_rect_tx_allowed(xd, mbmi)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001421#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1422 start_tx = chosen_tx_size;
1423 end_tx = chosen_tx_size;
1424 }
1425
1426 *distortion = INT64_MAX;
1427 *rate = INT_MAX;
1428 *skip = 0;
1429 *psse = INT64_MAX;
1430
1431 mbmi->tx_type = tx_type;
1432
1433#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001434 if (evaluate_rect_tx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001435 const TX_SIZE rect_tx_size = max_txsize_rect_lookup[bs];
Urvang Joshi368fbc92016-10-17 16:31:34 -07001436 ext_tx_set = get_ext_tx_set(rect_tx_size, bs, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001437 if (ext_tx_used_inter[ext_tx_set][tx_type]) {
1438 rd = txfm_yrd(cpi, x, &r, &d, &s, &sse, ref_best_rd, bs, tx_type,
1439 rect_tx_size);
1440 best_tx_size = rect_tx_size;
1441 best_rd = rd;
1442 *distortion = d;
1443 *rate = r;
1444 *skip = s;
1445 *psse = sse;
1446 }
1447 }
1448#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1449
1450 last_rd = INT64_MAX;
1451 for (n = start_tx; n >= end_tx; --n) {
1452#if CONFIG_EXT_TX && CONFIG_RECT_TX
1453 if (is_rect_tx(n)) break;
1454#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1455 if (FIXED_TX_TYPE && tx_type != get_default_tx_type(0, xd, 0, n)) continue;
1456 if (!is_inter && x->use_default_intra_tx_type &&
1457 tx_type != get_default_tx_type(0, xd, 0, n))
1458 continue;
1459 if (is_inter && x->use_default_inter_tx_type &&
1460 tx_type != get_default_tx_type(0, xd, 0, n))
1461 continue;
1462 if (max_tx_size == TX_32X32 && n == TX_4X4) continue;
1463#if CONFIG_EXT_TX
1464 ext_tx_set = get_ext_tx_set(n, bs, is_inter);
1465 if (is_inter) {
1466 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
1467 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1468 if (!do_tx_type_search(tx_type, prune)) continue;
1469 }
1470 } else {
1471 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1472 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
1473 }
1474 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
1475 }
1476#else // CONFIG_EXT_TX
1477 if (n >= TX_32X32 && tx_type != DCT_DCT) continue;
1478 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
1479 !do_tx_type_search(tx_type, prune))
1480 continue;
1481#endif // CONFIG_EXT_TX
1482
1483 rd = txfm_yrd(cpi, x, &r, &d, &s, &sse, ref_best_rd, bs, tx_type, n);
1484
1485 // Early termination in transform size search.
1486 if (cpi->sf.tx_size_search_breakout &&
1487 (rd == INT64_MAX || (s == 1 && tx_type != DCT_DCT && n < start_tx) ||
1488 (n < (int)max_tx_size && rd > last_rd)))
1489 break;
1490
1491 last_rd = rd;
1492 if (rd < best_rd) {
1493 best_tx_size = n;
1494 best_rd = rd;
1495 *distortion = d;
1496 *rate = r;
1497 *skip = s;
1498 *psse = sse;
1499 }
1500 }
1501 mbmi->tx_size = best_tx_size;
1502
1503 return best_rd;
1504}
1505
1506#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07001507static int64_t estimate_yrd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bs,
1508 MACROBLOCK *x, int *r, int64_t *d, int *s,
1509 int64_t *sse, int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001510 return txfm_yrd(cpi, x, r, d, s, sse, ref_best_rd, bs, DCT_DCT,
1511 max_txsize_lookup[bs]);
1512}
1513#endif // CONFIG_EXT_INTER
1514
Urvang Joshi52648442016-10-13 17:27:51 -07001515static void choose_largest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
1516 int *rate, int64_t *distortion, int *skip,
1517 int64_t *sse, int64_t ref_best_rd,
1518 BLOCK_SIZE bs) {
1519 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001520 MACROBLOCKD *const xd = &x->e_mbd;
1521 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1522 TX_TYPE tx_type, best_tx_type = DCT_DCT;
1523 int r, s;
1524 int64_t d, psse, this_rd, best_rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001525 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
1526 int s0 = av1_cost_bit(skip_prob, 0);
1527 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001528 const int is_inter = is_inter_block(mbmi);
1529 int prune = 0;
1530#if CONFIG_EXT_TX
1531 int ext_tx_set;
1532#endif // CONFIG_EXT_TX
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001533 *distortion = INT64_MAX;
1534 *rate = INT_MAX;
1535 *skip = 0;
1536 *sse = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001537
1538 mbmi->tx_size = tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
1539
1540#if CONFIG_EXT_TX
1541 ext_tx_set = get_ext_tx_set(mbmi->tx_size, bs, is_inter);
1542#endif // CONFIG_EXT_TX
1543
1544 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
1545#if CONFIG_EXT_TX
1546 prune = prune_tx_types(cpi, bs, x, xd, ext_tx_set);
1547#else
1548 prune = prune_tx_types(cpi, bs, x, xd, 0);
1549#endif
1550#if CONFIG_EXT_TX
1551 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1 &&
1552 !xd->lossless[mbmi->segment_id]) {
1553 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
1554 if (is_inter) {
1555 if (x->use_default_inter_tx_type &&
1556 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1557 continue;
1558 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
1559 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1560 if (!do_tx_type_search(tx_type, prune)) continue;
1561 }
1562 } else {
1563 if (x->use_default_intra_tx_type &&
1564 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1565 continue;
1566 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1567 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
1568 }
1569 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
1570 }
1571
1572 mbmi->tx_type = tx_type;
1573
1574 txfm_rd_in_plane(x, cpi, &r, &d, &s, &psse, ref_best_rd, 0, bs,
1575 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
1576
1577 if (r == INT_MAX) continue;
1578 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1) {
1579 if (is_inter) {
1580 if (ext_tx_set > 0)
1581 r += cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size]
1582 [mbmi->tx_type];
1583 } else {
1584 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
1585 r += cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->mode]
1586 [mbmi->tx_type];
1587 }
1588 }
1589
1590 if (s)
1591 this_rd = RDCOST(x->rdmult, x->rddiv, s1, psse);
1592 else
1593 this_rd = RDCOST(x->rdmult, x->rddiv, r + s0, d);
1594 if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] && !s)
Yaowu Xuf883b422016-08-30 14:01:10 -07001595 this_rd = AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, psse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001596
1597 if (this_rd < best_rd) {
1598 best_rd = this_rd;
1599 best_tx_type = mbmi->tx_type;
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001600 *distortion = d;
1601 *rate = r;
1602 *skip = s;
1603 *sse = psse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001604 }
1605 }
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001606 } else {
1607 mbmi->tx_type = DCT_DCT;
1608 txfm_rd_in_plane(x, cpi, rate, distortion, skip, sse, ref_best_rd, 0, bs,
1609 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001610 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001611#else // CONFIG_EXT_TX
1612 if (mbmi->tx_size < TX_32X32 && !xd->lossless[mbmi->segment_id]) {
1613 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
1614 if (!is_inter && x->use_default_intra_tx_type &&
1615 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1616 continue;
1617 if (is_inter && x->use_default_inter_tx_type &&
1618 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1619 continue;
1620 mbmi->tx_type = tx_type;
1621 txfm_rd_in_plane(x, cpi, &r, &d, &s, &psse, ref_best_rd, 0, bs,
1622 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
1623 if (r == INT_MAX) continue;
1624 if (is_inter) {
1625 r += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
1626 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
1627 !do_tx_type_search(tx_type, prune))
1628 continue;
1629 } else {
1630 r += cpi->intra_tx_type_costs[mbmi->tx_size]
1631 [intra_mode_to_tx_type_context[mbmi->mode]]
1632 [mbmi->tx_type];
1633 }
1634 if (s)
1635 this_rd = RDCOST(x->rdmult, x->rddiv, s1, psse);
1636 else
1637 this_rd = RDCOST(x->rdmult, x->rddiv, r + s0, d);
1638 if (is_inter && !xd->lossless[mbmi->segment_id] && !s)
Yaowu Xuf883b422016-08-30 14:01:10 -07001639 this_rd = AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, psse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001640
1641 if (this_rd < best_rd) {
1642 best_rd = this_rd;
1643 best_tx_type = mbmi->tx_type;
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001644 *distortion = d;
1645 *rate = r;
1646 *skip = s;
1647 *sse = psse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001648 }
1649 }
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001650 } else {
1651 mbmi->tx_type = DCT_DCT;
1652 txfm_rd_in_plane(x, cpi, rate, distortion, skip, sse, ref_best_rd, 0, bs,
1653 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001654 }
1655#endif // CONFIG_EXT_TX
1656 mbmi->tx_type = best_tx_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001657}
1658
Urvang Joshi52648442016-10-13 17:27:51 -07001659static void choose_smallest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
1660 int *rate, int64_t *distortion, int *skip,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001661 int64_t *sse, int64_t ref_best_rd,
1662 BLOCK_SIZE bs) {
1663 MACROBLOCKD *const xd = &x->e_mbd;
1664 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1665
1666 mbmi->tx_size = TX_4X4;
1667 mbmi->tx_type = DCT_DCT;
1668
1669 txfm_rd_in_plane(x, cpi, rate, distortion, skip, sse, ref_best_rd, 0, bs,
1670 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
1671}
1672
Urvang Joshi52648442016-10-13 17:27:51 -07001673static void choose_tx_size_type_from_rd(const AV1_COMP *const cpi,
1674 MACROBLOCK *x, int *rate,
Yaowu Xuf883b422016-08-30 14:01:10 -07001675 int64_t *distortion, int *skip,
1676 int64_t *psse, int64_t ref_best_rd,
1677 BLOCK_SIZE bs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001678 MACROBLOCKD *const xd = &x->e_mbd;
1679 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1680 int r, s;
1681 int64_t d, sse;
1682 int64_t rd = INT64_MAX;
1683 int64_t best_rd = INT64_MAX;
1684 TX_SIZE best_tx = max_txsize_lookup[bs];
1685 const int is_inter = is_inter_block(mbmi);
1686 TX_TYPE tx_type, best_tx_type = DCT_DCT;
1687 int prune = 0;
1688
1689 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
1690 // passing -1 in for tx_type indicates that all 1D
1691 // transforms should be considered for pruning
1692 prune = prune_tx_types(cpi, bs, x, xd, -1);
1693
1694 *distortion = INT64_MAX;
1695 *rate = INT_MAX;
1696 *skip = 0;
1697 *psse = INT64_MAX;
1698
1699 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
1700#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07001701 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001702#endif
1703 rd = choose_tx_size_fix_type(cpi, bs, x, &r, &d, &s, &sse, ref_best_rd,
1704 tx_type, prune);
1705 if (rd < best_rd) {
1706 best_rd = rd;
1707 *distortion = d;
1708 *rate = r;
1709 *skip = s;
1710 *psse = sse;
1711 best_tx_type = tx_type;
1712 best_tx = mbmi->tx_size;
1713 }
1714 }
1715
1716 mbmi->tx_size = best_tx;
1717 mbmi->tx_type = best_tx_type;
1718
1719#if !CONFIG_EXT_TX
1720 if (mbmi->tx_size >= TX_32X32) assert(mbmi->tx_type == DCT_DCT);
1721#endif
1722}
1723
Urvang Joshi52648442016-10-13 17:27:51 -07001724static void super_block_yrd(const AV1_COMP *const cpi, MACROBLOCK *x, int *rate,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001725 int64_t *distortion, int *skip, int64_t *psse,
1726 BLOCK_SIZE bs, int64_t ref_best_rd) {
1727 MACROBLOCKD *xd = &x->e_mbd;
1728 int64_t sse;
1729 int64_t *ret_sse = psse ? psse : &sse;
1730
1731 assert(bs == xd->mi[0]->mbmi.sb_type);
1732
1733 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
1734 choose_smallest_tx_size(cpi, x, rate, distortion, skip, ret_sse,
1735 ref_best_rd, bs);
1736 } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
1737 choose_largest_tx_size(cpi, x, rate, distortion, skip, ret_sse, ref_best_rd,
1738 bs);
1739 } else {
1740 choose_tx_size_type_from_rd(cpi, x, rate, distortion, skip, ret_sse,
1741 ref_best_rd, bs);
1742 }
1743}
1744
1745static int conditional_skipintra(PREDICTION_MODE mode,
1746 PREDICTION_MODE best_intra_mode) {
1747 if (mode == D117_PRED && best_intra_mode != V_PRED &&
1748 best_intra_mode != D135_PRED)
1749 return 1;
1750 if (mode == D63_PRED && best_intra_mode != V_PRED &&
1751 best_intra_mode != D45_PRED)
1752 return 1;
1753 if (mode == D207_PRED && best_intra_mode != H_PRED &&
1754 best_intra_mode != D45_PRED)
1755 return 1;
1756 if (mode == D153_PRED && best_intra_mode != H_PRED &&
1757 best_intra_mode != D135_PRED)
1758 return 1;
1759 return 0;
1760}
1761
Urvang Joshib100db72016-10-12 16:28:56 -07001762#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001763static int rd_pick_palette_intra_sby(
Urvang Joshi52648442016-10-13 17:27:51 -07001764 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int palette_ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001765 int dc_mode_cost, PALETTE_MODE_INFO *palette_mode_info,
1766 uint8_t *best_palette_color_map, TX_SIZE *best_tx, TX_TYPE *best_tx_type,
1767 PREDICTION_MODE *mode_selected, int64_t *best_rd) {
1768 int rate_overhead = 0;
1769 MACROBLOCKD *const xd = &x->e_mbd;
1770 MODE_INFO *const mic = xd->mi[0];
1771 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
1772 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
1773 int this_rate, this_rate_tokenonly, s, colors, n;
1774 int64_t this_distortion, this_rd;
1775 const int src_stride = x->plane[0].src.stride;
1776 const uint8_t *const src = x->plane[0].src.buf;
1777
1778 assert(cpi->common.allow_screen_content_tools);
1779
Yaowu Xuf883b422016-08-30 14:01:10 -07001780#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001781 if (cpi->common.use_highbitdepth)
Yaowu Xuf883b422016-08-30 14:01:10 -07001782 colors = av1_count_colors_highbd(src, src_stride, rows, cols,
1783 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001784 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001785#endif // CONFIG_AOM_HIGHBITDEPTH
1786 colors = av1_count_colors(src, src_stride, rows, cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001787 palette_mode_info->palette_size[0] = 0;
hui su5db97432016-10-14 16:10:14 -07001788#if CONFIG_FILTER_INTRA
1789 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0;
1790#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07001791
1792 if (colors > 1 && colors <= 64) {
1793 int r, c, i, j, k;
1794 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07001795 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001796 float *const data = x->palette_buffer->kmeans_data_buf;
1797 float centroids[PALETTE_MAX_SIZE];
1798 uint8_t *const color_map = xd->plane[0].color_index_map;
1799 float lb, ub, val;
1800 MB_MODE_INFO *const mbmi = &mic->mbmi;
1801 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuf883b422016-08-30 14:01:10 -07001802#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001803 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
1804 if (cpi->common.use_highbitdepth)
1805 lb = ub = src16[0];
1806 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001807#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001808 lb = ub = src[0];
1809
Yaowu Xuf883b422016-08-30 14:01:10 -07001810#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001811 if (cpi->common.use_highbitdepth) {
1812 for (r = 0; r < rows; ++r) {
1813 for (c = 0; c < cols; ++c) {
1814 val = src16[r * src_stride + c];
1815 data[r * cols + c] = val;
1816 if (val < lb)
1817 lb = val;
1818 else if (val > ub)
1819 ub = val;
1820 }
1821 }
1822 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001823#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001824 for (r = 0; r < rows; ++r) {
1825 for (c = 0; c < cols; ++c) {
1826 val = src[r * src_stride + c];
1827 data[r * cols + c] = val;
1828 if (val < lb)
1829 lb = val;
1830 else if (val > ub)
1831 ub = val;
1832 }
1833 }
Yaowu Xuf883b422016-08-30 14:01:10 -07001834#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001835 }
Yaowu Xuf883b422016-08-30 14:01:10 -07001836#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001837
1838 mbmi->mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07001839#if CONFIG_FILTER_INTRA
1840 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
1841#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07001842
1843 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return 0;
1844
1845 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
1846 --n) {
1847 for (i = 0; i < n; ++i)
1848 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
Yaowu Xuf883b422016-08-30 14:01:10 -07001849 av1_k_means(data, centroids, color_map, rows * cols, n, 1, max_itr);
1850 k = av1_remove_duplicates(centroids, n);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001851
Yaowu Xuf883b422016-08-30 14:01:10 -07001852#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001853 if (cpi->common.use_highbitdepth)
1854 for (i = 0; i < k; ++i)
1855 pmi->palette_colors[i] =
1856 clip_pixel_highbd((int)centroids[i], cpi->common.bit_depth);
1857 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001858#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001859 for (i = 0; i < k; ++i)
1860 pmi->palette_colors[i] = clip_pixel((int)centroids[i]);
1861 pmi->palette_size[0] = k;
1862
Yaowu Xuf883b422016-08-30 14:01:10 -07001863 av1_calc_indices(data, centroids, color_map, rows * cols, k, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001864
1865 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s, NULL,
1866 bsize, *best_rd);
1867 if (this_rate_tokenonly == INT_MAX) continue;
1868
1869 this_rate =
1870 this_rate_tokenonly + dc_mode_cost +
Yaowu Xuf883b422016-08-30 14:01:10 -07001871 cpi->common.bit_depth * k * av1_cost_bit(128, 0) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07001872 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - 2] +
1873 write_uniform_cost(k, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07001874 av1_cost_bit(
1875 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07001876 1);
1877 for (i = 0; i < rows; ++i) {
1878 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07001879 int color_idx;
1880 const int color_ctx = av1_get_palette_color_context(
1881 color_map, cols, i, j, k, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001882 assert(color_idx >= 0 && color_idx < k);
1883 this_rate += cpi->palette_y_color_cost[k - 2][color_ctx][color_idx];
1884 }
1885 }
1886 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
1887
1888 if (this_rd < *best_rd) {
1889 *best_rd = this_rd;
1890 *palette_mode_info = *pmi;
1891 memcpy(best_palette_color_map, color_map,
1892 rows * cols * sizeof(color_map[0]));
1893 *mode_selected = DC_PRED;
1894 *best_tx = mbmi->tx_size;
1895 *best_tx_type = mbmi->tx_type;
1896 rate_overhead = this_rate - this_rate_tokenonly;
1897 }
1898 }
1899 }
1900 return rate_overhead;
1901}
Urvang Joshib100db72016-10-12 16:28:56 -07001902#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001903
Urvang Joshi52648442016-10-13 17:27:51 -07001904static int64_t rd_pick_intra4x4block(
1905 const AV1_COMP *const cpi, MACROBLOCK *x, int row, int col,
1906 PREDICTION_MODE *best_mode, const int *bmode_costs, ENTROPY_CONTEXT *a,
1907 ENTROPY_CONTEXT *l, int *bestrate, int *bestratey, int64_t *bestdistortion,
1908 BLOCK_SIZE bsize, int *y_skip, int64_t rd_thresh) {
Angie Chiang22ba7512016-10-20 17:10:33 -07001909 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001910 PREDICTION_MODE mode;
1911 MACROBLOCKD *const xd = &x->e_mbd;
1912 int64_t best_rd = rd_thresh;
1913 struct macroblock_plane *p = &x->plane[0];
1914 struct macroblockd_plane *pd = &xd->plane[0];
1915 const int src_stride = p->src.stride;
1916 const int dst_stride = pd->dst.stride;
1917 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
1918 uint8_t *dst_init = &pd->dst.buf[row * 4 * src_stride + col * 4];
1919 ENTROPY_CONTEXT ta[2], tempa[2];
1920 ENTROPY_CONTEXT tl[2], templ[2];
1921 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1922 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1923 int idx, idy;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001924 int best_can_skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001925 uint8_t best_dst[8 * 8];
Yaowu Xuf883b422016-08-30 14:01:10 -07001926#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001927 uint16_t best_dst16[8 * 8];
1928#endif
1929
1930 memcpy(ta, a, num_4x4_blocks_wide * sizeof(a[0]));
1931 memcpy(tl, l, num_4x4_blocks_high * sizeof(l[0]));
1932 xd->mi[0]->mbmi.tx_size = TX_4X4;
Urvang Joshib100db72016-10-12 16:28:56 -07001933#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001934 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07001935#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001936
Yaowu Xuf883b422016-08-30 14:01:10 -07001937#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001938 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1939 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
1940 int64_t this_rd;
1941 int ratey = 0;
1942 int64_t distortion = 0;
1943 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001944 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001945
1946 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode))) continue;
1947
1948 // Only do the oblique modes if the best so far is
1949 // one of the neighboring directional modes
1950 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
1951 if (conditional_skipintra(mode, *best_mode)) continue;
1952 }
1953
1954 memcpy(tempa, ta, num_4x4_blocks_wide * sizeof(ta[0]));
1955 memcpy(templ, tl, num_4x4_blocks_high * sizeof(tl[0]));
1956
1957 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
1958 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
1959 const int block = (row + idy) * 2 + (col + idx);
1960 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
1961 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
1962 int16_t *const src_diff =
Yaowu Xuf883b422016-08-30 14:01:10 -07001963 av1_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001964 xd->mi[0]->bmi[block].as_mode = mode;
Jingning Hanc4c99da2016-10-24 10:27:28 -07001965 av1_predict_intra_block(xd, pd->width, pd->height, TX_4X4, mode, dst,
1966 dst_stride, dst, dst_stride, col + idx,
1967 row + idy, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07001968 aom_highbd_subtract_block(4, 4, src_diff, 8, src, src_stride, dst,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001969 dst_stride, xd->bd);
1970 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
1971 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07001972 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001973 const int coeff_ctx =
1974 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001975#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07001976 av1_xform_quant_fp_nuq(cm, x, 0, block, row + idy, col + idx,
1977 BLOCK_8X8, TX_4X4, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001978#else
Angie Chiangff6d8902016-10-21 11:02:09 -07001979 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Yaowu Xuf883b422016-08-30 14:01:10 -07001980 TX_4X4, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001981#endif // CONFIG_NEW_QUANT
Angie Chiang22ba7512016-10-20 17:10:33 -07001982 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001983 scan_order->scan, scan_order->neighbors,
1984 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001985 *(tempa + idx) = !(p->eobs[block] == 0);
1986 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001987 can_skip &= (p->eobs[block] == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001988 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1989 goto next_highbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07001990 av1_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
1991 dst_stride, p->eobs[block], xd->bd,
1992 DCT_DCT, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001993 } else {
1994 int64_t dist;
1995 unsigned int tmp;
1996 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07001997 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001998 const int coeff_ctx =
1999 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
2000#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002001 av1_xform_quant_fp_nuq(cm, x, 0, block, row + idy, col + idx,
2002 BLOCK_8X8, TX_4X4, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002003#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002004 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Yaowu Xuf883b422016-08-30 14:01:10 -07002005 TX_4X4, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002006#endif // CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002007 av1_optimize_b(cm, x, 0, block, TX_4X4, coeff_ctx);
Angie Chiang22ba7512016-10-20 17:10:33 -07002008 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002009 scan_order->scan, scan_order->neighbors,
2010 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002011 *(tempa + idx) = !(p->eobs[block] == 0);
2012 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002013 can_skip &= (p->eobs[block] == 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07002014 av1_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2015 dst_stride, p->eobs[block], xd->bd,
2016 tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002017 cpi->fn_ptr[BLOCK_4X4].vf(src, src_stride, dst, dst_stride, &tmp);
2018 dist = (int64_t)tmp << 4;
2019 distortion += dist;
2020 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2021 goto next_highbd;
2022 }
2023 }
2024 }
2025
2026 rate += ratey;
2027 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2028
2029 if (this_rd < best_rd) {
2030 *bestrate = rate;
2031 *bestratey = ratey;
2032 *bestdistortion = distortion;
2033 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002034 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002035 *best_mode = mode;
2036 memcpy(a, tempa, num_4x4_blocks_wide * sizeof(tempa[0]));
2037 memcpy(l, templ, num_4x4_blocks_high * sizeof(templ[0]));
2038 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
2039 memcpy(best_dst16 + idy * 8,
2040 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
2041 num_4x4_blocks_wide * 4 * sizeof(uint16_t));
2042 }
2043 }
2044 next_highbd : {}
2045 }
2046
2047 if (best_rd >= rd_thresh) return best_rd;
2048
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002049 if (y_skip) *y_skip &= best_can_skip;
2050
Yaowu Xuc27fc142016-08-22 16:08:15 -07002051 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
2052 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
2053 best_dst16 + idy * 8, num_4x4_blocks_wide * 4 * sizeof(uint16_t));
2054 }
2055
2056 return best_rd;
2057 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002058#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002059
2060 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2061 int64_t this_rd;
2062 int ratey = 0;
2063 int64_t distortion = 0;
2064 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002065 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002066
2067 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode))) continue;
2068
2069 // Only do the oblique modes if the best so far is
2070 // one of the neighboring directional modes
2071 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2072 if (conditional_skipintra(mode, *best_mode)) continue;
2073 }
2074
2075 memcpy(tempa, ta, num_4x4_blocks_wide * sizeof(ta[0]));
2076 memcpy(templ, tl, num_4x4_blocks_high * sizeof(tl[0]));
2077
2078 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
2079 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
2080 const int block = (row + idy) * 2 + (col + idx);
2081 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2082 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
2083 int16_t *const src_diff =
Yaowu Xuf883b422016-08-30 14:01:10 -07002084 av1_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002085 xd->mi[0]->bmi[block].as_mode = mode;
Jingning Hanc4c99da2016-10-24 10:27:28 -07002086 av1_predict_intra_block(xd, pd->width, pd->height, TX_4X4, mode, dst,
2087 dst_stride, dst, dst_stride, col + idx,
2088 row + idy, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07002089 aom_subtract_block(4, 4, src_diff, 8, src, src_stride, dst, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002090
2091 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
2092 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002093 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002094 const int coeff_ctx =
2095 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002096#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002097 av1_xform_quant_fp_nuq(cm, x, 0, block, row + idy, col + idx,
2098 BLOCK_8X8, TX_4X4, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002099#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002100 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2101 TX_4X4, AV1_XFORM_QUANT_B);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002102#endif // CONFIG_NEW_QUANT
Angie Chiang22ba7512016-10-20 17:10:33 -07002103 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002104 scan_order->scan, scan_order->neighbors,
2105 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002106 *(tempa + idx) = !(p->eobs[block] == 0);
2107 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002108 can_skip &= (p->eobs[block] == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002109 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2110 goto next;
Yaowu Xuf883b422016-08-30 14:01:10 -07002111 av1_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2112 dst_stride, p->eobs[block], DCT_DCT, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002113 } else {
2114 int64_t dist;
2115 unsigned int tmp;
2116 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002117 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002118 const int coeff_ctx =
2119 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
2120#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002121 av1_xform_quant_fp_nuq(cm, x, 0, block, row + idy, col + idx,
2122 BLOCK_8X8, TX_4X4, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002123#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002124 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2125 TX_4X4, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002126#endif // CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002127 av1_optimize_b(cm, x, 0, block, TX_4X4, coeff_ctx);
Angie Chiang22ba7512016-10-20 17:10:33 -07002128 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002129 scan_order->scan, scan_order->neighbors,
2130 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002131 *(tempa + idx) = !(p->eobs[block] == 0);
2132 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002133 can_skip &= (p->eobs[block] == 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07002134 av1_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2135 dst_stride, p->eobs[block], tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002136 cpi->fn_ptr[BLOCK_4X4].vf(src, src_stride, dst, dst_stride, &tmp);
2137 dist = (int64_t)tmp << 4;
2138 distortion += dist;
2139 // To use the pixel domain distortion, the step below needs to be
2140 // put behind the inv txfm. Compared to calculating the distortion
2141 // in the frequency domain, the overhead of encoding effort is low.
2142 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2143 goto next;
2144 }
2145 }
2146 }
2147
2148 rate += ratey;
2149 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2150
2151 if (this_rd < best_rd) {
2152 *bestrate = rate;
2153 *bestratey = ratey;
2154 *bestdistortion = distortion;
2155 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002156 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002157 *best_mode = mode;
2158 memcpy(a, tempa, num_4x4_blocks_wide * sizeof(tempa[0]));
2159 memcpy(l, templ, num_4x4_blocks_high * sizeof(templ[0]));
2160 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
2161 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
2162 num_4x4_blocks_wide * 4);
2163 }
2164 next : {}
2165 }
2166
2167 if (best_rd >= rd_thresh) return best_rd;
2168
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002169 if (y_skip) *y_skip &= best_can_skip;
2170
Yaowu Xuc27fc142016-08-22 16:08:15 -07002171 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
2172 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
2173 num_4x4_blocks_wide * 4);
2174
2175 return best_rd;
2176}
2177
Urvang Joshi52648442016-10-13 17:27:51 -07002178static int64_t rd_pick_intra_sub_8x8_y_mode(const AV1_COMP *const cpi,
2179 MACROBLOCK *mb, int *rate,
2180 int *rate_y, int64_t *distortion,
2181 int *y_skip, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002182 int i, j;
2183 const MACROBLOCKD *const xd = &mb->e_mbd;
2184 MODE_INFO *const mic = xd->mi[0];
2185 const MODE_INFO *above_mi = xd->above_mi;
2186 const MODE_INFO *left_mi = xd->left_mi;
2187 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
2188 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2189 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2190 int idx, idy;
2191 int cost = 0;
2192 int64_t total_distortion = 0;
2193 int tot_rate_y = 0;
2194 int64_t total_rd = 0;
2195 const int *bmode_costs = cpi->mbmode_cost[0];
2196
2197#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002198 mic->mbmi.intra_filter = INTRA_FILTER_LINEAR;
2199#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002200#if CONFIG_FILTER_INTRA
2201 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2202#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002203
2204 // TODO(any): Add search of the tx_type to improve rd performance at the
2205 // expense of speed.
2206 mic->mbmi.tx_type = DCT_DCT;
2207 mic->mbmi.tx_size = TX_4X4;
2208
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002209 if (y_skip) *y_skip = 1;
2210
Yaowu Xuc27fc142016-08-22 16:08:15 -07002211 // Pick modes for each sub-block (of size 4x4, 4x8, or 8x4) in an 8x8 block.
2212 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
2213 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
2214 PREDICTION_MODE best_mode = DC_PRED;
2215 int r = INT_MAX, ry = INT_MAX;
2216 int64_t d = INT64_MAX, this_rd = INT64_MAX;
2217 i = idy * 2 + idx;
2218 if (cpi->common.frame_type == KEY_FRAME) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002219 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, i);
2220 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, i);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002221
2222 bmode_costs = cpi->y_mode_costs[A][L];
2223 }
2224
2225 this_rd = rd_pick_intra4x4block(
2226 cpi, mb, idy, idx, &best_mode, bmode_costs,
2227 xd->plane[0].above_context + idx, xd->plane[0].left_context + idy, &r,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002228 &ry, &d, bsize, y_skip, best_rd - total_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002229 if (this_rd >= best_rd - total_rd) return INT64_MAX;
2230
2231 total_rd += this_rd;
2232 cost += r;
2233 total_distortion += d;
2234 tot_rate_y += ry;
2235
2236 mic->bmi[i].as_mode = best_mode;
2237 for (j = 1; j < num_4x4_blocks_high; ++j)
2238 mic->bmi[i + j * 2].as_mode = best_mode;
2239 for (j = 1; j < num_4x4_blocks_wide; ++j)
2240 mic->bmi[i + j].as_mode = best_mode;
2241
2242 if (total_rd >= best_rd) return INT64_MAX;
2243 }
2244 }
2245 mic->mbmi.mode = mic->bmi[3].as_mode;
2246
2247 // Add in the cost of the transform type
2248 if (!xd->lossless[mic->mbmi.segment_id]) {
2249 int rate_tx_type = 0;
2250#if CONFIG_EXT_TX
2251 if (get_ext_tx_types(TX_4X4, bsize, 0) > 1) {
2252 const int eset = get_ext_tx_set(TX_4X4, bsize, 0);
clang-format67948d32016-09-07 22:40:40 -07002253 rate_tx_type = cpi->intra_tx_type_costs[eset][TX_4X4][mic->mbmi.mode]
2254 [mic->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002255 }
2256#else
clang-format67948d32016-09-07 22:40:40 -07002257 rate_tx_type =
2258 cpi->intra_tx_type_costs[TX_4X4]
2259 [intra_mode_to_tx_type_context[mic->mbmi.mode]]
2260 [mic->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002261#endif
2262 assert(mic->mbmi.tx_size == TX_4X4);
2263 cost += rate_tx_type;
2264 tot_rate_y += rate_tx_type;
2265 }
2266
2267 *rate = cost;
2268 *rate_y = tot_rate_y;
2269 *distortion = total_distortion;
2270
2271 return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
2272}
2273
hui su5db97432016-10-14 16:10:14 -07002274#if CONFIG_FILTER_INTRA
2275// Return 1 if an filter intra mode is selected; return 0 otherwise.
2276static int rd_pick_filter_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2277 int *rate, int *rate_tokenonly,
2278 int64_t *distortion, int *skippable,
2279 BLOCK_SIZE bsize, int mode_cost,
2280 int64_t *best_rd, uint16_t skip_mask) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002281 MACROBLOCKD *const xd = &x->e_mbd;
2282 MODE_INFO *const mic = xd->mi[0];
2283 MB_MODE_INFO *mbmi = &mic->mbmi;
2284 int this_rate, this_rate_tokenonly, s;
hui su5db97432016-10-14 16:10:14 -07002285 int filter_intra_selected_flag = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002286 int64_t this_distortion, this_rd;
hui su5db97432016-10-14 16:10:14 -07002287 FILTER_INTRA_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002288 TX_SIZE best_tx_size = TX_4X4;
hui su5db97432016-10-14 16:10:14 -07002289 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002290 TX_TYPE best_tx_type;
2291
hui su5db97432016-10-14 16:10:14 -07002292 av1_zero(filter_intra_mode_info);
2293 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002294 mbmi->mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07002295#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002296 mbmi->palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002297#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002298
2299 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
2300 if (skip_mask & (1 << mode)) continue;
hui su5db97432016-10-14 16:10:14 -07002301 mbmi->filter_intra_mode_info.filter_intra_mode[0] = mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002302 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s, NULL,
2303 bsize, *best_rd);
2304 if (this_rate_tokenonly == INT_MAX) continue;
2305
2306 this_rate = this_rate_tokenonly +
hui su5db97432016-10-14 16:10:14 -07002307 av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07002308 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
2309 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
2310
2311 if (this_rd < *best_rd) {
2312 *best_rd = this_rd;
2313 best_tx_size = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07002314 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002315 best_tx_type = mic->mbmi.tx_type;
2316 *rate = this_rate;
2317 *rate_tokenonly = this_rate_tokenonly;
2318 *distortion = this_distortion;
2319 *skippable = s;
hui su5db97432016-10-14 16:10:14 -07002320 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002321 }
2322 }
2323
hui su5db97432016-10-14 16:10:14 -07002324 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002325 mbmi->mode = DC_PRED;
2326 mbmi->tx_size = best_tx_size;
hui su5db97432016-10-14 16:10:14 -07002327 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] =
2328 filter_intra_mode_info.use_filter_intra_mode[0];
2329 mbmi->filter_intra_mode_info.filter_intra_mode[0] =
2330 filter_intra_mode_info.filter_intra_mode[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002331 mbmi->tx_type = best_tx_type;
2332 return 1;
2333 } else {
2334 return 0;
2335 }
2336}
hui su5db97432016-10-14 16:10:14 -07002337#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002338
hui su5db97432016-10-14 16:10:14 -07002339#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002340static void pick_intra_angle_routine_sby(
Urvang Joshi52648442016-10-13 17:27:51 -07002341 const AV1_COMP *const cpi, MACROBLOCK *x, int *rate, int *rate_tokenonly,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002342 int64_t *distortion, int *skippable, int *best_angle_delta,
2343 TX_SIZE *best_tx_size, TX_TYPE *best_tx_type, INTRA_FILTER *best_filter,
2344 BLOCK_SIZE bsize, int rate_overhead, int64_t *best_rd) {
2345 int this_rate, this_rate_tokenonly, s;
2346 int64_t this_distortion, this_rd;
2347 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
2348 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s, NULL,
2349 bsize, *best_rd);
2350 if (this_rate_tokenonly == INT_MAX) return;
2351
2352 this_rate = this_rate_tokenonly + rate_overhead;
2353 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
2354
2355 if (this_rd < *best_rd) {
2356 *best_rd = this_rd;
2357 *best_angle_delta = mbmi->angle_delta[0];
2358 *best_tx_size = mbmi->tx_size;
2359 *best_filter = mbmi->intra_filter;
2360 *best_tx_type = mbmi->tx_type;
2361 *rate = this_rate;
2362 *rate_tokenonly = this_rate_tokenonly;
2363 *distortion = this_distortion;
2364 *skippable = s;
2365 }
2366}
2367
Urvang Joshi52648442016-10-13 17:27:51 -07002368static int64_t rd_pick_intra_angle_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2369 int *rate, int *rate_tokenonly,
2370 int64_t *distortion, int *skippable,
2371 BLOCK_SIZE bsize, int rate_overhead,
2372 int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002373 MACROBLOCKD *const xd = &x->e_mbd;
2374 MODE_INFO *const mic = xd->mi[0];
2375 MB_MODE_INFO *mbmi = &mic->mbmi;
2376 int this_rate, this_rate_tokenonly, s;
2377 int angle_delta, best_angle_delta = 0, p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07002378 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002379 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
2380 const double rd_adjust = 1.2;
2381 int64_t this_distortion, this_rd;
2382 TX_SIZE best_tx_size = mic->mbmi.tx_size;
2383 TX_TYPE best_tx_type = mbmi->tx_type;
2384
2385 if (ANGLE_FAST_SEARCH) {
2386 int deltas_level1[3] = { 0, -2, 2 };
2387 int deltas_level2[3][2] = {
2388 { -1, 1 }, { -3, -1 }, { 1, 3 },
2389 };
2390 const int level1 = 3, level2 = 2;
2391 int i, j, best_i = -1;
2392
2393 for (i = 0; i < level1; ++i) {
2394 mic->mbmi.angle_delta[0] = deltas_level1[i];
2395 p_angle =
2396 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
2397 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2398 int64_t tmp_best_rd;
Yaowu Xuf883b422016-08-30 14:01:10 -07002399 if ((FILTER_FAST_SEARCH || !av1_is_intra_filter_switchable(p_angle)) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002400 filter != INTRA_FILTER_LINEAR)
2401 continue;
2402 mic->mbmi.intra_filter = filter;
2403 tmp_best_rd =
2404 (i == 0 && filter == INTRA_FILTER_LINEAR && best_rd < INT64_MAX)
2405 ? (int64_t)(best_rd * rd_adjust)
2406 : best_rd;
2407 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s,
2408 NULL, bsize, tmp_best_rd);
2409 if (this_rate_tokenonly == INT_MAX) {
2410 if (i == 0 && filter == INTRA_FILTER_LINEAR)
2411 return best_rd;
2412 else
2413 continue;
2414 }
2415 this_rate = this_rate_tokenonly + rate_overhead +
2416 cpi->intra_filter_cost[intra_filter_ctx][filter];
2417 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
2418 if (i == 0 && filter == INTRA_FILTER_LINEAR && best_rd < INT64_MAX &&
2419 this_rd > best_rd * rd_adjust)
2420 return best_rd;
2421 if (this_rd < best_rd) {
2422 best_i = i;
2423 best_rd = this_rd;
2424 best_angle_delta = mbmi->angle_delta[0];
2425 best_tx_size = mbmi->tx_size;
2426 best_filter = mbmi->intra_filter;
2427 best_tx_type = mbmi->tx_type;
2428 *rate = this_rate;
2429 *rate_tokenonly = this_rate_tokenonly;
2430 *distortion = this_distortion;
2431 *skippable = s;
2432 }
2433 }
2434 }
2435
2436 if (best_i >= 0) {
2437 for (j = 0; j < level2; ++j) {
2438 mic->mbmi.angle_delta[0] = deltas_level2[best_i][j];
2439 p_angle =
2440 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
2441 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2442 mic->mbmi.intra_filter = filter;
2443 if ((FILTER_FAST_SEARCH ||
Yaowu Xuf883b422016-08-30 14:01:10 -07002444 !av1_is_intra_filter_switchable(p_angle)) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002445 filter != INTRA_FILTER_LINEAR)
2446 continue;
2447 pick_intra_angle_routine_sby(
2448 cpi, x, rate, rate_tokenonly, distortion, skippable,
2449 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
2450 bsize,
2451 rate_overhead + cpi->intra_filter_cost[intra_filter_ctx][filter],
2452 &best_rd);
2453 }
2454 }
2455 }
2456 } else {
2457 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
2458 ++angle_delta) {
2459 mbmi->angle_delta[0] = angle_delta;
2460 p_angle =
2461 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
2462 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2463 mic->mbmi.intra_filter = filter;
Yaowu Xuf883b422016-08-30 14:01:10 -07002464 if ((FILTER_FAST_SEARCH || !av1_is_intra_filter_switchable(p_angle)) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002465 filter != INTRA_FILTER_LINEAR)
2466 continue;
2467 pick_intra_angle_routine_sby(
2468 cpi, x, rate, rate_tokenonly, distortion, skippable,
2469 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
2470 bsize,
2471 rate_overhead + cpi->intra_filter_cost[intra_filter_ctx][filter],
2472 &best_rd);
2473 }
2474 }
2475 }
2476
2477 if (FILTER_FAST_SEARCH && *rate_tokenonly < INT_MAX) {
2478 mbmi->angle_delta[0] = best_angle_delta;
2479 p_angle = mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07002480 if (av1_is_intra_filter_switchable(p_angle)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002481 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
2482 mic->mbmi.intra_filter = filter;
2483 pick_intra_angle_routine_sby(
2484 cpi, x, rate, rate_tokenonly, distortion, skippable,
2485 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
2486 bsize,
2487 rate_overhead + cpi->intra_filter_cost[intra_filter_ctx][filter],
2488 &best_rd);
2489 }
2490 }
2491 }
2492
2493 mbmi->tx_size = best_tx_size;
2494 mbmi->angle_delta[0] = best_angle_delta;
2495 mic->mbmi.intra_filter = best_filter;
2496 mbmi->tx_type = best_tx_type;
2497 return best_rd;
2498}
2499
2500// Indices are sign, integer, and fractional part of the gradient value
2501static const uint8_t gradient_to_angle_bin[2][7][16] = {
2502 {
2503 { 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0 },
2504 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
2505 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
2506 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
2507 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
2508 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2509 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2510 },
2511 {
2512 { 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4 },
2513 { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3 },
2514 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2515 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2516 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2517 { 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2518 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2519 },
2520};
2521
2522static const uint8_t mode_to_angle_bin[INTRA_MODES] = {
2523 0, 2, 6, 0, 4, 3, 5, 7, 1, 0,
2524};
2525
2526static void angle_estimation(const uint8_t *src, int src_stride, int rows,
2527 int cols, uint8_t *directional_mode_skip_mask) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002528 int i, r, c, index, dx, dy, temp, sn, remd, quot;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002529 uint64_t hist[DIRECTIONAL_MODES];
2530 uint64_t hist_sum = 0;
2531
2532 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
2533 src += src_stride;
2534 for (r = 1; r < rows; ++r) {
2535 for (c = 1; c < cols; ++c) {
2536 dx = src[c] - src[c - 1];
2537 dy = src[c] - src[c - src_stride];
2538 temp = dx * dx + dy * dy;
2539 if (dy == 0) {
2540 index = 2;
2541 } else {
2542 sn = (dx > 0) ^ (dy > 0);
2543 dx = abs(dx);
2544 dy = abs(dy);
2545 remd = dx % dy;
2546 quot = dx / dy;
2547 remd = remd * 16 / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07002548 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002549 }
2550 hist[index] += temp;
2551 }
2552 src += src_stride;
2553 }
2554
2555 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
2556 for (i = 0; i < INTRA_MODES; ++i) {
2557 if (i != DC_PRED && i != TM_PRED) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002558 const uint8_t angle_bin = mode_to_angle_bin[i];
2559 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002560 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07002561 if (angle_bin > 0) {
2562 score += hist[angle_bin - 1];
2563 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002564 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07002565 if (angle_bin < DIRECTIONAL_MODES - 1) {
2566 score += hist[angle_bin + 1];
2567 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002568 }
2569 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
2570 directional_mode_skip_mask[i] = 1;
2571 }
2572 }
2573}
2574
Yaowu Xuf883b422016-08-30 14:01:10 -07002575#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002576static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
2577 int rows, int cols,
2578 uint8_t *directional_mode_skip_mask) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002579 int i, r, c, index, dx, dy, temp, sn, remd, quot;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002580 uint64_t hist[DIRECTIONAL_MODES];
2581 uint64_t hist_sum = 0;
2582 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
2583
2584 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
2585 src += src_stride;
2586 for (r = 1; r < rows; ++r) {
2587 for (c = 1; c < cols; ++c) {
2588 dx = src[c] - src[c - 1];
2589 dy = src[c] - src[c - src_stride];
2590 temp = dx * dx + dy * dy;
2591 if (dy == 0) {
2592 index = 2;
2593 } else {
2594 sn = (dx > 0) ^ (dy > 0);
2595 dx = abs(dx);
2596 dy = abs(dy);
2597 remd = dx % dy;
2598 quot = dx / dy;
2599 remd = remd * 16 / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07002600 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002601 }
2602 hist[index] += temp;
2603 }
2604 src += src_stride;
2605 }
2606
2607 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
2608 for (i = 0; i < INTRA_MODES; ++i) {
2609 if (i != DC_PRED && i != TM_PRED) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002610 const uint8_t angle_bin = mode_to_angle_bin[i];
2611 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002612 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07002613 if (angle_bin > 0) {
2614 score += hist[angle_bin - 1];
2615 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002616 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07002617 if (angle_bin < DIRECTIONAL_MODES - 1) {
2618 score += hist[angle_bin + 1];
2619 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002620 }
2621 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
2622 directional_mode_skip_mask[i] = 1;
2623 }
2624 }
2625}
Yaowu Xuf883b422016-08-30 14:01:10 -07002626#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002627#endif // CONFIG_EXT_INTRA
2628
2629// This function is used only for intra_only frames
Urvang Joshi52648442016-10-13 17:27:51 -07002630static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
2631 int *rate, int *rate_tokenonly,
2632 int64_t *distortion, int *skippable,
2633 BLOCK_SIZE bsize, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002634 uint8_t mode_idx;
2635 PREDICTION_MODE mode_selected = DC_PRED;
2636 MACROBLOCKD *const xd = &x->e_mbd;
2637 MODE_INFO *const mic = xd->mi[0];
2638 int this_rate, this_rate_tokenonly, s;
2639 int64_t this_distortion, this_rd;
2640 TX_SIZE best_tx = TX_4X4;
Urvang Joshib100db72016-10-12 16:28:56 -07002641#if CONFIG_EXT_INTRA || CONFIG_PALETTE
2642 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
2643 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
2644#endif // CONFIG_EXT_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002645#if CONFIG_EXT_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07002646 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002647 int is_directional_mode, rate_overhead, best_angle_delta = 0;
2648 INTRA_FILTER best_filter = INTRA_FILTER_LINEAR;
2649 uint8_t directional_mode_skip_mask[INTRA_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002650 const int src_stride = x->plane[0].src.stride;
2651 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002652#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002653#if CONFIG_FILTER_INTRA
2654 int beat_best_rd = 0;
2655 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
2656 uint16_t filter_intra_mode_skip_mask = (1 << FILTER_INTRA_MODES) - 1;
2657#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002658 TX_TYPE best_tx_type = DCT_DCT;
Urvang Joshi52648442016-10-13 17:27:51 -07002659 const int *bmode_costs;
Urvang Joshib100db72016-10-12 16:28:56 -07002660#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002661 PALETTE_MODE_INFO palette_mode_info;
2662 PALETTE_MODE_INFO *const pmi = &mic->mbmi.palette_mode_info;
2663 uint8_t *best_palette_color_map =
2664 cpi->common.allow_screen_content_tools
2665 ? x->palette_buffer->best_palette_color_map
2666 : NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002667 int palette_ctx = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002668#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002669 const MODE_INFO *above_mi = xd->above_mi;
2670 const MODE_INFO *left_mi = xd->left_mi;
Yaowu Xuf883b422016-08-30 14:01:10 -07002671 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, 0);
2672 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002673 const PREDICTION_MODE FINAL_MODE_SEARCH = TM_PRED + 1;
2674 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
2675 bmode_costs = cpi->y_mode_costs[A][L];
2676
2677#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002678 mic->mbmi.angle_delta[0] = 0;
2679 memset(directional_mode_skip_mask, 0,
2680 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
Yaowu Xuf883b422016-08-30 14:01:10 -07002681#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002682 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
2683 highbd_angle_estimation(src, src_stride, rows, cols,
2684 directional_mode_skip_mask);
2685 else
2686#endif
2687 angle_estimation(src, src_stride, rows, cols, directional_mode_skip_mask);
2688#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002689#if CONFIG_FILTER_INTRA
2690 filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2691 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2692#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07002693#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002694 palette_mode_info.palette_size[0] = 0;
2695 pmi->palette_size[0] = 0;
2696 if (above_mi)
2697 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
2698 if (left_mi)
2699 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Urvang Joshib100db72016-10-12 16:28:56 -07002700#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002701
2702 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
2703 x->use_default_intra_tx_type = 1;
2704 else
2705 x->use_default_intra_tx_type = 0;
2706
2707 /* Y Search for intra prediction mode */
2708 for (mode_idx = DC_PRED; mode_idx <= FINAL_MODE_SEARCH; ++mode_idx) {
2709 if (mode_idx == FINAL_MODE_SEARCH) {
2710 if (x->use_default_intra_tx_type == 0) break;
2711 mic->mbmi.mode = mode_selected;
2712 x->use_default_intra_tx_type = 0;
2713 } else {
2714 mic->mbmi.mode = mode_idx;
2715 }
2716#if CONFIG_EXT_INTRA
2717 is_directional_mode =
2718 (mic->mbmi.mode != DC_PRED && mic->mbmi.mode != TM_PRED);
2719 if (is_directional_mode && directional_mode_skip_mask[mic->mbmi.mode])
2720 continue;
2721 if (is_directional_mode) {
2722 rate_overhead = bmode_costs[mic->mbmi.mode] +
2723 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
2724 this_rate_tokenonly = INT_MAX;
2725 this_rd = rd_pick_intra_angle_sby(cpi, x, &this_rate,
2726 &this_rate_tokenonly, &this_distortion,
2727 &s, bsize, rate_overhead, best_rd);
2728 } else {
2729 mic->mbmi.angle_delta[0] = 0;
2730 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s, NULL,
2731 bsize, best_rd);
2732 }
2733#else
2734 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s, NULL,
2735 bsize, best_rd);
2736#endif // CONFIG_EXT_INTRA
2737
2738 if (this_rate_tokenonly == INT_MAX) continue;
2739
2740 this_rate = this_rate_tokenonly + bmode_costs[mic->mbmi.mode];
2741
2742 if (!xd->lossless[xd->mi[0]->mbmi.segment_id]) {
2743 // super_block_yrd above includes the cost of the tx_size in the
2744 // tokenonly rate, but for intra blocks, tx_size is always coded
2745 // (prediction granularity), so we account for it in the full rate,
2746 // not the tokenonly rate.
2747 this_rate_tokenonly -=
clang-format67948d32016-09-07 22:40:40 -07002748 cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
Jingning Hanb0a71302016-10-25 16:28:49 -07002749 [tx_size_to_depth(mic->mbmi.tx_size)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002750 }
Urvang Joshib100db72016-10-12 16:28:56 -07002751#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002752 if (cpi->common.allow_screen_content_tools && mic->mbmi.mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07002753 this_rate += av1_cost_bit(
2754 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07002755#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07002756#if CONFIG_FILTER_INTRA
2757 if (mic->mbmi.mode == DC_PRED)
2758 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 0);
2759#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002760#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002761 if (is_directional_mode) {
2762 int p_angle;
2763 this_rate +=
2764 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
2765 MAX_ANGLE_DELTAS + mic->mbmi.angle_delta[0]);
2766 p_angle = mode_to_angle_map[mic->mbmi.mode] +
2767 mic->mbmi.angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07002768 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07002769 this_rate +=
2770 cpi->intra_filter_cost[intra_filter_ctx][mic->mbmi.intra_filter];
2771 }
2772#endif // CONFIG_EXT_INTRA
2773 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui su5db97432016-10-14 16:10:14 -07002774#if CONFIG_FILTER_INTRA
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07002775 if (best_rd == INT64_MAX || this_rd - best_rd < (best_rd >> 4)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002776 filter_intra_mode_skip_mask ^= (1 << mic->mbmi.mode);
2777 }
hui su5db97432016-10-14 16:10:14 -07002778#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002779
2780 if (this_rd < best_rd) {
2781 mode_selected = mic->mbmi.mode;
2782 best_rd = this_rd;
2783 best_tx = mic->mbmi.tx_size;
2784#if CONFIG_EXT_INTRA
2785 best_angle_delta = mic->mbmi.angle_delta[0];
2786 best_filter = mic->mbmi.intra_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002787#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002788#if CONFIG_FILTER_INTRA
2789 beat_best_rd = 1;
2790#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002791 best_tx_type = mic->mbmi.tx_type;
2792 *rate = this_rate;
2793 *rate_tokenonly = this_rate_tokenonly;
2794 *distortion = this_distortion;
2795 *skippable = s;
2796 }
2797 }
2798
Urvang Joshib100db72016-10-12 16:28:56 -07002799#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002800 if (cpi->common.allow_screen_content_tools)
2801 rd_pick_palette_intra_sby(cpi, x, bsize, palette_ctx, bmode_costs[DC_PRED],
2802 &palette_mode_info, best_palette_color_map,
2803 &best_tx, &best_tx_type, &mode_selected,
2804 &best_rd);
Urvang Joshib100db72016-10-12 16:28:56 -07002805#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002806
hui su5db97432016-10-14 16:10:14 -07002807#if CONFIG_FILTER_INTRA
2808 if (beat_best_rd) {
2809 if (rd_pick_filter_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
2810 skippable, bsize, bmode_costs[DC_PRED],
2811 &best_rd, filter_intra_mode_skip_mask)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002812 mode_selected = mic->mbmi.mode;
2813 best_tx = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07002814 filter_intra_mode_info = mic->mbmi.filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002815 best_tx_type = mic->mbmi.tx_type;
2816 }
2817 }
2818
hui su5db97432016-10-14 16:10:14 -07002819 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] =
2820 filter_intra_mode_info.use_filter_intra_mode[0];
2821 if (filter_intra_mode_info.use_filter_intra_mode[0]) {
2822 mic->mbmi.filter_intra_mode_info.filter_intra_mode[0] =
2823 filter_intra_mode_info.filter_intra_mode[0];
Urvang Joshib100db72016-10-12 16:28:56 -07002824#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002825 palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002826#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002827 }
hui su5db97432016-10-14 16:10:14 -07002828#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002829
2830 mic->mbmi.mode = mode_selected;
2831 mic->mbmi.tx_size = best_tx;
2832#if CONFIG_EXT_INTRA
2833 mic->mbmi.angle_delta[0] = best_angle_delta;
2834 mic->mbmi.intra_filter = best_filter;
2835#endif // CONFIG_EXT_INTRA
2836 mic->mbmi.tx_type = best_tx_type;
Urvang Joshib100db72016-10-12 16:28:56 -07002837#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002838 pmi->palette_size[0] = palette_mode_info.palette_size[0];
2839 if (palette_mode_info.palette_size[0] > 0) {
2840 memcpy(pmi->palette_colors, palette_mode_info.palette_colors,
2841 PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
2842 memcpy(xd->plane[0].color_index_map, best_palette_color_map,
2843 rows * cols * sizeof(best_palette_color_map[0]));
2844 }
Urvang Joshib100db72016-10-12 16:28:56 -07002845#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002846
2847 return best_rd;
2848}
2849
Yue Chena1e48dc2016-08-29 17:29:33 -07002850// Return value 0: early termination triggered, no valid rd cost available;
2851// 1: rd cost values are valid.
Urvang Joshi52648442016-10-13 17:27:51 -07002852static int super_block_uvrd(const AV1_COMP *const cpi, MACROBLOCK *x, int *rate,
Yue Chena1e48dc2016-08-29 17:29:33 -07002853 int64_t *distortion, int *skippable, int64_t *sse,
2854 BLOCK_SIZE bsize, int64_t ref_best_rd) {
2855 MACROBLOCKD *const xd = &x->e_mbd;
2856 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2857 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
2858 int plane;
2859 int pnrate = 0, pnskip = 1;
2860 int64_t pndist = 0, pnsse = 0;
2861 int is_cost_valid = 1;
2862
2863 if (ref_best_rd < 0) is_cost_valid = 0;
2864
2865 if (is_inter_block(mbmi) && is_cost_valid) {
Yue Chena1e48dc2016-08-29 17:29:33 -07002866 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
2867 av1_subtract_plane(x, bsize, plane);
2868 }
2869
2870 *rate = 0;
2871 *distortion = 0;
2872 *sse = 0;
2873 *skippable = 1;
2874
Yushin Cho09de28b2016-06-21 14:51:23 -07002875 if (is_cost_valid) {
2876 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
2877 txfm_rd_in_plane(x, cpi, &pnrate, &pndist, &pnskip, &pnsse, ref_best_rd,
2878 plane, bsize, uv_tx_size, cpi->sf.use_fast_coef_costing);
2879 if (pnrate == INT_MAX) {
2880 is_cost_valid = 0;
2881 break;
2882 }
2883 *rate += pnrate;
2884 *distortion += pndist;
2885 *sse += pnsse;
2886 *skippable &= pnskip;
2887 if (RDCOST(x->rdmult, x->rddiv, *rate, *distortion) > ref_best_rd &&
2888 RDCOST(x->rdmult, x->rddiv, 0, *sse) > ref_best_rd) {
2889 is_cost_valid = 0;
2890 break;
2891 }
Yue Chena1e48dc2016-08-29 17:29:33 -07002892 }
2893 }
2894
2895 if (!is_cost_valid) {
2896 // reset cost value
2897 *rate = INT_MAX;
2898 *distortion = INT64_MAX;
2899 *sse = INT64_MAX;
2900 *skippable = 0;
2901 }
2902
2903 return is_cost_valid;
2904}
2905
Yaowu Xuc27fc142016-08-22 16:08:15 -07002906#if CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07002907void av1_tx_block_rd_b(const AV1_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
2908 int blk_row, int blk_col, int plane, int block,
2909 int plane_bsize, int coeff_ctx, int *rate, int64_t *dist,
2910 int64_t *bsse, int *skip) {
Angie Chiang22ba7512016-10-20 17:10:33 -07002911 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002912 MACROBLOCKD *xd = &x->e_mbd;
2913 const struct macroblock_plane *const p = &x->plane[plane];
2914 struct macroblockd_plane *const pd = &xd->plane[plane];
2915 int64_t tmp;
2916 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
2917 PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
2918 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002919 const SCAN_ORDER *const scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07002920 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002921 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
Jingning Han9fdc4222016-10-27 21:32:19 -07002922 int bh = block_size_high[txm_bsize];
2923 int bw = block_size_wide[txm_bsize];
2924 int txb_h = tx_size_high_unit[tx_size];
2925 int txb_w = tx_size_wide_unit[tx_size];
2926
Yaowu Xuc27fc142016-08-22 16:08:15 -07002927 int src_stride = p->src.stride;
2928 uint8_t *src = &p->src.buf[4 * blk_row * src_stride + 4 * blk_col];
2929 uint8_t *dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
Yaowu Xuf883b422016-08-30 14:01:10 -07002930#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002931 DECLARE_ALIGNED(16, uint16_t, rec_buffer16[MAX_TX_SQUARE]);
2932 uint8_t *rec_buffer;
2933#else
2934 DECLARE_ALIGNED(16, uint8_t, rec_buffer[MAX_TX_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07002935#endif // CONFIG_AOM_HIGHBITDEPTH
Jingning Han9fdc4222016-10-27 21:32:19 -07002936 int max_blocks_high = block_size_high[plane_bsize];
2937 int max_blocks_wide = block_size_wide[plane_bsize];
2938 const int diff_stride = max_blocks_wide;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002939 const int16_t *diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002940#if CONFIG_EXT_TX
2941 assert(tx_size < TX_SIZES);
2942#endif // CONFIG_EXT_TX
2943
2944 if (xd->mb_to_bottom_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07002945 max_blocks_high += xd->mb_to_bottom_edge >> (3 + pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002946 if (xd->mb_to_right_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07002947 max_blocks_wide += xd->mb_to_right_edge >> (3 + pd->subsampling_x);
2948
2949 max_blocks_high >>= tx_size_wide_log2[0];
2950 max_blocks_wide >>= tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002951
2952#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002953 av1_xform_quant_fp_nuq(cm, x, plane, block, blk_row, blk_col, plane_bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -07002954 tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002955#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002956 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Yaowu Xuf883b422016-08-30 14:01:10 -07002957 AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002958#endif // CONFIG_NEW_QUANT
2959
Angie Chiangff6d8902016-10-21 11:02:09 -07002960 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002961
2962// TODO(any): Use dist_block to compute distortion
Yaowu Xuf883b422016-08-30 14:01:10 -07002963#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002964 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2965 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer16);
Yaowu Xuf883b422016-08-30 14:01:10 -07002966 aom_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07002967 0, NULL, 0, bw, bh, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002968 } else {
2969 rec_buffer = (uint8_t *)rec_buffer16;
Yaowu Xuf883b422016-08-30 14:01:10 -07002970 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0,
Jingning Han9fdc4222016-10-27 21:32:19 -07002971 NULL, 0, bw, bh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002972 }
2973#else
Yaowu Xuf883b422016-08-30 14:01:10 -07002974 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07002975 0, bw, bh);
Yaowu Xuf883b422016-08-30 14:01:10 -07002976#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002977
Jingning Han9fdc4222016-10-27 21:32:19 -07002978 if (blk_row + txb_h > max_blocks_high || blk_col + txb_w > max_blocks_wide) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002979 int idx, idy;
Jingning Han9fdc4222016-10-27 21:32:19 -07002980 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
2981 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002982 tmp = 0;
2983 for (idy = 0; idy < blocks_height; idy += 2) {
2984 for (idx = 0; idx < blocks_width; idx += 2) {
2985 const int16_t *d = diff + 4 * idy * diff_stride + 4 * idx;
Yaowu Xuf883b422016-08-30 14:01:10 -07002986 tmp += aom_sum_squares_2d_i16(d, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002987 }
2988 }
2989 } else {
Jingning Han9fdc4222016-10-27 21:32:19 -07002990 tmp = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002991 }
2992
Yaowu Xuf883b422016-08-30 14:01:10 -07002993#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002994 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
2995 tmp = ROUND_POWER_OF_TWO(tmp, (xd->bd - 8) * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07002996#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002997 *bsse += tmp * 16;
2998
2999 if (p->eobs[block] > 0) {
3000 INV_TXFM_PARAM inv_txfm_param;
3001 inv_txfm_param.tx_type = tx_type;
3002 inv_txfm_param.tx_size = tx_size;
3003 inv_txfm_param.eob = p->eobs[block];
3004 inv_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
Yaowu Xuf883b422016-08-30 14:01:10 -07003005#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003006 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3007 inv_txfm_param.bd = xd->bd;
3008 highbd_inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
3009 } else {
3010 inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
3011 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003012#else // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003013 inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
Yaowu Xuf883b422016-08-30 14:01:10 -07003014#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003015
Jingning Han9fdc4222016-10-27 21:32:19 -07003016 if (txb_h + blk_col > max_blocks_wide ||
3017 txb_w + blk_row > max_blocks_high) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003018 int idx, idy;
3019 unsigned int this_dist;
Jingning Han9fdc4222016-10-27 21:32:19 -07003020 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3021 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003022 tmp = 0;
3023 for (idy = 0; idy < blocks_height; idy += 2) {
3024 for (idx = 0; idx < blocks_width; idx += 2) {
3025 uint8_t *const s = src + 4 * idy * src_stride + 4 * idx;
3026 uint8_t *const r = rec_buffer + 4 * idy * MAX_TX_SIZE + 4 * idx;
3027 cpi->fn_ptr[BLOCK_8X8].vf(s, src_stride, r, MAX_TX_SIZE, &this_dist);
3028 tmp += this_dist;
3029 }
3030 }
3031 } else {
3032 uint32_t this_dist;
3033 cpi->fn_ptr[txm_bsize].vf(src, src_stride, rec_buffer, MAX_TX_SIZE,
3034 &this_dist);
3035 tmp = this_dist;
3036 }
3037 }
3038 *dist += tmp * 16;
Angie Chiang22ba7512016-10-20 17:10:33 -07003039 *rate += av1_cost_coeffs(cm, x, plane, block, coeff_ctx, tx_size,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003040 scan_order->scan, scan_order->neighbors, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003041 *skip &= (p->eobs[block] == 0);
3042}
3043
Yaowu Xuf883b422016-08-30 14:01:10 -07003044static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003045 int blk_col, int plane, int block, TX_SIZE tx_size,
Jingning Han94d5bfc2016-10-21 10:14:36 -07003046 int depth, BLOCK_SIZE plane_bsize,
3047 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
3048 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
3049 int *rate, int64_t *dist, int64_t *bsse, int *skip,
3050 int64_t ref_best_rd, int *is_cost_valid) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003051 MACROBLOCKD *const xd = &x->e_mbd;
3052 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3053 struct macroblock_plane *const p = &x->plane[plane];
3054 struct macroblockd_plane *const pd = &xd->plane[plane];
3055 const int tx_row = blk_row >> (1 - pd->subsampling_y);
3056 const int tx_col = blk_col >> (1 - pd->subsampling_x);
clang-format67948d32016-09-07 22:40:40 -07003057 TX_SIZE(*const inter_tx_size)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003058 [MAX_MIB_SIZE] =
3059 (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
Jingning Hanf65b8702016-10-31 12:13:20 -07003060 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
3061 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Jingning Han58224042016-10-27 16:35:32 -07003062 const int bw = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003063 int64_t this_rd = INT64_MAX;
3064 ENTROPY_CONTEXT *pta = ta + blk_col;
3065 ENTROPY_CONTEXT *ptl = tl + blk_row;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003066 int coeff_ctx, i;
3067 int ctx = txfm_partition_context(tx_above + (blk_col >> 1),
3068 tx_left + (blk_row >> 1), tx_size);
3069
3070 int64_t sum_dist = 0, sum_bsse = 0;
3071 int64_t sum_rd = INT64_MAX;
Jingning Hance059e82016-10-31 16:27:28 -07003072 int sum_rate = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003073 int all_skip = 1;
3074 int tmp_eob = 0;
3075 int zero_blk_rate;
3076
3077#if CONFIG_EXT_TX
3078 assert(tx_size < TX_SIZES);
3079#endif // CONFIG_EXT_TX
3080
3081 if (ref_best_rd < 0) {
3082 *is_cost_valid = 0;
3083 return;
3084 }
3085
Jingning Hance059e82016-10-31 16:27:28 -07003086 coeff_ctx = get_entropy_context(tx_size, pta, ptl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003087
Yaowu Xuc27fc142016-08-22 16:08:15 -07003088 *rate = 0;
3089 *dist = 0;
3090 *bsse = 0;
3091 *skip = 1;
3092
3093 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
3094
3095 zero_blk_rate =
3096 x->token_costs[tx_size][pd->plane_type][1][0][0][coeff_ctx][EOB_TOKEN];
3097
3098 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
3099 inter_tx_size[0][0] = tx_size;
Yaowu Xuf883b422016-08-30 14:01:10 -07003100 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
3101 plane_bsize, coeff_ctx, rate, dist, bsse, skip);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003102
3103 if ((RDCOST(x->rdmult, x->rddiv, *rate, *dist) >=
3104 RDCOST(x->rdmult, x->rddiv, zero_blk_rate, *bsse) ||
3105 *skip == 1) &&
3106 !xd->lossless[mbmi->segment_id]) {
3107 *rate = zero_blk_rate;
3108 *dist = *bsse;
3109 *skip = 1;
3110 x->blk_skip[plane][blk_row * bw + blk_col] = 1;
3111 p->eobs[block] = 0;
3112 } else {
3113 x->blk_skip[plane][blk_row * bw + blk_col] = 0;
3114 *skip = 0;
3115 }
3116
Jingning Han571189c2016-10-24 10:38:43 -07003117 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH)
Yaowu Xuf883b422016-08-30 14:01:10 -07003118 *rate += av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003119 this_rd = RDCOST(x->rdmult, x->rddiv, *rate, *dist);
3120 tmp_eob = p->eobs[block];
3121 }
3122
Jingning Han571189c2016-10-24 10:38:43 -07003123 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003124 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
Jingning Han58224042016-10-27 16:35:32 -07003125 int bsl = block_size_wide[bsize] >> (tx_size_wide_log2[0] + 1);
3126 // TODO(jingning): Refactor this transform block size transition.
3127 TX_SIZE sub_txs = tx_size - 1;
3128 int sub_step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003129 int this_rate;
3130 int64_t this_dist;
3131 int64_t this_bsse;
3132 int this_skip;
3133 int this_cost_valid = 1;
3134 int64_t tmp_rd = 0;
3135
Jingning Hance059e82016-10-31 16:27:28 -07003136 sum_rate = av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003137#if CONFIG_EXT_TX
3138 assert(tx_size < TX_SIZES);
3139#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003140 for (i = 0; i < 4 && this_cost_valid; ++i) {
Jingning Han58224042016-10-27 16:35:32 -07003141 int offsetr = (i >> 1) * bsl;
3142 int offsetc = (i & 0x01) * bsl;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003143 select_tx_block(cpi, x, blk_row + offsetr, blk_col + offsetc, plane,
Jingning Han58224042016-10-27 16:35:32 -07003144 block + i * sub_step, sub_txs, depth + 1, plane_bsize, ta,
3145 tl, tx_above, tx_left, &this_rate, &this_dist, &this_bsse,
3146 &this_skip, ref_best_rd - tmp_rd, &this_cost_valid);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003147 sum_rate += this_rate;
3148 sum_dist += this_dist;
3149 sum_bsse += this_bsse;
3150 all_skip &= this_skip;
3151 tmp_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
3152 if (this_rd < tmp_rd) break;
3153 }
3154 if (this_cost_valid) sum_rd = tmp_rd;
3155 }
3156
3157 if (this_rd < sum_rd) {
3158 int idx, idy;
Jingning Han58224042016-10-27 16:35:32 -07003159 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) pta[i] = !(tmp_eob == 0);
3160 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) ptl[i] = !(tmp_eob == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003161 txfm_partition_update(tx_above + (blk_col >> 1), tx_left + (blk_row >> 1),
3162 tx_size);
3163 inter_tx_size[0][0] = tx_size;
Jingning Han58224042016-10-27 16:35:32 -07003164 for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
3165 for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003166 inter_tx_size[idy][idx] = tx_size;
3167 mbmi->tx_size = tx_size;
3168 if (this_rd == INT64_MAX) *is_cost_valid = 0;
3169 x->blk_skip[plane][blk_row * bw + blk_col] = *skip;
3170 } else {
3171 *rate = sum_rate;
3172 *dist = sum_dist;
3173 *bsse = sum_bsse;
3174 *skip = all_skip;
3175 if (sum_rd == INT64_MAX) *is_cost_valid = 0;
3176 }
3177}
3178
Yaowu Xuf883b422016-08-30 14:01:10 -07003179static void inter_block_yrd(const AV1_COMP *cpi, MACROBLOCK *x, int *rate,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003180 int64_t *distortion, int *skippable, int64_t *sse,
3181 BLOCK_SIZE bsize, int64_t ref_best_rd) {
3182 MACROBLOCKD *const xd = &x->e_mbd;
3183 int is_cost_valid = 1;
3184 int64_t this_rd = 0;
3185
3186 if (ref_best_rd < 0) is_cost_valid = 0;
3187
3188 *rate = 0;
3189 *distortion = 0;
3190 *sse = 0;
3191 *skippable = 1;
3192
3193 if (is_cost_valid) {
3194 const struct macroblockd_plane *const pd = &xd->plane[0];
3195 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
3196 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
3197 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
3198 BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[plane_bsize]];
3199 int bh = num_4x4_blocks_wide_lookup[txb_size];
3200 int idx, idy;
3201 int block = 0;
Jingning Han607fa6a2016-10-26 10:46:28 -07003202 int step = tx_size_wide_unit[max_txsize_lookup[plane_bsize]] *
3203 tx_size_high_unit[max_txsize_lookup[plane_bsize]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003204 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
3205 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
3206 TXFM_CONTEXT tx_above[MAX_MIB_SIZE];
3207 TXFM_CONTEXT tx_left[MAX_MIB_SIZE];
3208
3209 int pnrate = 0, pnskip = 1;
3210 int64_t pndist = 0, pnsse = 0;
3211
Yaowu Xuf883b422016-08-30 14:01:10 -07003212 av1_get_entropy_contexts(bsize, TX_4X4, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003213 memcpy(tx_above, xd->above_txfm_context,
3214 sizeof(TXFM_CONTEXT) * (mi_width >> 1));
3215 memcpy(tx_left, xd->left_txfm_context,
3216 sizeof(TXFM_CONTEXT) * (mi_height >> 1));
3217
3218 for (idy = 0; idy < mi_height; idy += bh) {
3219 for (idx = 0; idx < mi_width; idx += bh) {
3220 select_tx_block(cpi, x, idy, idx, 0, block,
Jingning Han94d5bfc2016-10-21 10:14:36 -07003221 max_txsize_lookup[plane_bsize], mi_height != mi_width,
3222 plane_bsize, ctxa, ctxl, tx_above, tx_left, &pnrate,
3223 &pndist, &pnsse, &pnskip, ref_best_rd - this_rd,
3224 &is_cost_valid);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003225 *rate += pnrate;
3226 *distortion += pndist;
3227 *sse += pnsse;
3228 *skippable &= pnskip;
Yaowu Xuf883b422016-08-30 14:01:10 -07003229 this_rd += AOMMIN(RDCOST(x->rdmult, x->rddiv, pnrate, pndist),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003230 RDCOST(x->rdmult, x->rddiv, 0, pnsse));
3231 block += step;
3232 }
3233 }
3234 }
3235
Yaowu Xuf883b422016-08-30 14:01:10 -07003236 this_rd = AOMMIN(RDCOST(x->rdmult, x->rddiv, *rate, *distortion),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003237 RDCOST(x->rdmult, x->rddiv, 0, *sse));
3238 if (this_rd > ref_best_rd) is_cost_valid = 0;
3239
3240 if (!is_cost_valid) {
3241 // reset cost value
3242 *rate = INT_MAX;
3243 *distortion = INT64_MAX;
3244 *sse = INT64_MAX;
3245 *skippable = 0;
3246 }
3247}
3248
Yaowu Xuf883b422016-08-30 14:01:10 -07003249static int64_t select_tx_size_fix_type(const AV1_COMP *cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003250 int *rate, int64_t *dist, int *skippable,
3251 int64_t *sse, BLOCK_SIZE bsize,
3252 int64_t ref_best_rd, TX_TYPE tx_type) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003253 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003254 MACROBLOCKD *const xd = &x->e_mbd;
3255 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003256 const int is_inter = is_inter_block(mbmi);
Yaowu Xuf883b422016-08-30 14:01:10 -07003257 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
3258 int s0 = av1_cost_bit(skip_prob, 0);
3259 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003260 int64_t rd;
3261
3262 mbmi->tx_type = tx_type;
3263 inter_block_yrd(cpi, x, rate, dist, skippable, sse, bsize, ref_best_rd);
Yue Chena1e48dc2016-08-29 17:29:33 -07003264#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07003265 if (is_rect_tx_allowed(xd, mbmi)) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003266 int rate_rect_tx, skippable_rect_tx = 0;
Urvang Joshi368fbc92016-10-17 16:31:34 -07003267 int64_t dist_rect_tx, sse_rect_tx, rd_rect_tx;
Yue Chena1e48dc2016-08-29 17:29:33 -07003268 int tx_size_cat = inter_tx_size_cat_lookup[bsize];
3269 TX_SIZE tx_size = max_txsize_rect_lookup[bsize];
3270 TX_SIZE var_tx_size = mbmi->tx_size;
3271
3272 txfm_rd_in_plane(x, cpi, &rate_rect_tx, &dist_rect_tx, &skippable_rect_tx,
3273 &sse_rect_tx, ref_best_rd, 0, bsize, tx_size,
3274 cpi->sf.use_fast_coef_costing);
3275
3276 if (*rate != INT_MAX) {
3277 *rate += av1_cost_bit(cm->fc->rect_tx_prob[tx_size_cat], 0);
3278 if (*skippable) {
3279 rd = RDCOST(x->rdmult, x->rddiv, s1, *sse);
3280 } else {
3281 rd = RDCOST(x->rdmult, x->rddiv, *rate + s0, *dist);
3282 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
3283 !(*skippable))
3284 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, *sse));
3285 }
3286 } else {
3287 rd = INT64_MAX;
3288 }
3289
3290 if (rate_rect_tx != INT_MAX) {
3291 rate_rect_tx += av1_cost_bit(cm->fc->rect_tx_prob[tx_size_cat], 1);
3292 if (skippable_rect_tx) {
3293 rd_rect_tx = RDCOST(x->rdmult, x->rddiv, s1, sse_rect_tx);
3294 } else {
3295 rd_rect_tx =
3296 RDCOST(x->rdmult, x->rddiv, rate_rect_tx + s0, dist_rect_tx);
3297 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
3298 !(skippable_rect_tx))
3299 rd_rect_tx =
3300 AOMMIN(rd_rect_tx, RDCOST(x->rdmult, x->rddiv, s1, sse_rect_tx));
3301 }
3302 } else {
3303 rd_rect_tx = INT64_MAX;
3304 }
3305
3306 if (rd_rect_tx < rd) {
3307 *rate = rate_rect_tx;
3308 *dist = dist_rect_tx;
3309 *sse = sse_rect_tx;
3310 *skippable = skippable_rect_tx;
3311 if (!xd->lossless[mbmi->segment_id]) x->blk_skip[0][0] = *skippable;
3312 mbmi->tx_size = tx_size;
3313 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
3314 } else {
3315 mbmi->tx_size = var_tx_size;
3316 }
3317 }
3318#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003319
3320 if (*rate == INT_MAX) return INT64_MAX;
3321
3322#if CONFIG_EXT_TX
Peter de Rivazc0b4d7a2016-09-08 10:55:58 +01003323 if (get_ext_tx_types(mbmi->tx_size, bsize, is_inter) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003324 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Peter de Rivazc0b4d7a2016-09-08 10:55:58 +01003325 int ext_tx_set = get_ext_tx_set(mbmi->tx_size, bsize, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003326 if (is_inter) {
3327 if (ext_tx_set > 0)
Peter de Rivazb85a5a72016-10-18 11:47:56 +01003328 *rate +=
3329 cpi->inter_tx_type_costs[ext_tx_set][txsize_sqr_map[mbmi->tx_size]]
3330 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003331 } else {
3332 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Peter de Rivazc0b4d7a2016-09-08 10:55:58 +01003333 *rate += cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->mode]
Yaowu Xuc27fc142016-08-22 16:08:15 -07003334 [mbmi->tx_type];
3335 }
3336 }
3337#else // CONFIG_EXT_TX
Peter de Rivazc0b4d7a2016-09-08 10:55:58 +01003338 if (mbmi->tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003339 if (is_inter)
Peter de Rivazc0b4d7a2016-09-08 10:55:58 +01003340 *rate += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003341 else
clang-format67948d32016-09-07 22:40:40 -07003342 *rate +=
3343 cpi->intra_tx_type_costs[mbmi->tx_size]
3344 [intra_mode_to_tx_type_context[mbmi->mode]]
3345 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003346 }
3347#endif // CONFIG_EXT_TX
3348
3349 if (*skippable)
3350 rd = RDCOST(x->rdmult, x->rddiv, s1, *sse);
3351 else
3352 rd = RDCOST(x->rdmult, x->rddiv, *rate + s0, *dist);
3353
3354 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] && !(*skippable))
Yaowu Xuf883b422016-08-30 14:01:10 -07003355 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, *sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003356
3357 return rd;
3358}
3359
Yaowu Xuf883b422016-08-30 14:01:10 -07003360static void select_tx_type_yrd(const AV1_COMP *cpi, MACROBLOCK *x, int *rate,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003361 int64_t *distortion, int *skippable,
3362 int64_t *sse, BLOCK_SIZE bsize,
3363 int64_t ref_best_rd) {
3364 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
3365 MACROBLOCKD *const xd = &x->e_mbd;
3366 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3367 int64_t rd = INT64_MAX;
3368 int64_t best_rd = INT64_MAX;
3369 TX_TYPE tx_type, best_tx_type = DCT_DCT;
3370 const int is_inter = is_inter_block(mbmi);
3371 TX_SIZE best_tx_size[MAX_MIB_SIZE][MAX_MIB_SIZE];
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07003372 TX_SIZE best_tx = max_txsize_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003373 uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
3374 const int n4 = 1 << (num_pels_log2_lookup[bsize] - 4);
3375 int idx, idy;
3376 int prune = 0;
3377#if CONFIG_EXT_TX
3378 int ext_tx_set = get_ext_tx_set(max_tx_size, bsize, is_inter);
3379#endif // CONFIG_EXT_TX
3380
3381 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
3382#if CONFIG_EXT_TX
3383 prune = prune_tx_types(cpi, bsize, x, xd, ext_tx_set);
3384#else
3385 prune = prune_tx_types(cpi, bsize, x, xd, 0);
3386#endif
3387
3388 *distortion = INT64_MAX;
3389 *rate = INT_MAX;
3390 *skippable = 0;
3391 *sse = INT64_MAX;
3392
3393 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
3394 int this_rate = 0;
3395 int this_skip = 1;
3396 int64_t this_dist = 0;
3397 int64_t this_sse = 0;
3398#if CONFIG_EXT_TX
3399 if (is_inter) {
3400 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
3401 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
3402 if (!do_tx_type_search(tx_type, prune)) continue;
3403 }
3404 } else {
3405 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
3406 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
3407 }
3408 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
3409 }
3410#else // CONFIG_EXT_TX
3411 if (max_tx_size >= TX_32X32 && tx_type != DCT_DCT) continue;
3412 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
3413 !do_tx_type_search(tx_type, prune))
3414 continue;
3415#endif // CONFIG_EXT_TX
3416 if (is_inter && x->use_default_inter_tx_type &&
3417 tx_type != get_default_tx_type(0, xd, 0, max_tx_size))
3418 continue;
3419
3420 rd = select_tx_size_fix_type(cpi, x, &this_rate, &this_dist, &this_skip,
3421 &this_sse, bsize, ref_best_rd, tx_type);
3422
3423 if (rd < best_rd) {
3424 best_rd = rd;
3425 *distortion = this_dist;
3426 *rate = this_rate;
3427 *skippable = this_skip;
3428 *sse = this_sse;
3429 best_tx_type = mbmi->tx_type;
3430 best_tx = mbmi->tx_size;
3431 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
3432 for (idy = 0; idy < xd->n8_h; ++idy)
3433 for (idx = 0; idx < xd->n8_w; ++idx)
3434 best_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
3435 }
3436 }
3437
3438 mbmi->tx_type = best_tx_type;
3439 for (idy = 0; idy < xd->n8_h; ++idy)
3440 for (idx = 0; idx < xd->n8_w; ++idx)
3441 mbmi->inter_tx_size[idy][idx] = best_tx_size[idy][idx];
3442 mbmi->tx_size = best_tx;
3443 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
3444}
3445
Yaowu Xuf883b422016-08-30 14:01:10 -07003446static void tx_block_rd(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003447 int blk_col, int plane, int block, TX_SIZE tx_size,
3448 BLOCK_SIZE plane_bsize, ENTROPY_CONTEXT *above_ctx,
3449 ENTROPY_CONTEXT *left_ctx, int *rate, int64_t *dist,
3450 int64_t *bsse, int *skip) {
3451 MACROBLOCKD *const xd = &x->e_mbd;
3452 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3453 struct macroblock_plane *const p = &x->plane[plane];
3454 struct macroblockd_plane *const pd = &xd->plane[plane];
3455 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
3456 const int tx_row = blk_row >> (1 - pd->subsampling_y);
3457 const int tx_col = blk_col >> (1 - pd->subsampling_x);
3458 TX_SIZE plane_tx_size;
Jingning Han58224042016-10-27 16:35:32 -07003459 int max_blocks_high = block_size_high[plane_bsize];
3460 int max_blocks_wide = block_size_wide[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003461
3462#if CONFIG_EXT_TX
3463 assert(tx_size < TX_SIZES);
3464#endif // CONFIG_EXT_TX
3465
3466 if (xd->mb_to_bottom_edge < 0)
Jingning Han58224042016-10-27 16:35:32 -07003467 max_blocks_high += xd->mb_to_bottom_edge >> (3 + pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003468 if (xd->mb_to_right_edge < 0)
Jingning Han58224042016-10-27 16:35:32 -07003469 max_blocks_wide += xd->mb_to_right_edge >> (3 + pd->subsampling_x);
3470
3471 max_blocks_high >>= tx_size_wide_log2[0];
3472 max_blocks_wide >>= tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003473
3474 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
3475
Debargha Mukherjee2f123402016-08-30 17:43:38 -07003476 plane_tx_size =
3477 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
3478 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003479
3480 if (tx_size == plane_tx_size) {
3481 int coeff_ctx, i;
3482 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
3483 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
3484 switch (tx_size) {
3485 case TX_4X4: break;
3486 case TX_8X8:
3487 ta[0] = !!*(const uint16_t *)&ta[0];
3488 tl[0] = !!*(const uint16_t *)&tl[0];
3489 break;
3490 case TX_16X16:
3491 ta[0] = !!*(const uint32_t *)&ta[0];
3492 tl[0] = !!*(const uint32_t *)&tl[0];
3493 break;
3494 case TX_32X32:
3495 ta[0] = !!*(const uint64_t *)&ta[0];
3496 tl[0] = !!*(const uint64_t *)&tl[0];
3497 break;
3498 default: assert(0 && "Invalid transform size."); break;
3499 }
3500 coeff_ctx = combine_entropy_contexts(ta[0], tl[0]);
Yaowu Xuf883b422016-08-30 14:01:10 -07003501 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
3502 plane_bsize, coeff_ctx, rate, dist, bsse, skip);
Jingning Han607fa6a2016-10-26 10:46:28 -07003503
Jingning Han58224042016-10-27 16:35:32 -07003504 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003505 ta[i] = !(p->eobs[block] == 0);
Jingning Han58224042016-10-27 16:35:32 -07003506 for (i = 0; i < tx_size_high_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003507 tl[i] = !(p->eobs[block] == 0);
3508 } else {
Jingning Han58224042016-10-27 16:35:32 -07003509 const int bsl = block_size_wide[bsize] >> (1 + tx_size_wide_log2[0]);
3510 const TX_SIZE sub_txs = tx_size - 1;
3511 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003512 int i;
3513
3514 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003515
3516 for (i = 0; i < 4; ++i) {
Jingning Han58224042016-10-27 16:35:32 -07003517 int offsetr = (i >> 1) * bsl;
3518 int offsetc = (i & 0x01) * bsl;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003519 tx_block_rd(cpi, x, blk_row + offsetr, blk_col + offsetc, plane,
Jingning Han58224042016-10-27 16:35:32 -07003520 block + i * step, sub_txs, plane_bsize, above_ctx, left_ctx,
3521 rate, dist, bsse, skip);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003522 }
3523 }
3524}
3525
3526// Return value 0: early termination triggered, no valid rd cost available;
3527// 1: rd cost values are valid.
Yaowu Xuf883b422016-08-30 14:01:10 -07003528static int inter_block_uvrd(const AV1_COMP *cpi, MACROBLOCK *x, int *rate,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003529 int64_t *distortion, int *skippable, int64_t *sse,
3530 BLOCK_SIZE bsize, int64_t ref_best_rd) {
3531 MACROBLOCKD *const xd = &x->e_mbd;
3532 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3533 int plane;
3534 int is_cost_valid = 1;
3535 int64_t this_rd;
3536
3537 if (ref_best_rd < 0) is_cost_valid = 0;
3538
Yue Chena1e48dc2016-08-29 17:29:33 -07003539 *rate = 0;
3540 *distortion = 0;
3541 *sse = 0;
3542 *skippable = 1;
3543
3544#if CONFIG_EXT_TX && CONFIG_RECT_TX
3545 if (is_rect_tx(mbmi->tx_size)) {
3546 return super_block_uvrd(cpi, x, rate, distortion, skippable, sse, bsize,
3547 ref_best_rd);
3548 }
3549#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
3550
Yaowu Xuc27fc142016-08-22 16:08:15 -07003551 if (is_inter_block(mbmi) && is_cost_valid) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003552 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
Yaowu Xuf883b422016-08-30 14:01:10 -07003553 av1_subtract_plane(x, bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003554 }
3555
Yaowu Xuc27fc142016-08-22 16:08:15 -07003556 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
3557 const struct macroblockd_plane *const pd = &xd->plane[plane];
3558 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
3559 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
3560 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
3561 BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[plane_bsize]];
3562 int bh = num_4x4_blocks_wide_lookup[txb_size];
3563 int idx, idy;
3564 int block = 0;
3565 int step = 1 << (max_txsize_lookup[plane_bsize] * 2);
3566 int pnrate = 0, pnskip = 1;
3567 int64_t pndist = 0, pnsse = 0;
3568 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE];
3569 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE];
3570
Yaowu Xuf883b422016-08-30 14:01:10 -07003571 av1_get_entropy_contexts(bsize, TX_4X4, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003572
3573 for (idy = 0; idy < mi_height; idy += bh) {
3574 for (idx = 0; idx < mi_width; idx += bh) {
3575 tx_block_rd(cpi, x, idy, idx, plane, block,
3576 max_txsize_lookup[plane_bsize], plane_bsize, ta, tl,
3577 &pnrate, &pndist, &pnsse, &pnskip);
3578 block += step;
3579 }
3580 }
3581
3582 if (pnrate == INT_MAX) {
3583 is_cost_valid = 0;
3584 break;
3585 }
3586
3587 *rate += pnrate;
3588 *distortion += pndist;
3589 *sse += pnsse;
3590 *skippable &= pnskip;
3591
Yaowu Xuf883b422016-08-30 14:01:10 -07003592 this_rd = AOMMIN(RDCOST(x->rdmult, x->rddiv, *rate, *distortion),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003593 RDCOST(x->rdmult, x->rddiv, 0, *sse));
3594
3595 if (this_rd > ref_best_rd) {
3596 is_cost_valid = 0;
3597 break;
3598 }
3599 }
3600
3601 if (!is_cost_valid) {
3602 // reset cost value
3603 *rate = INT_MAX;
3604 *distortion = INT64_MAX;
3605 *sse = INT64_MAX;
3606 *skippable = 0;
3607 }
3608
3609 return is_cost_valid;
3610}
3611#endif // CONFIG_VAR_TX
3612
Urvang Joshib100db72016-10-12 16:28:56 -07003613#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003614static void rd_pick_palette_intra_sbuv(
Urvang Joshi52648442016-10-13 17:27:51 -07003615 const AV1_COMP *const cpi, MACROBLOCK *x, int dc_mode_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003616 PALETTE_MODE_INFO *palette_mode_info, uint8_t *best_palette_color_map,
3617 PREDICTION_MODE *mode_selected, int64_t *best_rd, int *rate,
3618 int *rate_tokenonly, int64_t *distortion, int *skippable) {
3619 MACROBLOCKD *const xd = &x->e_mbd;
3620 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3621 const BLOCK_SIZE bsize = mbmi->sb_type;
3622 const int rows =
3623 (4 * num_4x4_blocks_high_lookup[bsize]) >> (xd->plane[1].subsampling_y);
3624 const int cols =
3625 (4 * num_4x4_blocks_wide_lookup[bsize]) >> (xd->plane[1].subsampling_x);
3626 int this_rate, this_rate_tokenonly, s;
3627 int64_t this_distortion, this_rd;
3628 int colors_u, colors_v, colors;
3629 const int src_stride = x->plane[1].src.stride;
3630 const uint8_t *const src_u = x->plane[1].src.buf;
3631 const uint8_t *const src_v = x->plane[2].src.buf;
3632
3633 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return;
3634
hui su5db97432016-10-14 16:10:14 -07003635#if CONFIG_FILTER_INTRA
3636 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
3637#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003638
Yaowu Xuf883b422016-08-30 14:01:10 -07003639#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003640 if (cpi->common.use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003641 colors_u = av1_count_colors_highbd(src_u, src_stride, rows, cols,
3642 cpi->common.bit_depth);
3643 colors_v = av1_count_colors_highbd(src_v, src_stride, rows, cols,
3644 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003645 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003646#endif // CONFIG_AOM_HIGHBITDEPTH
3647 colors_u = av1_count_colors(src_u, src_stride, rows, cols);
3648 colors_v = av1_count_colors(src_v, src_stride, rows, cols);
3649#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003650 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003651#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003652
3653 colors = colors_u > colors_v ? colors_u : colors_v;
3654 if (colors > 1 && colors <= 64) {
3655 int r, c, n, i, j;
3656 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07003657 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003658 int64_t this_sse;
3659 float lb_u, ub_u, val_u;
3660 float lb_v, ub_v, val_v;
3661 float *const data = x->palette_buffer->kmeans_data_buf;
3662 float centroids[2 * PALETTE_MAX_SIZE];
3663 uint8_t *const color_map = xd->plane[1].color_index_map;
3664 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
3665
Yaowu Xuf883b422016-08-30 14:01:10 -07003666#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003667 uint16_t *src_u16 = CONVERT_TO_SHORTPTR(src_u);
3668 uint16_t *src_v16 = CONVERT_TO_SHORTPTR(src_v);
3669 if (cpi->common.use_highbitdepth) {
3670 lb_u = src_u16[0];
3671 ub_u = src_u16[0];
3672 lb_v = src_v16[0];
3673 ub_v = src_v16[0];
3674 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003675#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003676 lb_u = src_u[0];
3677 ub_u = src_u[0];
3678 lb_v = src_v[0];
3679 ub_v = src_v[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07003680#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003681 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003682#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003683
3684 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07003685#if CONFIG_FILTER_INTRA
3686 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
3687#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003688 for (r = 0; r < rows; ++r) {
3689 for (c = 0; c < cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003690#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003691 if (cpi->common.use_highbitdepth) {
3692 val_u = src_u16[r * src_stride + c];
3693 val_v = src_v16[r * src_stride + c];
3694 data[(r * cols + c) * 2] = val_u;
3695 data[(r * cols + c) * 2 + 1] = val_v;
3696 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003697#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003698 val_u = src_u[r * src_stride + c];
3699 val_v = src_v[r * src_stride + c];
3700 data[(r * cols + c) * 2] = val_u;
3701 data[(r * cols + c) * 2 + 1] = val_v;
Yaowu Xuf883b422016-08-30 14:01:10 -07003702#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003703 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003704#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003705 if (val_u < lb_u)
3706 lb_u = val_u;
3707 else if (val_u > ub_u)
3708 ub_u = val_u;
3709 if (val_v < lb_v)
3710 lb_v = val_v;
3711 else if (val_v > ub_v)
3712 ub_v = val_v;
3713 }
3714 }
3715
3716 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
3717 --n) {
3718 for (i = 0; i < n; ++i) {
3719 centroids[i * 2] = lb_u + (2 * i + 1) * (ub_u - lb_u) / n / 2;
3720 centroids[i * 2 + 1] = lb_v + (2 * i + 1) * (ub_v - lb_v) / n / 2;
3721 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003722 av1_k_means(data, centroids, color_map, rows * cols, n, 2, max_itr);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003723 pmi->palette_size[1] = n;
3724 for (i = 1; i < 3; ++i) {
3725 for (j = 0; j < n; ++j) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003726#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003727 if (cpi->common.use_highbitdepth)
3728 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] = clip_pixel_highbd(
3729 (int)centroids[j * 2 + i - 1], cpi->common.bit_depth);
3730 else
Yaowu Xuf883b422016-08-30 14:01:10 -07003731#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003732 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
3733 clip_pixel((int)centroids[j * 2 + i - 1]);
3734 }
3735 }
3736
3737 super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s,
3738 &this_sse, bsize, *best_rd);
3739 if (this_rate_tokenonly == INT_MAX) continue;
3740 this_rate =
3741 this_rate_tokenonly + dc_mode_cost +
Yaowu Xuf883b422016-08-30 14:01:10 -07003742 2 * cpi->common.bit_depth * n * av1_cost_bit(128, 0) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003743 cpi->palette_uv_size_cost[bsize - BLOCK_8X8][n - 2] +
3744 write_uniform_cost(n, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07003745 av1_cost_bit(
3746 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003747
3748 for (i = 0; i < rows; ++i) {
3749 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07003750 int color_idx;
3751 const int color_ctx = av1_get_palette_color_context(
3752 color_map, cols, i, j, n, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003753 assert(color_idx >= 0 && color_idx < n);
3754 this_rate += cpi->palette_uv_color_cost[n - 2][color_ctx][color_idx];
3755 }
3756 }
3757
3758 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3759 if (this_rd < *best_rd) {
3760 *best_rd = this_rd;
3761 *palette_mode_info = *pmi;
3762 memcpy(best_palette_color_map, color_map,
3763 rows * cols * sizeof(best_palette_color_map[0]));
3764 *mode_selected = DC_PRED;
3765 *rate = this_rate;
3766 *distortion = this_distortion;
3767 *rate_tokenonly = this_rate_tokenonly;
3768 *skippable = s;
3769 }
3770 }
3771 }
3772}
Urvang Joshib100db72016-10-12 16:28:56 -07003773#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003774
hui su5db97432016-10-14 16:10:14 -07003775#if CONFIG_FILTER_INTRA
3776// Return 1 if an filter intra mode is selected; return 0 otherwise.
3777static int rd_pick_filter_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
3778 int *rate, int *rate_tokenonly,
3779 int64_t *distortion, int *skippable,
3780 BLOCK_SIZE bsize, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003781 MACROBLOCKD *const xd = &x->e_mbd;
3782 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su5db97432016-10-14 16:10:14 -07003783 int filter_intra_selected_flag = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003784 int this_rate_tokenonly, this_rate, s;
3785 int64_t this_distortion, this_sse, this_rd;
hui su5db97432016-10-14 16:10:14 -07003786 FILTER_INTRA_MODE mode;
3787 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003788
hui su5db97432016-10-14 16:10:14 -07003789 av1_zero(filter_intra_mode_info);
3790 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003791 mbmi->uv_mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07003792#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003793 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003794#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003795
3796 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su5db97432016-10-14 16:10:14 -07003797 mbmi->filter_intra_mode_info.filter_intra_mode[1] = mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003798 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s,
3799 &this_sse, bsize, *best_rd))
3800 continue;
3801
3802 this_rate = this_rate_tokenonly +
hui su5db97432016-10-14 16:10:14 -07003803 av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003804 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
3805 write_uniform_cost(FILTER_INTRA_MODES, mode);
3806 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3807 if (this_rd < *best_rd) {
3808 *best_rd = this_rd;
3809 *rate = this_rate;
3810 *rate_tokenonly = this_rate_tokenonly;
3811 *distortion = this_distortion;
3812 *skippable = s;
hui su5db97432016-10-14 16:10:14 -07003813 filter_intra_mode_info = mbmi->filter_intra_mode_info;
3814 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003815 }
3816 }
3817
hui su5db97432016-10-14 16:10:14 -07003818 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003819 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07003820 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
3821 filter_intra_mode_info.use_filter_intra_mode[1];
3822 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
3823 filter_intra_mode_info.filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003824 return 1;
3825 } else {
3826 return 0;
3827 }
3828}
hui su5db97432016-10-14 16:10:14 -07003829#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003830
hui su5db97432016-10-14 16:10:14 -07003831#if CONFIG_EXT_INTRA
Urvang Joshi52648442016-10-13 17:27:51 -07003832static void pick_intra_angle_routine_sbuv(
3833 const AV1_COMP *const cpi, MACROBLOCK *x, int *rate, int *rate_tokenonly,
3834 int64_t *distortion, int *skippable, int *best_angle_delta,
3835 BLOCK_SIZE bsize, int rate_overhead, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003836 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
3837 int this_rate_tokenonly, this_rate, s;
3838 int64_t this_distortion, this_sse, this_rd;
3839
3840 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s,
3841 &this_sse, bsize, *best_rd))
3842 return;
3843
3844 this_rate = this_rate_tokenonly + rate_overhead;
3845 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3846 if (this_rd < *best_rd) {
3847 *best_rd = this_rd;
3848 *best_angle_delta = mbmi->angle_delta[1];
3849 *rate = this_rate;
3850 *rate_tokenonly = this_rate_tokenonly;
3851 *distortion = this_distortion;
3852 *skippable = s;
3853 }
3854}
3855
Urvang Joshi52648442016-10-13 17:27:51 -07003856static int rd_pick_intra_angle_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
3857 int *rate, int *rate_tokenonly,
3858 int64_t *distortion, int *skippable,
3859 BLOCK_SIZE bsize, int rate_overhead,
3860 int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003861 MACROBLOCKD *const xd = &x->e_mbd;
3862 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
3863 int this_rate_tokenonly, this_rate, s;
3864 int64_t this_distortion, this_sse, this_rd;
3865 int angle_delta, best_angle_delta = 0;
3866 const double rd_adjust = 1.2;
3867
3868 *rate_tokenonly = INT_MAX;
3869 if (ANGLE_FAST_SEARCH) {
3870 int deltas_level1[3] = { 0, -2, 2 };
3871 int deltas_level2[3][2] = {
3872 { -1, 1 }, { -3, -1 }, { 1, 3 },
3873 };
3874 const int level1 = 3, level2 = 2;
3875 int i, j, best_i = -1;
3876
3877 for (i = 0; i < level1; ++i) {
3878 int64_t tmp_best_rd;
3879 mbmi->angle_delta[1] = deltas_level1[i];
3880 tmp_best_rd = (i == 0 && best_rd < INT64_MAX)
3881 ? (int64_t)(best_rd * rd_adjust)
3882 : best_rd;
3883 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s,
3884 &this_sse, bsize, tmp_best_rd)) {
3885 if (i == 0)
3886 break;
3887 else
3888 continue;
3889 }
3890 this_rate = this_rate_tokenonly + rate_overhead;
3891 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3892 if (i == 0 && best_rd < INT64_MAX && this_rd > best_rd * rd_adjust) break;
3893 if (this_rd < best_rd) {
3894 best_i = i;
3895 best_rd = this_rd;
3896 best_angle_delta = mbmi->angle_delta[1];
3897 *rate = this_rate;
3898 *rate_tokenonly = this_rate_tokenonly;
3899 *distortion = this_distortion;
3900 *skippable = s;
3901 }
3902 }
3903
3904 if (best_i >= 0) {
3905 for (j = 0; j < level2; ++j) {
3906 mbmi->angle_delta[1] = deltas_level2[best_i][j];
3907 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly, distortion,
3908 skippable, &best_angle_delta, bsize,
3909 rate_overhead, &best_rd);
3910 }
3911 }
3912 } else {
3913 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
3914 ++angle_delta) {
3915 mbmi->angle_delta[1] = angle_delta;
3916 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly, distortion,
3917 skippable, &best_angle_delta, bsize,
3918 rate_overhead, &best_rd);
3919 }
3920 }
3921
3922 mbmi->angle_delta[1] = best_angle_delta;
3923 return *rate_tokenonly != INT_MAX;
3924}
3925#endif // CONFIG_EXT_INTRA
3926
Urvang Joshi52648442016-10-13 17:27:51 -07003927static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
3928 int *rate, int *rate_tokenonly,
3929 int64_t *distortion, int *skippable,
3930 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003931 MACROBLOCKD *xd = &x->e_mbd;
3932 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
3933 PREDICTION_MODE mode;
3934 PREDICTION_MODE mode_selected = DC_PRED;
3935 int64_t best_rd = INT64_MAX, this_rd;
3936 int this_rate_tokenonly, this_rate, s;
3937 int64_t this_distortion, this_sse;
Urvang Joshib100db72016-10-12 16:28:56 -07003938#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003939 const int rows =
3940 (4 * num_4x4_blocks_high_lookup[bsize]) >> (xd->plane[1].subsampling_y);
3941 const int cols =
3942 (4 * num_4x4_blocks_wide_lookup[bsize]) >> (xd->plane[1].subsampling_x);
3943 PALETTE_MODE_INFO palette_mode_info;
3944 PALETTE_MODE_INFO *const pmi = &xd->mi[0]->mbmi.palette_mode_info;
3945 uint8_t *best_palette_color_map = NULL;
Urvang Joshib100db72016-10-12 16:28:56 -07003946#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003947#if CONFIG_EXT_INTRA
3948 int is_directional_mode, rate_overhead, best_angle_delta = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003949#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003950#if CONFIG_FILTER_INTRA
3951 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
3952
3953 filter_intra_mode_info.use_filter_intra_mode[1] = 0;
3954 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
3955#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07003956#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003957 palette_mode_info.palette_size[1] = 0;
3958 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003959#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003960 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
3961 if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode))) continue;
3962
3963 mbmi->uv_mode = mode;
3964#if CONFIG_EXT_INTRA
3965 is_directional_mode = (mode != DC_PRED && mode != TM_PRED);
3966 rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
3967 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
3968 mbmi->angle_delta[1] = 0;
3969 if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode) {
3970 if (!rd_pick_intra_angle_sbuv(cpi, x, &this_rate, &this_rate_tokenonly,
3971 &this_distortion, &s, bsize, rate_overhead,
3972 best_rd))
3973 continue;
3974 } else {
3975 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s,
3976 &this_sse, bsize, best_rd))
3977 continue;
3978 }
3979 this_rate = this_rate_tokenonly + cpi->intra_uv_mode_cost[mbmi->mode][mode];
3980 if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode)
3981 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
3982 MAX_ANGLE_DELTAS + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003983#else
3984 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s,
3985 &this_sse, bsize, best_rd))
3986 continue;
3987 this_rate = this_rate_tokenonly + cpi->intra_uv_mode_cost[mbmi->mode][mode];
3988#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003989#if CONFIG_FILTER_INTRA
3990 if (mbmi->sb_type >= BLOCK_8X8 && mode == DC_PRED)
3991 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 0);
3992#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07003993#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003994 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8 &&
3995 mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07003996 this_rate += av1_cost_bit(
3997 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07003998#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003999
4000 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
4001
4002 if (this_rd < best_rd) {
4003 mode_selected = mode;
4004#if CONFIG_EXT_INTRA
4005 best_angle_delta = mbmi->angle_delta[1];
4006#endif // CONFIG_EXT_INTRA
4007 best_rd = this_rd;
4008 *rate = this_rate;
4009 *rate_tokenonly = this_rate_tokenonly;
4010 *distortion = this_distortion;
4011 *skippable = s;
4012 }
4013 }
4014
Urvang Joshib100db72016-10-12 16:28:56 -07004015#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004016 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8) {
4017 best_palette_color_map = x->palette_buffer->best_palette_color_map;
4018 rd_pick_palette_intra_sbuv(
4019 cpi, x, cpi->intra_uv_mode_cost[mbmi->mode][DC_PRED],
4020 &palette_mode_info, best_palette_color_map, &mode_selected, &best_rd,
4021 rate, rate_tokenonly, distortion, skippable);
4022 }
Urvang Joshib100db72016-10-12 16:28:56 -07004023#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004024
hui su5db97432016-10-14 16:10:14 -07004025#if CONFIG_FILTER_INTRA
4026 if (mbmi->sb_type >= BLOCK_8X8) {
4027 if (rd_pick_filter_intra_sbuv(cpi, x, rate, rate_tokenonly, distortion,
4028 skippable, bsize, &best_rd)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004029 mode_selected = mbmi->uv_mode;
hui su5db97432016-10-14 16:10:14 -07004030 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004031 }
4032 }
4033
hui su5db97432016-10-14 16:10:14 -07004034 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
4035 filter_intra_mode_info.use_filter_intra_mode[1];
4036 if (filter_intra_mode_info.use_filter_intra_mode[1]) {
4037 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
4038 filter_intra_mode_info.filter_intra_mode[1];
Urvang Joshib100db72016-10-12 16:28:56 -07004039#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004040 palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004041#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004042 }
hui su5db97432016-10-14 16:10:14 -07004043#endif // CONFIG_FILTER_INTRA
4044
4045#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004046 mbmi->angle_delta[1] = best_angle_delta;
4047#endif // CONFIG_EXT_INTRA
4048 mbmi->uv_mode = mode_selected;
Urvang Joshib100db72016-10-12 16:28:56 -07004049#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004050 pmi->palette_size[1] = palette_mode_info.palette_size[1];
4051 if (palette_mode_info.palette_size[1] > 0) {
4052 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
4053 palette_mode_info.palette_colors + PALETTE_MAX_SIZE,
4054 2 * PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
4055 memcpy(xd->plane[1].color_index_map, best_palette_color_map,
4056 rows * cols * sizeof(best_palette_color_map[0]));
4057 }
Urvang Joshib100db72016-10-12 16:28:56 -07004058#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004059
4060 return best_rd;
4061}
4062
Urvang Joshi52648442016-10-13 17:27:51 -07004063static void choose_intra_uv_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004064 PICK_MODE_CONTEXT *ctx, BLOCK_SIZE bsize,
4065 TX_SIZE max_tx_size, int *rate_uv,
4066 int *rate_uv_tokenonly, int64_t *dist_uv,
4067 int *skip_uv, PREDICTION_MODE *mode_uv) {
4068 // Use an estimated rd for uv_intra based on DC_PRED if the
4069 // appropriate speed flag is set.
Jingning Han3f167252016-06-07 16:11:42 -07004070 (void)ctx;
4071 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4072 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004073 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
4074}
4075
Urvang Joshi52648442016-10-13 17:27:51 -07004076static int cost_mv_ref(const AV1_COMP *const cpi, PREDICTION_MODE mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004077#if CONFIG_REF_MV && CONFIG_EXT_INTER
4078 int is_compound,
4079#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4080 int16_t mode_context) {
4081#if CONFIG_REF_MV
4082 int mode_cost = 0;
4083#if CONFIG_EXT_INTER
4084 int16_t mode_ctx =
4085 is_compound ? mode_context : (mode_context & NEWMV_CTX_MASK);
4086#else
4087 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
4088#endif // CONFIG_EXT_INTER
4089 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
4090
4091 assert(is_inter_mode(mode));
4092
4093#if CONFIG_EXT_INTER
4094 if (is_compound) {
clang-format67948d32016-09-07 22:40:40 -07004095 return cpi->inter_compound_mode_cost[mode_context]
4096 [INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004097 } else {
4098 if (mode == NEWMV || mode == NEWFROMNEARMV) {
4099#else
4100 if (mode == NEWMV) {
4101#endif // CONFIG_EXT_INTER
4102 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
4103#if CONFIG_EXT_INTER
4104 if (!is_compound)
4105 mode_cost += cpi->new2mv_mode_cost[mode == NEWFROMNEARMV];
4106#endif // CONFIG_EXT_INTER
4107 return mode_cost;
4108 } else {
4109 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
4110 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
4111
4112 if (is_all_zero_mv) return mode_cost;
4113
4114 if (mode == ZEROMV) {
4115 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
4116 return mode_cost;
4117 } else {
4118 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
4119 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
4120
4121 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
4122 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
4123 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
4124
4125 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
4126 return mode_cost;
4127 }
4128 }
4129#if CONFIG_EXT_INTER
4130 }
4131#endif // CONFIG_EXT_INTER
4132#else
4133 assert(is_inter_mode(mode));
4134#if CONFIG_EXT_INTER
4135 if (is_inter_compound_mode(mode)) {
clang-format67948d32016-09-07 22:40:40 -07004136 return cpi->inter_compound_mode_cost[mode_context]
4137 [INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004138 } else {
4139#endif // CONFIG_EXT_INTER
4140 return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
4141#if CONFIG_EXT_INTER
4142 }
4143#endif // CONFIG_EXT_INTER
4144#endif
4145}
4146
Sarah Parkere5299862016-08-16 14:57:37 -07004147#if CONFIG_GLOBAL_MOTION
4148static int get_gmbitcost(const Global_Motion_Params *gm,
4149 const aom_prob *probs) {
4150 int gmtype_cost[GLOBAL_MOTION_TYPES];
4151 int bits;
4152 av1_cost_tokens(gmtype_cost, probs, av1_global_motion_types_tree);
4153 if (gm->motion_params.wmmat[2].as_int) {
4154 bits = (GM_ABS_TRANS_BITS + 1) * 2 + 4 * GM_ABS_ALPHA_BITS + 4;
4155 } else if (gm->motion_params.wmmat[1].as_int) {
4156 bits = (GM_ABS_TRANS_BITS + 1) * 2 + 2 * GM_ABS_ALPHA_BITS + 2;
4157 } else {
4158 bits =
4159 (gm->motion_params.wmmat[0].as_int ? ((GM_ABS_TRANS_BITS + 1) * 2) : 0);
4160 }
Sarah Parkerae51dd82016-10-18 16:18:23 -07004161 return bits ? (bits << AV1_PROB_COST_SHIFT) + gmtype_cost[gm->gmtype] : 0;
Sarah Parkere5299862016-08-16 14:57:37 -07004162}
4163
4164#define GLOBAL_MOTION_RATE(ref) \
4165 (cpi->global_motion_used[ref] >= 2 \
4166 ? 0 \
4167 : get_gmbitcost(&cm->global_motion[(ref)], \
4168 cm->fc->global_motion_types_prob) / \
4169 2);
4170#endif // CONFIG_GLOBAL_MOTION
4171
Urvang Joshi52648442016-10-13 17:27:51 -07004172static int set_and_cost_bmi_mvs(const AV1_COMP *const cpi, MACROBLOCK *x,
4173 MACROBLOCKD *xd, int i, PREDICTION_MODE mode,
4174 int_mv this_mv[2],
clang-format67948d32016-09-07 22:40:40 -07004175 int_mv frame_mv[MB_MODE_COUNT]
4176 [TOTAL_REFS_PER_FRAME],
4177 int_mv seg_mvs[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004178#if CONFIG_EXT_INTER
clang-format67948d32016-09-07 22:40:40 -07004179 int_mv compound_seg_newmvs[2],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004180#endif // CONFIG_EXT_INTER
clang-format67948d32016-09-07 22:40:40 -07004181 int_mv *best_ref_mv[2], const int *mvjcost,
4182 int *mvcost[2]) {
Sarah Parkere5299862016-08-16 14:57:37 -07004183#if CONFIG_GLOBAL_MOTION
4184 const AV1_COMMON *cm = &cpi->common;
4185#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004186 MODE_INFO *const mic = xd->mi[0];
4187 const MB_MODE_INFO *const mbmi = &mic->mbmi;
4188 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4189 int thismvcost = 0;
4190 int idx, idy;
4191 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
4192 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
4193 const int is_compound = has_second_ref(mbmi);
4194 int mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
4195
4196 switch (mode) {
4197 case NEWMV:
4198#if CONFIG_EXT_INTER
4199 case NEWFROMNEARMV:
4200#endif // CONFIG_EXT_INTER
4201 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
4202#if CONFIG_EXT_INTER
Alex Converse6317c882016-09-29 14:21:37 -07004203 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004204 lower_mv_precision(&this_mv[0].as_mv, 0);
4205#endif // CONFIG_EXT_INTER
4206
4207#if CONFIG_REF_MV
4208 for (idx = 0; idx < 1 + is_compound; ++idx) {
4209 this_mv[idx] = seg_mvs[mbmi->ref_frame[idx]];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07004210 av1_set_mvcost(x, mbmi->ref_frame[idx], idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004211 thismvcost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07004212 av1_mv_bit_cost(&this_mv[idx].as_mv, &best_ref_mv[idx]->as_mv,
4213 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004214 }
4215 (void)mvjcost;
4216 (void)mvcost;
4217#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004218 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4219 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004220#if !CONFIG_EXT_INTER
4221 if (is_compound) {
4222 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07004223 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4224 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004225 }
4226#endif // !CONFIG_EXT_INTER
4227#endif
4228 break;
4229 case NEARMV:
4230 case NEARESTMV:
4231 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4232 if (is_compound)
4233 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4234 break;
4235 case ZEROMV:
Sarah Parkere5299862016-08-16 14:57:37 -07004236#if CONFIG_GLOBAL_MOTION
4237 this_mv[0].as_int = cpi->common.global_motion[mbmi->ref_frame[0]]
4238 .motion_params.wmmat[0]
4239 .as_int;
4240 thismvcost += GLOBAL_MOTION_RATE(mbmi->ref_frame[0]);
4241 if (is_compound) {
4242 this_mv[1].as_int = cpi->common.global_motion[mbmi->ref_frame[1]]
4243 .motion_params.wmmat[0]
4244 .as_int;
4245 thismvcost += GLOBAL_MOTION_RATE(mbmi->ref_frame[1]);
4246 }
4247#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004248 this_mv[0].as_int = 0;
4249 if (is_compound) this_mv[1].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07004250#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004251 break;
4252#if CONFIG_EXT_INTER
4253 case NEW_NEWMV:
4254 if (compound_seg_newmvs[0].as_int == INVALID_MV ||
4255 compound_seg_newmvs[1].as_int == INVALID_MV) {
4256 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
4257 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
4258 } else {
4259 this_mv[0].as_int = compound_seg_newmvs[0].as_int;
4260 this_mv[1].as_int = compound_seg_newmvs[1].as_int;
4261 }
Alex Converse6317c882016-09-29 14:21:37 -07004262 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004263 lower_mv_precision(&this_mv[0].as_mv, 0);
Alex Converse6317c882016-09-29 14:21:37 -07004264 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004265 lower_mv_precision(&this_mv[1].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07004266 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4267 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
4268 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4269 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004270 break;
4271 case NEW_NEARMV:
4272 case NEW_NEARESTMV:
4273 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07004274 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004275 lower_mv_precision(&this_mv[0].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07004276 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4277 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004278 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4279 break;
4280 case NEAR_NEWMV:
4281 case NEAREST_NEWMV:
4282 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4283 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07004284 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004285 lower_mv_precision(&this_mv[1].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07004286 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4287 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004288 break;
4289 case NEAREST_NEARMV:
4290 case NEAR_NEARESTMV:
4291 case NEAREST_NEARESTMV:
4292 case NEAR_NEARMV:
4293 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4294 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4295 break;
4296 case ZERO_ZEROMV:
4297 this_mv[0].as_int = 0;
4298 this_mv[1].as_int = 0;
4299 break;
4300#endif // CONFIG_EXT_INTER
4301 default: break;
4302 }
4303
4304 mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
4305 if (is_compound) mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
4306
4307 mic->bmi[i].as_mode = mode;
4308
4309#if CONFIG_REF_MV
4310 if (mode == NEWMV) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07004311 mic->bmi[i].pred_mv[0].as_int =
4312 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_int;
4313 if (is_compound)
4314 mic->bmi[i].pred_mv[1].as_int =
4315 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004316 } else {
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07004317 mic->bmi[i].pred_mv[0].as_int = this_mv[0].as_int;
4318 if (is_compound) mic->bmi[i].pred_mv[1].as_int = this_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004319 }
4320#endif
4321
4322 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
4323 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
4324 memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
4325
4326#if CONFIG_REF_MV
4327#if CONFIG_EXT_INTER
4328 if (is_compound)
4329 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
4330 else
4331#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07004332 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
4333 mbmi->ref_frame, mbmi->sb_type, i);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004334#endif
4335#if CONFIG_REF_MV && CONFIG_EXT_INTER
4336 return cost_mv_ref(cpi, mode, is_compound, mode_ctx) + thismvcost;
4337#else
4338 return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
4339#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4340}
4341
Urvang Joshi52648442016-10-13 17:27:51 -07004342static int64_t encode_inter_mb_segment(const AV1_COMP *const cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004343 int64_t best_yrd, int i, int *labelyrate,
4344 int64_t *distortion, int64_t *sse,
4345 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
4346 int ir, int ic, int mi_row, int mi_col) {
Angie Chiang22ba7512016-10-20 17:10:33 -07004347 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004348 int k;
4349 MACROBLOCKD *xd = &x->e_mbd;
4350 struct macroblockd_plane *const pd = &xd->plane[0];
4351 struct macroblock_plane *const p = &x->plane[0];
4352 MODE_INFO *const mi = xd->mi[0];
4353 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
Jingning Hanc4049db2016-10-27 14:44:13 -07004354 const int width = block_size_wide[plane_bsize];
4355 const int height = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004356 int idx, idy;
4357 const uint8_t *const src =
Yaowu Xuf883b422016-08-30 14:01:10 -07004358 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004359 uint8_t *const dst =
Yaowu Xuf883b422016-08-30 14:01:10 -07004360 &pd->dst.buf[av1_raster_block_offset(BLOCK_8X8, i, pd->dst.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004361 int64_t thisdistortion = 0, thissse = 0;
4362 int thisrate = 0;
4363 TX_SIZE tx_size = mi->mbmi.tx_size;
4364
4365 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, i, tx_size);
Angie Chiangff6d8902016-10-21 11:02:09 -07004366 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 1);
Jingning Hanc4049db2016-10-27 14:44:13 -07004367 const int num_4x4_w = tx_size_wide_unit[tx_size];
4368 const int num_4x4_h = tx_size_high_unit[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004369
4370#if CONFIG_EXT_TX && CONFIG_RECT_TX
4371 assert(IMPLIES(xd->lossless[mi->mbmi.segment_id], tx_size == TX_4X4));
4372 assert(IMPLIES(!xd->lossless[mi->mbmi.segment_id],
4373 tx_size == max_txsize_rect_lookup[mi->mbmi.sb_type]));
4374#else
4375 assert(tx_size == TX_4X4);
4376#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4377 assert(tx_type == DCT_DCT);
4378
Yaowu Xuf883b422016-08-30 14:01:10 -07004379 av1_build_inter_predictor_sub8x8(xd, 0, i, ir, ic, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004380
Yaowu Xuf883b422016-08-30 14:01:10 -07004381#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004382 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004383 aom_highbd_subtract_block(
4384 height, width, av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
4385 8, src, p->src.stride, dst, pd->dst.stride, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004386 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004387 aom_subtract_block(height, width,
4388 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07004389 8, src, p->src.stride, dst, pd->dst.stride);
4390 }
4391#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004392 aom_subtract_block(height, width,
4393 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07004394 8, src, p->src.stride, dst, pd->dst.stride);
Yaowu Xuf883b422016-08-30 14:01:10 -07004395#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004396
4397 k = i;
4398 for (idy = 0; idy < height / 4; idy += num_4x4_h) {
4399 for (idx = 0; idx < width / 4; idx += num_4x4_w) {
4400 int64_t dist, ssz, rd, rd1, rd2;
4401 int block;
4402 int coeff_ctx;
4403 k += (idy * 2 + idx);
4404 if (tx_size == TX_4X4)
4405 block = k;
4406 else
4407 block = (i ? 2 : 0);
Jingning Hanc4049db2016-10-27 14:44:13 -07004408
Yaowu Xuc27fc142016-08-22 16:08:15 -07004409 coeff_ctx = combine_entropy_contexts(*(ta + (k & 1)), *(tl + (k >> 1)));
4410#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07004411 av1_xform_quant_fp_nuq(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
Yaowu Xuf883b422016-08-30 14:01:10 -07004412 BLOCK_8X8, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004413#else
Angie Chiangff6d8902016-10-21 11:02:09 -07004414 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
4415 BLOCK_8X8, tx_size, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004416#endif // CONFIG_NEW_QUANT
4417 if (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0)
Angie Chiangff6d8902016-10-21 11:02:09 -07004418 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004419 dist_block(cpi, x, 0, block, idy + (i >> 1), idx + (i & 0x1), tx_size,
4420 &dist, &ssz);
4421 thisdistortion += dist;
4422 thissse += ssz;
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07004423 thisrate +=
Angie Chiang22ba7512016-10-20 17:10:33 -07004424 av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size, scan_order->scan,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07004425 scan_order->neighbors, cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004426 *(ta + (k & 1)) = !(p->eobs[block] == 0);
4427 *(tl + (k >> 1)) = !(p->eobs[block] == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004428#if CONFIG_EXT_TX
4429 if (tx_size == TX_8X4) {
4430 *(ta + (k & 1) + 1) = *(ta + (k & 1));
4431 }
4432 if (tx_size == TX_4X8) {
4433 *(tl + (k >> 1) + 1) = *(tl + (k >> 1));
4434 }
4435#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004436 rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion);
4437 rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse);
Yaowu Xuf883b422016-08-30 14:01:10 -07004438 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004439 if (rd >= best_yrd) return INT64_MAX;
4440 }
4441 }
4442
4443 *distortion = thisdistortion;
4444 *labelyrate = thisrate;
4445 *sse = thissse;
4446
4447 return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
4448}
4449
4450typedef struct {
4451 int eobs;
4452 int brate;
4453 int byrate;
4454 int64_t bdist;
4455 int64_t bsse;
4456 int64_t brdcost;
4457 int_mv mvs[2];
4458#if CONFIG_REF_MV
4459 int_mv pred_mv[2];
4460#endif
4461#if CONFIG_EXT_INTER
4462 int_mv ref_mv[2];
4463#endif // CONFIG_EXT_INTER
4464 ENTROPY_CONTEXT ta[2];
4465 ENTROPY_CONTEXT tl[2];
4466} SEG_RDSTAT;
4467
4468typedef struct {
4469 int_mv *ref_mv[2];
4470 int_mv mvp;
4471
4472 int64_t segment_rd;
4473 int r;
4474 int64_t d;
4475 int64_t sse;
4476 int segment_yrate;
4477 PREDICTION_MODE modes[4];
4478#if CONFIG_EXT_INTER
4479 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
4480#else
4481 SEG_RDSTAT rdstat[4][INTER_MODES];
4482#endif // CONFIG_EXT_INTER
4483 int mvthresh;
4484} BEST_SEG_INFO;
4485
4486static INLINE int mv_check_bounds(const MACROBLOCK *x, const MV *mv) {
4487 return (mv->row >> 3) < x->mv_row_min || (mv->row >> 3) > x->mv_row_max ||
4488 (mv->col >> 3) < x->mv_col_min || (mv->col >> 3) > x->mv_col_max;
4489}
4490
4491static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
4492 MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
4493 struct macroblock_plane *const p = &x->plane[0];
4494 struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
4495
4496 p->src.buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07004497 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004498 assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
4499 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07004500 &pd->pre[0].buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[0].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004501 if (has_second_ref(mbmi))
4502 pd->pre[1].buf =
4503 &pd->pre[1]
Yaowu Xuf883b422016-08-30 14:01:10 -07004504 .buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[1].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004505}
4506
4507static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
4508 struct buf_2d orig_pre[2]) {
4509 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
4510 x->plane[0].src = orig_src;
4511 x->e_mbd.plane[0].pre[0] = orig_pre[0];
4512 if (has_second_ref(mbmi)) x->e_mbd.plane[0].pre[1] = orig_pre[1];
4513}
4514
4515// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
4516// TODO(aconverse): Find out if this is still productive then clean up or remove
4517static int check_best_zero_mv(
Urvang Joshi52648442016-10-13 17:27:51 -07004518 const AV1_COMP *const cpi, const int16_t mode_context[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004519#if CONFIG_REF_MV && CONFIG_EXT_INTER
4520 const int16_t compound_mode_context[TOTAL_REFS_PER_FRAME],
4521#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4522 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME], int this_mode,
4523 const MV_REFERENCE_FRAME ref_frames[2], const BLOCK_SIZE bsize, int block) {
4524
4525#if !CONFIG_EXT_INTER
4526 assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
4527#endif
4528
4529 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
4530 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
4531 (ref_frames[1] <= INTRA_FRAME ||
4532 frame_mv[this_mode][ref_frames[1]].as_int == 0)) {
4533#if CONFIG_REF_MV
4534 int16_t rfc =
Yaowu Xuf883b422016-08-30 14:01:10 -07004535 av1_mode_context_analyzer(mode_context, ref_frames, bsize, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004536#else
4537 int16_t rfc = mode_context[ref_frames[0]];
4538#endif
4539#if CONFIG_REF_MV && CONFIG_EXT_INTER
4540 int c1 = cost_mv_ref(cpi, NEARMV, ref_frames[1] > INTRA_FRAME, rfc);
4541 int c2 = cost_mv_ref(cpi, NEARESTMV, ref_frames[1] > INTRA_FRAME, rfc);
4542 int c3 = cost_mv_ref(cpi, ZEROMV, ref_frames[1] > INTRA_FRAME, rfc);
4543#else
4544 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
4545 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
4546 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
4547#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4548
4549#if !CONFIG_REF_MV
4550 (void)bsize;
4551 (void)block;
4552#endif
4553
4554 if (this_mode == NEARMV) {
4555 if (c1 > c3) return 0;
4556 } else if (this_mode == NEARESTMV) {
4557 if (c2 > c3) return 0;
4558 } else {
4559 assert(this_mode == ZEROMV);
4560 if (ref_frames[1] <= INTRA_FRAME) {
4561 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
4562 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
4563 return 0;
4564 } else {
4565 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
4566 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
4567 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
4568 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
4569 return 0;
4570 }
4571 }
4572 }
4573#if CONFIG_EXT_INTER
4574 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
4575 this_mode == NEAR_NEARESTMV || this_mode == NEAR_NEARMV ||
4576 this_mode == ZERO_ZEROMV) &&
4577 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
4578 frame_mv[this_mode][ref_frames[1]].as_int == 0) {
4579#if CONFIG_REF_MV
4580 int16_t rfc = compound_mode_context[ref_frames[0]];
4581 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, 1, rfc);
4582 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, 1, rfc);
4583 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, 1, rfc);
4584 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, 1, rfc);
4585 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, 1, rfc);
4586#else
4587 int16_t rfc = mode_context[ref_frames[0]];
4588 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
4589 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
4590 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
4591 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
4592 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, rfc);
4593#endif
4594
4595 if (this_mode == NEAREST_NEARMV) {
4596 if (c1 > c3) return 0;
4597 } else if (this_mode == NEAREST_NEARESTMV) {
4598 if (c2 > c3) return 0;
4599 } else if (this_mode == NEAR_NEARESTMV) {
4600 if (c4 > c3) return 0;
4601 } else if (this_mode == NEAR_NEARMV) {
4602 if (c5 > c3) return 0;
4603 } else {
4604 assert(this_mode == ZERO_ZEROMV);
4605 if ((c3 >= c2 && frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
4606 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
4607 (c3 >= c1 && frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
4608 frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
4609 (c3 >= c5 && frame_mv[NEAR_NEARMV][ref_frames[0]].as_int == 0 &&
4610 frame_mv[NEAR_NEARMV][ref_frames[1]].as_int == 0) ||
4611 (c3 >= c4 && frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
4612 frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
4613 return 0;
4614 }
4615 }
4616#endif // CONFIG_EXT_INTER
4617 return 1;
4618}
4619
Urvang Joshi52648442016-10-13 17:27:51 -07004620static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
4621 BLOCK_SIZE bsize, int_mv *frame_mv, int mi_row,
4622 int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004623#if CONFIG_EXT_INTER
4624 int_mv *ref_mv_sub8x8[2],
4625#endif
4626 int_mv single_newmv[TOTAL_REFS_PER_FRAME],
4627 int *rate_mv, const int block) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004628 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004629 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
4630 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
4631 MACROBLOCKD *xd = &x->e_mbd;
4632 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4633 const int refs[2] = { mbmi->ref_frame[0],
4634 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
4635 int_mv ref_mv[2];
4636 int ite, ref;
4637#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07004638 InterpFilter interp_filter[4] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004639 mbmi->interp_filter[0], mbmi->interp_filter[1], mbmi->interp_filter[2],
4640 mbmi->interp_filter[3],
4641 };
4642#else
James Zern7b9407a2016-05-18 23:48:05 -07004643 const InterpFilter interp_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004644#endif
4645 struct scale_factors sf;
4646
4647 // Do joint motion search in compound mode to get more accurate mv.
4648 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
4649 int last_besterr[2] = { INT_MAX, INT_MAX };
4650 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
Yaowu Xuf883b422016-08-30 14:01:10 -07004651 av1_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
4652 av1_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
Yaowu Xuc27fc142016-08-22 16:08:15 -07004653 };
4654
4655// Prediction buffer from second frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07004656#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004657 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
4658 uint8_t *second_pred;
4659#else
4660 DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07004661#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004662
4663 for (ref = 0; ref < 2; ++ref) {
4664#if CONFIG_EXT_INTER
4665 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
4666 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
4667 else
4668#endif // CONFIG_EXT_INTER
4669 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
4670
4671 if (scaled_ref_frame[ref]) {
4672 int i;
4673 // Swap out the reference frame for a version that's been scaled to
4674 // match the resolution of the current frame, allowing the existing
4675 // motion search code to be used without additional modifications.
4676 for (i = 0; i < MAX_MB_PLANE; i++)
4677 backup_yv12[ref][i] = xd->plane[i].pre[ref];
Yaowu Xuf883b422016-08-30 14:01:10 -07004678 av1_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
4679 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004680 }
4681
4682 frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
4683 }
4684
4685// Since we have scaled the reference frames to match the size of the current
4686// frame we must use a unit scaling factor during mode selection.
Yaowu Xuf883b422016-08-30 14:01:10 -07004687#if CONFIG_AOM_HIGHBITDEPTH
4688 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
4689 cm->height, cm->use_highbitdepth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004690#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004691 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
4692 cm->height);
4693#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004694
4695 // Allow joint search multiple times iteratively for each reference frame
4696 // and break out of the search loop if it couldn't find a better mv.
4697 for (ite = 0; ite < 4; ite++) {
4698 struct buf_2d ref_yv12[2];
4699 int bestsme = INT_MAX;
4700 int sadpb = x->sadperbit16;
4701 MV *const best_mv = &x->best_mv.as_mv;
4702 int search_range = 3;
4703
4704 int tmp_col_min = x->mv_col_min;
4705 int tmp_col_max = x->mv_col_max;
4706 int tmp_row_min = x->mv_row_min;
4707 int tmp_row_max = x->mv_row_max;
4708 int id = ite % 2; // Even iterations search in the first reference frame,
4709 // odd iterations search in the second. The predictor
4710 // found for the 'other' reference frame is factored in.
4711
4712 // Initialized here because of compiler problem in Visual Studio.
4713 ref_yv12[0] = xd->plane[0].pre[0];
4714 ref_yv12[1] = xd->plane[0].pre[1];
4715
4716#if CONFIG_DUAL_FILTER
4717 // reload the filter types
4718 interp_filter[0] =
4719 (id == 0) ? mbmi->interp_filter[2] : mbmi->interp_filter[0];
4720 interp_filter[1] =
4721 (id == 0) ? mbmi->interp_filter[3] : mbmi->interp_filter[1];
4722#endif
4723
4724// Get the prediction block from the 'other' reference frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07004725#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004726 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
4727 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
Yaowu Xuf883b422016-08-30 14:01:10 -07004728 av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004729 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
4730 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, 0, interp_filter,
4731 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd->bd);
4732 } else {
4733 second_pred = (uint8_t *)second_pred_alloc_16;
Yaowu Xuf883b422016-08-30 14:01:10 -07004734 av1_build_inter_predictor(ref_yv12[!id].buf, ref_yv12[!id].stride,
4735 second_pred, pw, &frame_mv[refs[!id]].as_mv,
4736 &sf, pw, ph, 0, interp_filter, MV_PRECISION_Q3,
4737 mi_col * MI_SIZE, mi_row * MI_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004738 }
4739#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004740 av1_build_inter_predictor(ref_yv12[!id].buf, ref_yv12[!id].stride,
4741 second_pred, pw, &frame_mv[refs[!id]].as_mv, &sf,
4742 pw, ph, 0, interp_filter, MV_PRECISION_Q3,
4743 mi_col * MI_SIZE, mi_row * MI_SIZE);
4744#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004745
4746 // Do compound motion search on the current reference frame.
4747 if (id) xd->plane[0].pre[0] = ref_yv12[id];
Yaowu Xuf883b422016-08-30 14:01:10 -07004748 av1_set_mv_search_range(x, &ref_mv[id].as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004749
4750 // Use the mv result from the single mode as mv predictor.
4751 *best_mv = frame_mv[refs[id]].as_mv;
4752
4753 best_mv->col >>= 3;
4754 best_mv->row >>= 3;
4755
4756#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07004757 av1_set_mvcost(x, refs[id], id, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004758#endif
4759
4760 // Small-range full-pixel motion search.
4761 bestsme =
Yaowu Xuf883b422016-08-30 14:01:10 -07004762 av1_refining_search_8p_c(x, sadpb, search_range, &cpi->fn_ptr[bsize],
4763 &ref_mv[id].as_mv, second_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004764 if (bestsme < INT_MAX)
Yaowu Xuf883b422016-08-30 14:01:10 -07004765 bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv[id].as_mv,
4766 second_pred, &cpi->fn_ptr[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004767
4768 x->mv_col_min = tmp_col_min;
4769 x->mv_col_max = tmp_col_max;
4770 x->mv_row_min = tmp_row_min;
4771 x->mv_row_max = tmp_row_max;
4772
4773 if (bestsme < INT_MAX) {
4774 int dis; /* TODO: use dis in distortion calculation later. */
4775 unsigned int sse;
4776 if (cpi->sf.use_upsampled_references) {
4777 // Use up-sampled reference frames.
4778 struct macroblockd_plane *const pd = &xd->plane[0];
4779 struct buf_2d backup_pred = pd->pre[0];
4780 const YV12_BUFFER_CONFIG *upsampled_ref =
4781 get_upsampled_ref(cpi, refs[id]);
4782
4783 // Set pred for Y plane
4784 setup_pred_plane(&pd->pre[0], upsampled_ref->y_buffer,
4785 upsampled_ref->y_crop_width,
4786 upsampled_ref->y_crop_height, upsampled_ref->y_stride,
4787 (mi_row << 3), (mi_col << 3), NULL, pd->subsampling_x,
4788 pd->subsampling_y);
4789
4790 // If bsize < BLOCK_8X8, adjust pred pointer for this block
4791 if (bsize < BLOCK_8X8)
4792 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07004793 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, block,
4794 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004795 << 3];
4796
4797 bestsme = cpi->find_fractional_mv_step(
4798 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
4799 x->errorperbit, &cpi->fn_ptr[bsize], 0,
4800 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
4801 &dis, &sse, second_pred, pw, ph, 1);
4802
4803 // Restore the reference frames.
4804 pd->pre[0] = backup_pred;
4805 } else {
4806 (void)block;
4807 bestsme = cpi->find_fractional_mv_step(
4808 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
4809 x->errorperbit, &cpi->fn_ptr[bsize], 0,
4810 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
4811 &dis, &sse, second_pred, pw, ph, 0);
4812 }
4813 }
4814
4815 // Restore the pointer to the first (possibly scaled) prediction buffer.
4816 if (id) xd->plane[0].pre[0] = ref_yv12[0];
4817
4818 if (bestsme < last_besterr[id]) {
4819 frame_mv[refs[id]].as_mv = *best_mv;
4820 last_besterr[id] = bestsme;
4821 } else {
4822 break;
4823 }
4824 }
4825
4826 *rate_mv = 0;
4827
4828 for (ref = 0; ref < 2; ++ref) {
4829 if (scaled_ref_frame[ref]) {
4830 // Restore the prediction frame pointers to their unscaled versions.
4831 int i;
4832 for (i = 0; i < MAX_MB_PLANE; i++)
4833 xd->plane[i].pre[ref] = backup_yv12[ref][i];
4834 }
4835#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07004836 av1_set_mvcost(x, refs[ref], ref, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004837#endif
4838#if CONFIG_EXT_INTER
4839 if (bsize >= BLOCK_8X8)
4840#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07004841 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
4842 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
4843 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004844#if CONFIG_EXT_INTER
4845 else
Yaowu Xuf883b422016-08-30 14:01:10 -07004846 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
4847 &ref_mv_sub8x8[ref]->as_mv, x->nmvjointcost,
4848 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004849#endif // CONFIG_EXT_INTER
4850 }
4851}
4852
4853static int64_t rd_pick_best_sub8x8_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07004854 const AV1_COMP *const cpi, MACROBLOCK *x, int_mv *best_ref_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004855 int_mv *second_best_ref_mv, int64_t best_rd, int *returntotrate,
4856 int *returnyrate, int64_t *returndistortion, int *skippable, int64_t *psse,
4857 int mvthresh,
4858#if CONFIG_EXT_INTER
4859 int_mv seg_mvs[4][2][TOTAL_REFS_PER_FRAME],
4860 int_mv compound_seg_newmvs[4][2],
4861#else
4862 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME],
4863#endif // CONFIG_EXT_INTER
4864 BEST_SEG_INFO *bsi_buf, int filter_idx, int mi_row, int mi_col) {
4865 BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
4866#if CONFIG_REF_MV
4867 int_mv tmp_ref_mv[2];
4868#endif
4869 MACROBLOCKD *xd = &x->e_mbd;
4870 MODE_INFO *mi = xd->mi[0];
4871 MB_MODE_INFO *mbmi = &mi->mbmi;
4872 int mode_idx;
4873 int k, br = 0, idx, idy;
4874 int64_t bd = 0, block_sse = 0;
4875 PREDICTION_MODE this_mode;
Urvang Joshi52648442016-10-13 17:27:51 -07004876 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004877 struct macroblock_plane *const p = &x->plane[0];
4878 struct macroblockd_plane *const pd = &xd->plane[0];
4879 const int label_count = 4;
4880 int64_t this_segment_rd = 0;
4881 int label_mv_thresh;
4882 int segmentyrate = 0;
4883 const BLOCK_SIZE bsize = mbmi->sb_type;
4884 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
4885 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
4886 ENTROPY_CONTEXT t_above[2], t_left[2];
4887 int subpelmv = 1, have_ref = 0;
4888 const int has_second_rf = has_second_ref(mbmi);
4889 const int inter_mode_mask = cpi->sf.inter_mode_mask[bsize];
4890 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4891#if CONFIG_EXT_TX && CONFIG_RECT_TX
4892 mbmi->tx_size =
4893 xd->lossless[mbmi->segment_id] ? TX_4X4 : max_txsize_rect_lookup[bsize];
4894#else
4895 mbmi->tx_size = TX_4X4;
4896#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4897
Yaowu Xuf883b422016-08-30 14:01:10 -07004898 av1_zero(*bsi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004899
4900 bsi->segment_rd = best_rd;
4901 bsi->ref_mv[0] = best_ref_mv;
4902 bsi->ref_mv[1] = second_best_ref_mv;
4903 bsi->mvp.as_int = best_ref_mv->as_int;
4904 bsi->mvthresh = mvthresh;
4905
4906 for (idx = 0; idx < 4; ++idx) bsi->modes[idx] = ZEROMV;
4907
4908#if CONFIG_REFMV
4909 for (idx = 0; idx < 4; ++idx) {
4910 for (k = NEARESTMV; k <= NEWMV; ++k) {
4911 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[0].as_int = INVALID_MV;
4912 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[1].as_int = INVALID_MV;
4913
4914 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[0].as_int = INVALID_MV;
4915 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[1].as_int = INVALID_MV;
4916 }
4917 }
4918#endif
4919
4920 memcpy(t_above, pd->above_context, sizeof(t_above));
4921 memcpy(t_left, pd->left_context, sizeof(t_left));
4922
4923 // 64 makes this threshold really big effectively
4924 // making it so that we very rarely check mvs on
4925 // segments. setting this to 1 would make mv thresh
4926 // roughly equal to what it is for macroblocks
4927 label_mv_thresh = 1 * bsi->mvthresh / label_count;
4928
4929 // Segmentation method overheads
4930 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
4931 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
4932 // TODO(jingning,rbultje): rewrite the rate-distortion optimization
4933 // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
4934 int_mv mode_mv[MB_MODE_COUNT][2];
4935 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
4936 PREDICTION_MODE mode_selected = ZEROMV;
Urvang Joshi454280d2016-10-14 16:51:44 -07004937 int64_t new_best_rd = INT64_MAX;
4938 const int index = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004939 int ref;
4940#if CONFIG_REF_MV
4941 CANDIDATE_MV ref_mv_stack[2][MAX_REF_MV_STACK_SIZE];
4942 uint8_t ref_mv_count[2];
4943#endif
4944#if CONFIG_EXT_INTER
4945 int mv_idx;
4946 int_mv ref_mvs_sub8x8[2][2];
4947#endif // CONFIG_EXT_INTER
4948
4949 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
4950 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
4951#if CONFIG_EXT_INTER
4952 int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
Urvang Joshi454280d2016-10-14 16:51:44 -07004953 av1_update_mv_context(xd, mi, frame, mv_ref_list, index, mi_row, mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -07004954 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004955#endif // CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07004956#if CONFIG_GLOBAL_MOTION
4957 frame_mv[ZEROMV][frame].as_int =
4958 cm->global_motion[frame].motion_params.wmmat[0].as_int;
4959#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004960 frame_mv[ZEROMV][frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07004961#endif // CONFIG_GLOBAL_MOTION
Urvang Joshi454280d2016-10-14 16:51:44 -07004962 av1_append_sub8x8_mvs_for_idx(cm, xd, index, ref, mi_row, mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004963#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07004964 ref_mv_stack[ref], &ref_mv_count[ref],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004965#endif
4966#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07004967 mv_ref_list,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004968#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07004969 &frame_mv[NEARESTMV][frame],
4970 &frame_mv[NEARMV][frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004971
4972#if CONFIG_REF_MV
4973 tmp_ref_mv[ref] = frame_mv[NEARESTMV][mbmi->ref_frame[ref]];
4974 lower_mv_precision(&tmp_ref_mv[ref].as_mv, cm->allow_high_precision_mv);
4975 bsi->ref_mv[ref] = &tmp_ref_mv[ref];
4976 mbmi_ext->ref_mvs[frame][0] = tmp_ref_mv[ref];
4977#endif
4978
4979#if CONFIG_EXT_INTER
4980 mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
4981 mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07004982 av1_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
4983 &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004984
4985 if (has_second_rf) {
4986 frame_mv[ZERO_ZEROMV][frame].as_int = 0;
4987 frame_mv[NEAREST_NEARESTMV][frame].as_int =
4988 frame_mv[NEARESTMV][frame].as_int;
4989
4990 if (ref == 0) {
4991 frame_mv[NEAREST_NEARMV][frame].as_int =
4992 frame_mv[NEARESTMV][frame].as_int;
4993 frame_mv[NEAR_NEARESTMV][frame].as_int =
4994 frame_mv[NEARMV][frame].as_int;
4995 frame_mv[NEAREST_NEWMV][frame].as_int =
4996 frame_mv[NEARESTMV][frame].as_int;
4997 frame_mv[NEAR_NEWMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
4998 frame_mv[NEAR_NEARMV][frame].as_int =
4999 frame_mv[NEARMV][frame].as_int;
5000 } else if (ref == 1) {
5001 frame_mv[NEAREST_NEARMV][frame].as_int =
5002 frame_mv[NEARMV][frame].as_int;
5003 frame_mv[NEAR_NEARESTMV][frame].as_int =
5004 frame_mv[NEARESTMV][frame].as_int;
5005 frame_mv[NEW_NEARESTMV][frame].as_int =
5006 frame_mv[NEARESTMV][frame].as_int;
5007 frame_mv[NEW_NEARMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5008 frame_mv[NEAR_NEARMV][frame].as_int =
5009 frame_mv[NEARMV][frame].as_int;
5010 }
5011 }
5012#endif // CONFIG_EXT_INTER
5013 }
5014
5015// search for the best motion vector on this segment
5016#if CONFIG_EXT_INTER
5017 for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
5018 this_mode <= (has_second_rf ? NEW_NEWMV : NEWFROMNEARMV);
5019 ++this_mode)
5020#else
5021 for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode)
5022#endif // CONFIG_EXT_INTER
5023 {
5024 const struct buf_2d orig_src = x->plane[0].src;
5025 struct buf_2d orig_pre[2];
5026 // This flag controls if the motion estimation will kick off. When it
5027 // is set to a non-zero value, the encoder will force motion estimation.
5028 int run_mv_search = 0;
5029
5030 mode_idx = INTER_OFFSET(this_mode);
5031#if CONFIG_EXT_INTER
5032 mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
5033
5034 for (ref = 0; ref < 1 + has_second_rf; ++ref)
5035 bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[mv_idx][ref].as_int;
5036#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005037 bsi->rdstat[index][mode_idx].brdcost = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005038 if (!(inter_mode_mask & (1 << this_mode))) continue;
5039
5040#if CONFIG_REF_MV
5041 run_mv_search = 2;
5042#if !CONFIG_EXT_INTER
5043 if (filter_idx > 0 && this_mode == NEWMV) {
5044 BEST_SEG_INFO *ref_bsi = bsi_buf;
Urvang Joshi454280d2016-10-14 16:51:44 -07005045 SEG_RDSTAT *ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005046
5047 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005048 if (seg_mvs[index][mbmi->ref_frame[0]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005049 ref_rdstat->mvs[0].as_int &&
5050 ref_rdstat->mvs[0].as_int != INVALID_MV)
5051 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
5052 --run_mv_search;
5053
Urvang Joshi454280d2016-10-14 16:51:44 -07005054 if (seg_mvs[index][mbmi->ref_frame[1]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005055 ref_rdstat->mvs[1].as_int &&
5056 ref_rdstat->mvs[1].as_int != INVALID_MV)
5057 if (bsi->ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
5058 --run_mv_search;
5059 } else {
5060 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
5061 ref_rdstat->mvs[0].as_int != INVALID_MV) {
5062 run_mv_search = 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005063 seg_mvs[index][mbmi->ref_frame[0]].as_int =
5064 ref_rdstat->mvs[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005065 }
5066 }
5067
5068 if (run_mv_search != 0 && filter_idx > 1) {
5069 ref_bsi = bsi_buf + 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07005070 ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005071 run_mv_search = 2;
5072
5073 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005074 if (seg_mvs[index][mbmi->ref_frame[0]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005075 ref_rdstat->mvs[0].as_int &&
5076 ref_rdstat->mvs[0].as_int != INVALID_MV)
5077 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
5078 --run_mv_search;
5079
Urvang Joshi454280d2016-10-14 16:51:44 -07005080 if (seg_mvs[index][mbmi->ref_frame[1]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005081 ref_rdstat->mvs[1].as_int &&
5082 ref_rdstat->mvs[1].as_int != INVALID_MV)
5083 if (bsi->ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
5084 --run_mv_search;
5085 } else {
5086 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
5087 ref_rdstat->mvs[0].as_int != INVALID_MV) {
5088 run_mv_search = 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005089 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005090 ref_rdstat->mvs[0].as_int;
5091 }
5092 }
5093 }
5094 }
5095#endif // CONFIG_EXT_INTER
5096#endif // CONFIG_REF_MV
5097
Sarah Parkere5299862016-08-16 14:57:37 -07005098#if CONFIG_GLOBAL_MOTION
5099 if (get_gmtype(&cm->global_motion[mbmi->ref_frame[0]]) == GLOBAL_ZERO &&
5100 (!has_second_rf ||
5101 get_gmtype(&cm->global_motion[mbmi->ref_frame[1]]) == GLOBAL_ZERO))
5102#endif // CONFIG_GLOBAL_MOTION
5103
5104 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005105#if CONFIG_REF_MV && CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005106 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005107#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005108 frame_mv, this_mode, mbmi->ref_frame, bsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07005109 index))
Sarah Parkere5299862016-08-16 14:57:37 -07005110 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005111
5112 memcpy(orig_pre, pd->pre, sizeof(orig_pre));
Urvang Joshi454280d2016-10-14 16:51:44 -07005113 memcpy(bsi->rdstat[index][mode_idx].ta, t_above,
5114 sizeof(bsi->rdstat[index][mode_idx].ta));
5115 memcpy(bsi->rdstat[index][mode_idx].tl, t_left,
5116 sizeof(bsi->rdstat[index][mode_idx].tl));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005117
5118 // motion search for newmv (single predictor case only)
5119 if (!has_second_rf &&
5120#if CONFIG_EXT_INTER
5121 have_newmv_in_inter_mode(this_mode) &&
Alex Converse6317c882016-09-29 14:21:37 -07005122 (seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005123#else
5124 this_mode == NEWMV &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005125 (seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07005126 run_mv_search)
5127#endif // CONFIG_EXT_INTER
5128 ) {
5129 int step_param = 0;
5130 int bestsme = INT_MAX;
5131 int sadpb = x->sadperbit4;
5132 MV mvp_full;
5133 int max_mv;
5134 int cost_list[5];
5135 int tmp_col_min = x->mv_col_min;
5136 int tmp_col_max = x->mv_col_max;
5137 int tmp_row_min = x->mv_row_min;
5138 int tmp_row_max = x->mv_row_max;
5139
5140 /* Is the best so far sufficiently good that we cant justify doing
5141 * and new motion search. */
Urvang Joshi454280d2016-10-14 16:51:44 -07005142 if (new_best_rd < label_mv_thresh) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005143
5144 if (cpi->oxcf.mode != BEST) {
5145#if CONFIG_EXT_INTER
5146 bsi->mvp.as_int = bsi->ref_mv[0]->as_int;
5147#else
5148// use previous block's result as next block's MV predictor.
5149#if !CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07005150 if (index > 0) {
5151 bsi->mvp.as_int = mi->bmi[index - 1].as_mv[0].as_int;
5152 if (index == 2)
5153 bsi->mvp.as_int = mi->bmi[index - 2].as_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005154 }
5155#endif
5156#endif // CONFIG_EXT_INTER
5157 }
Urvang Joshi454280d2016-10-14 16:51:44 -07005158 max_mv = (index == 0) ? (int)x->max_mv_context[mbmi->ref_frame[0]]
5159 : AOMMAX(abs(bsi->mvp.as_mv.row),
5160 abs(bsi->mvp.as_mv.col)) >>
5161 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005162
5163 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
5164 // Take wtd average of the step_params based on the last frame's
5165 // max mv magnitude and the best ref mvs of the current block for
5166 // the given reference.
5167 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07005168 (av1_init_search_range(max_mv) + cpi->mv_step_param) / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005169 } else {
5170 step_param = cpi->mv_step_param;
5171 }
5172
5173#if CONFIG_REF_MV
5174 mvp_full.row = bsi->ref_mv[0]->as_mv.row >> 3;
5175 mvp_full.col = bsi->ref_mv[0]->as_mv.col >> 3;
5176#else
5177 mvp_full.row = bsi->mvp.as_mv.row >> 3;
5178 mvp_full.col = bsi->mvp.as_mv.col >> 3;
5179#endif
5180
5181 if (cpi->sf.adaptive_motion_search) {
5182 mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
5183 mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
Yaowu Xuf883b422016-08-30 14:01:10 -07005184 step_param = AOMMAX(step_param, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005185 }
5186
5187 // adjust src pointer for this block
Urvang Joshi454280d2016-10-14 16:51:44 -07005188 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005189
Yaowu Xuf883b422016-08-30 14:01:10 -07005190 av1_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005191
5192 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
5193
5194#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005195 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005196#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07005197 bestsme = av1_full_pixel_search(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005198 cpi, x, bsize, &mvp_full, step_param, sadpb,
5199 cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
5200 &bsi->ref_mv[0]->as_mv, INT_MAX, 1);
5201
5202 x->mv_col_min = tmp_col_min;
5203 x->mv_col_max = tmp_col_max;
5204 x->mv_row_min = tmp_row_min;
5205 x->mv_row_max = tmp_row_max;
5206
5207 if (bestsme < INT_MAX) {
5208 int distortion;
5209 if (cpi->sf.use_upsampled_references) {
5210 int best_mv_var;
5211 const int try_second =
5212 x->second_best_mv.as_int != INVALID_MV &&
5213 x->second_best_mv.as_int != x->best_mv.as_int;
5214 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
5215 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
5216 // Use up-sampled reference frames.
Yaowu Xuc27fc142016-08-22 16:08:15 -07005217 struct buf_2d backup_pred = pd->pre[0];
5218 const YV12_BUFFER_CONFIG *upsampled_ref =
5219 get_upsampled_ref(cpi, mbmi->ref_frame[0]);
5220
5221 // Set pred for Y plane
5222 setup_pred_plane(
5223 &pd->pre[0], upsampled_ref->y_buffer,
5224 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
5225 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
5226 pd->subsampling_x, pd->subsampling_y);
5227
5228 // adjust pred pointer for this block
5229 pd->pre[0].buf =
Urvang Joshi454280d2016-10-14 16:51:44 -07005230 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, index,
Yaowu Xuf883b422016-08-30 14:01:10 -07005231 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005232 << 3];
5233
5234 best_mv_var = cpi->find_fractional_mv_step(
5235 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
5236 x->errorperbit, &cpi->fn_ptr[bsize],
5237 cpi->sf.mv.subpel_force_stop,
5238 cpi->sf.mv.subpel_iters_per_step,
5239 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
5240 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, pw, ph,
5241 1);
5242
5243 if (try_second) {
5244 int this_var;
5245 MV best_mv = x->best_mv.as_mv;
5246 const MV ref_mv = bsi->ref_mv[0]->as_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07005247 const int minc = AOMMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
5248 const int maxc = AOMMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
5249 const int minr = AOMMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
5250 const int maxr = AOMMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005251
5252 x->best_mv = x->second_best_mv;
5253 if (x->best_mv.as_mv.row * 8 <= maxr &&
5254 x->best_mv.as_mv.row * 8 >= minr &&
5255 x->best_mv.as_mv.col * 8 <= maxc &&
5256 x->best_mv.as_mv.col * 8 >= minc) {
5257 this_var = cpi->find_fractional_mv_step(
5258 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
5259 x->errorperbit, &cpi->fn_ptr[bsize],
5260 cpi->sf.mv.subpel_force_stop,
5261 cpi->sf.mv.subpel_iters_per_step,
5262 cond_cost_list(cpi, cost_list), x->nmvjointcost,
5263 x->mvcost, &distortion, &x->pred_sse[mbmi->ref_frame[0]],
5264 NULL, pw, ph, 1);
5265 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
5266 x->best_mv.as_mv = best_mv;
5267 }
5268 }
5269
5270 // Restore the reference frames.
5271 pd->pre[0] = backup_pred;
5272 } else {
5273 cpi->find_fractional_mv_step(
5274 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
5275 x->errorperbit, &cpi->fn_ptr[bsize],
5276 cpi->sf.mv.subpel_force_stop,
5277 cpi->sf.mv.subpel_iters_per_step,
5278 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
5279 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, 0, 0, 0);
5280 }
5281
5282// save motion search result for use in compound prediction
5283#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005284 seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005285#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005286 seg_mvs[index][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005287#endif // CONFIG_EXT_INTER
5288 }
5289
5290 if (cpi->sf.adaptive_motion_search)
5291 x->pred_mv[mbmi->ref_frame[0]] = x->best_mv.as_mv;
5292
5293#if CONFIG_EXT_INTER
5294 mode_mv[this_mode][0] = x->best_mv;
5295#else
5296 mode_mv[NEWMV][0] = x->best_mv;
5297#endif // CONFIG_EXT_INTER
5298
5299 // restore src pointers
5300 mi_buf_restore(x, orig_src, orig_pre);
5301 }
5302
5303 if (has_second_rf) {
5304#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005305 if (seg_mvs[index][mv_idx][mbmi->ref_frame[1]].as_int == INVALID_MV ||
5306 seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005307#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005308 if (seg_mvs[index][mbmi->ref_frame[1]].as_int == INVALID_MV ||
5309 seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005310#endif // CONFIG_EXT_INTER
5311 continue;
5312 }
5313
5314#if CONFIG_DUAL_FILTER
5315 (void)run_mv_search;
5316#endif
5317
5318 if (has_second_rf &&
5319#if CONFIG_EXT_INTER
5320 this_mode == NEW_NEWMV &&
5321#else
5322 this_mode == NEWMV &&
5323#endif // CONFIG_EXT_INTER
5324#if CONFIG_DUAL_FILTER
5325 (mbmi->interp_filter[0] == EIGHTTAP_REGULAR || run_mv_search))
5326#else
5327 (mbmi->interp_filter == EIGHTTAP_REGULAR || run_mv_search))
5328#endif
5329 {
5330 // adjust src pointers
Urvang Joshi454280d2016-10-14 16:51:44 -07005331 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005332 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
5333 int rate_mv;
5334 joint_motion_search(cpi, x, bsize, frame_mv[this_mode], mi_row,
5335 mi_col,
5336#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005337 bsi->ref_mv, seg_mvs[index][mv_idx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005338#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005339 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005340#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005341 &rate_mv, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005342#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005343 compound_seg_newmvs[index][0].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005344 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07005345 compound_seg_newmvs[index][1].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005346 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
5347#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005348 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005349 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07005350 seg_mvs[index][mbmi->ref_frame[1]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005351 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
5352#endif // CONFIG_EXT_INTER
5353 }
5354 // restore src pointers
5355 mi_buf_restore(x, orig_src, orig_pre);
5356 }
5357
Urvang Joshi454280d2016-10-14 16:51:44 -07005358 bsi->rdstat[index][mode_idx].brate = set_and_cost_bmi_mvs(
5359 cpi, x, xd, index, this_mode, mode_mv[this_mode], frame_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005360#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005361 seg_mvs[index][mv_idx], compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005362#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005363 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005364#endif // CONFIG_EXT_INTER
5365 bsi->ref_mv, x->nmvjointcost, x->mvcost);
5366
5367 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005368 bsi->rdstat[index][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005369 mode_mv[this_mode][ref].as_int;
5370 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005371 bsi->rdstat[index + 1][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005372 mode_mv[this_mode][ref].as_int;
5373 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005374 bsi->rdstat[index + 2][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005375 mode_mv[this_mode][ref].as_int;
5376#if CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07005377 bsi->rdstat[index][mode_idx].pred_mv[ref].as_int =
5378 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005379 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005380 bsi->rdstat[index + 1][mode_idx].pred_mv[ref].as_int =
5381 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005382 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005383 bsi->rdstat[index + 2][mode_idx].pred_mv[ref].as_int =
5384 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005385#endif
5386#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005387 bsi->rdstat[index][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005388 bsi->ref_mv[ref]->as_int;
5389 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005390 bsi->rdstat[index + 1][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005391 bsi->ref_mv[ref]->as_int;
5392 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005393 bsi->rdstat[index + 2][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005394 bsi->ref_mv[ref]->as_int;
5395#endif // CONFIG_EXT_INTER
5396 }
5397
5398 // Trap vectors that reach beyond the UMV borders
5399 if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
5400 (has_second_rf && mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
5401 continue;
5402
5403 if (filter_idx > 0) {
5404 BEST_SEG_INFO *ref_bsi = bsi_buf;
5405 subpelmv = 0;
5406 have_ref = 1;
5407
5408 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5409 subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
5410#if CONFIG_EXT_INTER
5411 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07005412 have_ref &=
5413 ((mode_mv[this_mode][ref].as_int ==
5414 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
5415 (bsi->ref_mv[ref]->as_int ==
5416 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005417 else
5418#endif // CONFIG_EXT_INTER
5419 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07005420 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005421 }
5422
Urvang Joshi454280d2016-10-14 16:51:44 -07005423 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005424
5425 if (filter_idx > 1 && !subpelmv && !have_ref) {
5426 ref_bsi = bsi_buf + 1;
5427 have_ref = 1;
5428 for (ref = 0; ref < 1 + has_second_rf; ++ref)
5429#if CONFIG_EXT_INTER
5430 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07005431 have_ref &=
5432 ((mode_mv[this_mode][ref].as_int ==
5433 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
5434 (bsi->ref_mv[ref]->as_int ==
5435 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005436 else
5437#endif // CONFIG_EXT_INTER
5438 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07005439 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005440
Urvang Joshi454280d2016-10-14 16:51:44 -07005441 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005442 }
5443
5444 if (!subpelmv && have_ref &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005445 ref_bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005446#if CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07005447 bsi->rdstat[index][mode_idx].byrate =
5448 ref_bsi->rdstat[index][mode_idx].byrate;
5449 bsi->rdstat[index][mode_idx].bdist =
5450 ref_bsi->rdstat[index][mode_idx].bdist;
5451 bsi->rdstat[index][mode_idx].bsse =
5452 ref_bsi->rdstat[index][mode_idx].bsse;
5453 bsi->rdstat[index][mode_idx].brate +=
5454 ref_bsi->rdstat[index][mode_idx].byrate;
5455 bsi->rdstat[index][mode_idx].eobs =
5456 ref_bsi->rdstat[index][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005457
Urvang Joshi454280d2016-10-14 16:51:44 -07005458 bsi->rdstat[index][mode_idx].brdcost =
5459 RDCOST(x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate,
5460 bsi->rdstat[index][mode_idx].bdist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005461
Urvang Joshi454280d2016-10-14 16:51:44 -07005462 memcpy(bsi->rdstat[index][mode_idx].ta,
5463 ref_bsi->rdstat[index][mode_idx].ta,
5464 sizeof(bsi->rdstat[index][mode_idx].ta));
5465 memcpy(bsi->rdstat[index][mode_idx].tl,
5466 ref_bsi->rdstat[index][mode_idx].tl,
5467 sizeof(bsi->rdstat[index][mode_idx].tl));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005468#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005469 memcpy(&bsi->rdstat[index][mode_idx],
5470 &ref_bsi->rdstat[index][mode_idx], sizeof(SEG_RDSTAT));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005471#endif
5472 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005473 bsi->rdstat[index + 1][mode_idx].eobs =
5474 ref_bsi->rdstat[index + 1][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005475 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005476 bsi->rdstat[index + 2][mode_idx].eobs =
5477 ref_bsi->rdstat[index + 2][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005478
Urvang Joshi454280d2016-10-14 16:51:44 -07005479 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005480#if CONFIG_REF_MV
5481 // If the NEWMV mode is using the same motion vector as the
5482 // NEARESTMV mode, skip the rest rate-distortion calculations
5483 // and use the inferred motion vector modes.
5484 if (this_mode == NEWMV) {
5485 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005486 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005487 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005488 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005489 bsi->ref_mv[1]->as_int)
5490 continue;
5491 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07005492 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005493 bsi->ref_mv[0]->as_int)
5494 continue;
5495 }
5496 }
5497#endif
5498 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07005499 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005500 }
5501 continue;
5502 }
5503 }
5504
Urvang Joshi454280d2016-10-14 16:51:44 -07005505 bsi->rdstat[index][mode_idx].brdcost = encode_inter_mb_segment(
5506 cpi, x, bsi->segment_rd - this_segment_rd, index,
5507 &bsi->rdstat[index][mode_idx].byrate,
5508 &bsi->rdstat[index][mode_idx].bdist,
5509 &bsi->rdstat[index][mode_idx].bsse, bsi->rdstat[index][mode_idx].ta,
5510 bsi->rdstat[index][mode_idx].tl, idy, idx, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005511
Urvang Joshi454280d2016-10-14 16:51:44 -07005512 if (bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
5513 bsi->rdstat[index][mode_idx].brdcost += RDCOST(
5514 x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate, 0);
5515 bsi->rdstat[index][mode_idx].brate +=
5516 bsi->rdstat[index][mode_idx].byrate;
5517 bsi->rdstat[index][mode_idx].eobs = p->eobs[index];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005518 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005519 bsi->rdstat[index + 1][mode_idx].eobs = p->eobs[index + 1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005520 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005521 bsi->rdstat[index + 2][mode_idx].eobs = p->eobs[index + 2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005522 }
5523
Urvang Joshi454280d2016-10-14 16:51:44 -07005524 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005525#if CONFIG_REF_MV
5526 // If the NEWMV mode is using the same motion vector as the
5527 // NEARESTMV mode, skip the rest rate-distortion calculations
5528 // and use the inferred motion vector modes.
5529 if (this_mode == NEWMV) {
5530 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005531 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005532 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005533 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005534 bsi->ref_mv[1]->as_int)
5535 continue;
5536 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07005537 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005538 bsi->ref_mv[0]->as_int)
5539 continue;
5540 }
5541 }
5542#endif
5543 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07005544 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005545 }
5546 } /*for each 4x4 mode*/
5547
Urvang Joshi454280d2016-10-14 16:51:44 -07005548 if (new_best_rd == INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005549 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07005550 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005551#if CONFIG_EXT_INTER
5552 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
5553#else
5554 for (midx = 0; midx < INTER_MODES; ++midx)
5555#endif // CONFIG_EXT_INTER
5556 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
5557 bsi->segment_rd = INT64_MAX;
5558 return INT64_MAX;
5559 }
5560
5561 mode_idx = INTER_OFFSET(mode_selected);
Urvang Joshi454280d2016-10-14 16:51:44 -07005562 memcpy(t_above, bsi->rdstat[index][mode_idx].ta, sizeof(t_above));
5563 memcpy(t_left, bsi->rdstat[index][mode_idx].tl, sizeof(t_left));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005564
5565#if CONFIG_EXT_INTER
5566 mv_idx = (mode_selected == NEWFROMNEARMV) ? 1 : 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005567 bsi->ref_mv[0]->as_int = bsi->rdstat[index][mode_idx].ref_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005568 if (has_second_rf)
Urvang Joshi454280d2016-10-14 16:51:44 -07005569 bsi->ref_mv[1]->as_int = bsi->rdstat[index][mode_idx].ref_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005570#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005571 set_and_cost_bmi_mvs(cpi, x, xd, index, mode_selected,
5572 mode_mv[mode_selected], frame_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005573#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005574 seg_mvs[index][mv_idx], compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005575#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005576 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005577#endif // CONFIG_EXT_INTER
5578 bsi->ref_mv, x->nmvjointcost, x->mvcost);
5579
Urvang Joshi454280d2016-10-14 16:51:44 -07005580 br += bsi->rdstat[index][mode_idx].brate;
5581 bd += bsi->rdstat[index][mode_idx].bdist;
5582 block_sse += bsi->rdstat[index][mode_idx].bsse;
5583 segmentyrate += bsi->rdstat[index][mode_idx].byrate;
5584 this_segment_rd += bsi->rdstat[index][mode_idx].brdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005585
5586 if (this_segment_rd > bsi->segment_rd) {
5587 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07005588 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005589#if CONFIG_EXT_INTER
5590 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
5591#else
5592 for (midx = 0; midx < INTER_MODES; ++midx)
5593#endif // CONFIG_EXT_INTER
5594 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
5595 bsi->segment_rd = INT64_MAX;
5596 return INT64_MAX;
5597 }
5598 }
5599 } /* for each label */
5600
5601 bsi->r = br;
5602 bsi->d = bd;
5603 bsi->segment_yrate = segmentyrate;
5604 bsi->segment_rd = this_segment_rd;
5605 bsi->sse = block_sse;
5606
5607 // update the coding decisions
5608 for (k = 0; k < 4; ++k) bsi->modes[k] = mi->bmi[k].as_mode;
5609
5610 if (bsi->segment_rd > best_rd) return INT64_MAX;
5611 /* set it to the best */
5612 for (idx = 0; idx < 4; idx++) {
5613 mode_idx = INTER_OFFSET(bsi->modes[idx]);
5614 mi->bmi[idx].as_mv[0].as_int = bsi->rdstat[idx][mode_idx].mvs[0].as_int;
5615 if (has_second_ref(mbmi))
5616 mi->bmi[idx].as_mv[1].as_int = bsi->rdstat[idx][mode_idx].mvs[1].as_int;
5617#if CONFIG_REF_MV
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07005618 mi->bmi[idx].pred_mv[0] = bsi->rdstat[idx][mode_idx].pred_mv[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005619 if (has_second_ref(mbmi))
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07005620 mi->bmi[idx].pred_mv[1] = bsi->rdstat[idx][mode_idx].pred_mv[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005621#endif
5622#if CONFIG_EXT_INTER
5623 mi->bmi[idx].ref_mv[0].as_int = bsi->rdstat[idx][mode_idx].ref_mv[0].as_int;
5624 if (has_second_rf)
5625 mi->bmi[idx].ref_mv[1].as_int =
5626 bsi->rdstat[idx][mode_idx].ref_mv[1].as_int;
5627#endif // CONFIG_EXT_INTER
5628 x->plane[0].eobs[idx] = bsi->rdstat[idx][mode_idx].eobs;
5629 mi->bmi[idx].as_mode = bsi->modes[idx];
5630 }
5631
5632 /*
5633 * used to set mbmi->mv.as_int
5634 */
5635 *returntotrate = bsi->r;
5636 *returndistortion = bsi->d;
5637 *returnyrate = bsi->segment_yrate;
Yaowu Xuf883b422016-08-30 14:01:10 -07005638 *skippable = av1_is_skippable_in_plane(x, BLOCK_8X8, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005639 *psse = bsi->sse;
5640 mbmi->mode = bsi->modes[3];
5641
5642 return bsi->segment_rd;
5643}
5644
Yaowu Xuf883b422016-08-30 14:01:10 -07005645static void estimate_ref_frame_costs(const AV1_COMMON *cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005646 const MACROBLOCKD *xd, int segment_id,
5647 unsigned int *ref_costs_single,
5648 unsigned int *ref_costs_comp,
Yaowu Xuf883b422016-08-30 14:01:10 -07005649 aom_prob *comp_mode_p) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005650 int seg_ref_active =
5651 segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
5652 if (seg_ref_active) {
5653 memset(ref_costs_single, 0,
5654 TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_single));
5655 memset(ref_costs_comp, 0, TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_comp));
5656 *comp_mode_p = 128;
5657 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005658 aom_prob intra_inter_p = av1_get_intra_inter_prob(cm, xd);
5659 aom_prob comp_inter_p = 128;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005660
5661 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005662 comp_inter_p = av1_get_reference_mode_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005663 *comp_mode_p = comp_inter_p;
5664 } else {
5665 *comp_mode_p = 128;
5666 }
5667
Yaowu Xuf883b422016-08-30 14:01:10 -07005668 ref_costs_single[INTRA_FRAME] = av1_cost_bit(intra_inter_p, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005669
5670 if (cm->reference_mode != COMPOUND_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005671 aom_prob ref_single_p1 = av1_get_pred_prob_single_ref_p1(cm, xd);
5672 aom_prob ref_single_p2 = av1_get_pred_prob_single_ref_p2(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005673#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005674 aom_prob ref_single_p3 = av1_get_pred_prob_single_ref_p3(cm, xd);
5675 aom_prob ref_single_p4 = av1_get_pred_prob_single_ref_p4(cm, xd);
5676 aom_prob ref_single_p5 = av1_get_pred_prob_single_ref_p5(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005677#endif // CONFIG_EXT_REFS
5678
Yaowu Xuf883b422016-08-30 14:01:10 -07005679 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005680
5681 ref_costs_single[LAST_FRAME] =
5682#if CONFIG_EXT_REFS
5683 ref_costs_single[LAST2_FRAME] = ref_costs_single[LAST3_FRAME] =
5684 ref_costs_single[BWDREF_FRAME] =
5685#endif // CONFIG_EXT_REFS
5686 ref_costs_single[GOLDEN_FRAME] =
5687 ref_costs_single[ALTREF_FRAME] = base_cost;
5688
5689#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005690 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
5691 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p1, 0);
5692 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p1, 0);
5693 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 0);
5694 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
5695 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005696
Yaowu Xuf883b422016-08-30 14:01:10 -07005697 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p3, 0);
5698 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p3, 0);
5699 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p3, 1);
5700 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p3, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005701
Yaowu Xuf883b422016-08-30 14:01:10 -07005702 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p2, 0);
5703 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005704
Yaowu Xuf883b422016-08-30 14:01:10 -07005705 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p4, 0);
5706 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p4, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005707
Yaowu Xuf883b422016-08-30 14:01:10 -07005708 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p5, 0);
5709 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p5, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005710#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005711 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
5712 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 1);
5713 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005714
Yaowu Xuf883b422016-08-30 14:01:10 -07005715 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p2, 0);
5716 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005717#endif // CONFIG_EXT_REFS
5718 } else {
5719 ref_costs_single[LAST_FRAME] = 512;
5720#if CONFIG_EXT_REFS
5721 ref_costs_single[LAST2_FRAME] = 512;
5722 ref_costs_single[LAST3_FRAME] = 512;
5723 ref_costs_single[BWDREF_FRAME] = 512;
5724#endif // CONFIG_EXT_REFS
5725 ref_costs_single[GOLDEN_FRAME] = 512;
5726 ref_costs_single[ALTREF_FRAME] = 512;
5727 }
5728
5729 if (cm->reference_mode != SINGLE_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005730 aom_prob ref_comp_p = av1_get_pred_prob_comp_ref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005731#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005732 aom_prob ref_comp_p1 = av1_get_pred_prob_comp_ref_p1(cm, xd);
5733 aom_prob ref_comp_p2 = av1_get_pred_prob_comp_ref_p2(cm, xd);
5734 aom_prob bwdref_comp_p = av1_get_pred_prob_comp_bwdref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005735#endif // CONFIG_EXT_REFS
5736
Yaowu Xuf883b422016-08-30 14:01:10 -07005737 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005738
5739 ref_costs_comp[LAST_FRAME] =
5740#if CONFIG_EXT_REFS
5741 ref_costs_comp[LAST2_FRAME] = ref_costs_comp[LAST3_FRAME] =
5742#endif // CONFIG_EXT_REFS
5743 ref_costs_comp[GOLDEN_FRAME] = base_cost;
5744
5745#if CONFIG_EXT_REFS
5746 ref_costs_comp[BWDREF_FRAME] = ref_costs_comp[ALTREF_FRAME] = 0;
5747#endif // CONFIG_EXT_REFS
5748
5749#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005750 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
5751 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p, 0);
5752 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p, 1);
5753 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005754
Yaowu Xuf883b422016-08-30 14:01:10 -07005755 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p1, 1);
5756 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005757
Yaowu Xuf883b422016-08-30 14:01:10 -07005758 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p2, 0);
5759 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005760
5761 // NOTE(zoeliu): BWDREF and ALTREF each add an extra cost by coding 1
5762 // more bit.
Yaowu Xuf883b422016-08-30 14:01:10 -07005763 ref_costs_comp[BWDREF_FRAME] += av1_cost_bit(bwdref_comp_p, 0);
5764 ref_costs_comp[ALTREF_FRAME] += av1_cost_bit(bwdref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005765#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005766 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
5767 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005768#endif // CONFIG_EXT_REFS
5769 } else {
5770 ref_costs_comp[LAST_FRAME] = 512;
5771#if CONFIG_EXT_REFS
5772 ref_costs_comp[LAST2_FRAME] = 512;
5773 ref_costs_comp[LAST3_FRAME] = 512;
5774 ref_costs_comp[BWDREF_FRAME] = 512;
5775 ref_costs_comp[ALTREF_FRAME] = 512;
5776#endif // CONFIG_EXT_REFS
5777 ref_costs_comp[GOLDEN_FRAME] = 512;
5778 }
5779 }
5780}
5781
5782static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
5783 int mode_index,
5784 int64_t comp_pred_diff[REFERENCE_MODES],
5785 int skippable) {
5786 MACROBLOCKD *const xd = &x->e_mbd;
5787
5788 // Take a snapshot of the coding context so it can be
5789 // restored if we decide to encode this way
5790 ctx->skip = x->skip;
5791 ctx->skippable = skippable;
5792 ctx->best_mode_index = mode_index;
5793 ctx->mic = *xd->mi[0];
5794 ctx->mbmi_ext = *x->mbmi_ext;
5795 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
5796 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
5797 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
5798}
5799
Urvang Joshi52648442016-10-13 17:27:51 -07005800static void setup_buffer_inter(const AV1_COMP *const cpi, MACROBLOCK *x,
clang-format67948d32016-09-07 22:40:40 -07005801 MV_REFERENCE_FRAME ref_frame,
5802 BLOCK_SIZE block_size, int mi_row, int mi_col,
5803 int_mv frame_nearest_mv[TOTAL_REFS_PER_FRAME],
5804 int_mv frame_near_mv[TOTAL_REFS_PER_FRAME],
5805 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME]
5806 [MAX_MB_PLANE]) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005807 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005808 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
5809 MACROBLOCKD *const xd = &x->e_mbd;
5810 MODE_INFO *const mi = xd->mi[0];
5811 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
5812 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
5813 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
5814
5815 assert(yv12 != NULL);
5816
5817 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
5818 // use the UV scaling factors.
Yaowu Xuf883b422016-08-30 14:01:10 -07005819 av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005820
5821 // Gets an initial list of candidate vectors from neighbours and orders them
Yaowu Xuf883b422016-08-30 14:01:10 -07005822 av1_find_mv_refs(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005823 cm, xd, mi, ref_frame,
5824#if CONFIG_REF_MV
5825 &mbmi_ext->ref_mv_count[ref_frame], mbmi_ext->ref_mv_stack[ref_frame],
5826#if CONFIG_EXT_INTER
5827 mbmi_ext->compound_mode_context,
5828#endif // CONFIG_EXT_INTER
5829#endif
5830 candidates, mi_row, mi_col, NULL, NULL, mbmi_ext->mode_context);
5831
5832 // Candidate refinement carried out at encoder and decoder
Yaowu Xuf883b422016-08-30 14:01:10 -07005833 av1_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
5834 &frame_nearest_mv[ref_frame],
5835 &frame_near_mv[ref_frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005836
5837 // Further refinement that is encode side only to test the top few candidates
5838 // in full and choose the best as the centre point for subsequent searches.
5839 // The current implementation doesn't support scaling.
Yaowu Xuf883b422016-08-30 14:01:10 -07005840 if (!av1_is_scaled(sf) && block_size >= BLOCK_8X8)
5841 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
5842 block_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005843}
5844
Urvang Joshi52648442016-10-13 17:27:51 -07005845static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
5846 BLOCK_SIZE bsize, int mi_row, int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005847#if CONFIG_EXT_INTER
5848 int ref_idx, int mv_idx,
5849#endif // CONFIG_EXT_INTER
5850 int *rate_mv) {
5851 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07005852 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005853 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5854 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
5855 int bestsme = INT_MAX;
5856 int step_param;
5857 int sadpb = x->sadperbit16;
5858 MV mvp_full;
5859#if CONFIG_EXT_INTER
5860 int ref = mbmi->ref_frame[ref_idx];
5861 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
5862#else
5863 int ref = mbmi->ref_frame[0];
5864 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
5865 int ref_idx = 0;
5866#endif // CONFIG_EXT_INTER
5867
5868 int tmp_col_min = x->mv_col_min;
5869 int tmp_col_max = x->mv_col_max;
5870 int tmp_row_min = x->mv_row_min;
5871 int tmp_row_max = x->mv_row_max;
5872 int cost_list[5];
5873
5874 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07005875 av1_get_scaled_ref_frame(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005876
5877 MV pred_mv[3];
5878 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
5879 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
5880 pred_mv[2] = x->pred_mv[ref];
5881
Yaowu Xuc27fc142016-08-22 16:08:15 -07005882 if (scaled_ref_frame) {
5883 int i;
5884 // Swap out the reference frame for a version that's been scaled to
5885 // match the resolution of the current frame, allowing the existing
5886 // motion search code to be used without additional modifications.
5887 for (i = 0; i < MAX_MB_PLANE; i++)
5888 backup_yv12[i] = xd->plane[i].pre[ref_idx];
5889
Yaowu Xuf883b422016-08-30 14:01:10 -07005890 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005891 }
5892
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005893 av1_set_mv_search_range(x, &ref_mv);
5894
5895#if CONFIG_REF_MV
5896 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
5897#endif
5898
Yaowu Xuc27fc142016-08-22 16:08:15 -07005899 // Work out the size of the first step in the mv step search.
Yaowu Xuf883b422016-08-30 14:01:10 -07005900 // 0 here is maximum length first step. 1 is AOMMAX >> 1 etc.
Yaowu Xuc27fc142016-08-22 16:08:15 -07005901 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
5902 // Take wtd average of the step_params based on the last frame's
5903 // max mv magnitude and that based on the best ref mvs of the current
5904 // block for the given reference.
5905 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07005906 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07005907 2;
5908 } else {
5909 step_param = cpi->mv_step_param;
5910 }
5911
5912 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size) {
5913 int boffset =
5914 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07005915 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
5916 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005917 }
5918
5919 if (cpi->sf.adaptive_motion_search) {
5920 int bwl = b_width_log2_lookup[bsize];
5921 int bhl = b_height_log2_lookup[bsize];
5922 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
5923
5924 if (tlevel < 5) step_param += 2;
5925
5926 // prev_mv_sad is not setup for dynamically scaled frames.
5927 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
5928 int i;
5929 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
5930 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
5931 x->pred_mv[ref].row = 0;
5932 x->pred_mv[ref].col = 0;
5933 x->best_mv.as_int = INVALID_MV;
5934
5935 if (scaled_ref_frame) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005936 int j;
5937 for (j = 0; j < MAX_MB_PLANE; ++j)
5938 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005939 }
5940 return;
5941 }
5942 }
5943 }
5944 }
5945
Yaowu Xuf883b422016-08-30 14:01:10 -07005946 av1_set_mv_search_range(x, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005947
Yue Chene9638cc2016-10-10 12:37:54 -07005948#if CONFIG_MOTION_VAR
5949 if (mbmi->motion_mode != SIMPLE_TRANSLATION)
5950 mvp_full = mbmi->mv[0].as_mv;
5951 else
5952#endif // CONFIG_MOTION_VAR
5953 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005954
5955 mvp_full.col >>= 3;
5956 mvp_full.row >>= 3;
5957
5958 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
5959
Yue Chene9638cc2016-10-10 12:37:54 -07005960#if CONFIG_MOTION_VAR
5961 switch (mbmi->motion_mode) {
5962 case SIMPLE_TRANSLATION:
5963#endif // CONFIG_MOTION_VAR
5964 bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
5965 sadpb, cond_cost_list(cpi, cost_list),
5966 &ref_mv, INT_MAX, 1);
5967#if CONFIG_MOTION_VAR
5968 break;
5969 case OBMC_CAUSAL:
5970 bestsme = av1_obmc_full_pixel_diamond(
5971 cpi, x, &mvp_full, step_param, sadpb,
5972 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
5973 &(x->best_mv.as_mv), 0);
5974 break;
5975 default: assert("Invalid motion mode!\n");
5976 }
5977#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07005978
5979 x->mv_col_min = tmp_col_min;
5980 x->mv_col_max = tmp_col_max;
5981 x->mv_row_min = tmp_row_min;
5982 x->mv_row_max = tmp_row_max;
5983
5984 if (bestsme < INT_MAX) {
5985 int dis; /* TODO: use dis in distortion calculation later. */
Yue Chene9638cc2016-10-10 12:37:54 -07005986#if CONFIG_MOTION_VAR
5987 switch (mbmi->motion_mode) {
5988 case SIMPLE_TRANSLATION:
5989#endif // CONFIG_MOTION_VAR
5990 if (cpi->sf.use_upsampled_references) {
5991 int best_mv_var;
5992 const int try_second = x->second_best_mv.as_int != INVALID_MV &&
5993 x->second_best_mv.as_int != x->best_mv.as_int;
5994 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
5995 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
5996 // Use up-sampled reference frames.
5997 struct macroblockd_plane *const pd = &xd->plane[0];
5998 struct buf_2d backup_pred = pd->pre[ref_idx];
5999 const YV12_BUFFER_CONFIG *upsampled_ref = get_upsampled_ref(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006000
Yue Chene9638cc2016-10-10 12:37:54 -07006001 // Set pred for Y plane
6002 setup_pred_plane(
6003 &pd->pre[ref_idx], upsampled_ref->y_buffer,
6004 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
6005 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
6006 pd->subsampling_x, pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006007
Yue Chene9638cc2016-10-10 12:37:54 -07006008 best_mv_var = cpi->find_fractional_mv_step(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006009 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6010 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6011 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
6012 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, pw, ph,
6013 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006014
Yue Chene9638cc2016-10-10 12:37:54 -07006015 if (try_second) {
6016 const int minc = AOMMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
6017 const int maxc = AOMMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
6018 const int minr = AOMMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
6019 const int maxr = AOMMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
6020 int this_var;
6021 MV best_mv = x->best_mv.as_mv;
6022
6023 x->best_mv = x->second_best_mv;
6024 if (x->best_mv.as_mv.row * 8 <= maxr &&
6025 x->best_mv.as_mv.row * 8 >= minr &&
6026 x->best_mv.as_mv.col * 8 <= maxc &&
6027 x->best_mv.as_mv.col * 8 >= minc) {
6028 this_var = cpi->find_fractional_mv_step(
6029 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6030 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6031 cpi->sf.mv.subpel_iters_per_step,
6032 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
6033 &dis, &x->pred_sse[ref], NULL, pw, ph, 1);
6034 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
6035 x->best_mv.as_mv = best_mv;
6036 }
6037 }
6038
6039 // Restore the reference frames.
6040 pd->pre[ref_idx] = backup_pred;
6041 } else {
6042 cpi->find_fractional_mv_step(
6043 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6044 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6045 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
6046 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, 0, 0,
6047 0);
6048 }
6049#if CONFIG_MOTION_VAR
6050 break;
6051 case OBMC_CAUSAL:
6052 av1_find_best_obmc_sub_pixel_tree_up(
6053 cpi, x, mi_row, mi_col, &x->best_mv.as_mv, &ref_mv,
6054 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
6055 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
6056 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], 0,
6057 cpi->sf.use_upsampled_references);
6058 break;
6059 default: assert("Invalid motion mode!\n");
Yaowu Xuc27fc142016-08-22 16:08:15 -07006060 }
Yue Chene9638cc2016-10-10 12:37:54 -07006061#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006062 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006063 *rate_mv = av1_mv_bit_cost(&x->best_mv.as_mv, &ref_mv, x->nmvjointcost,
6064 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006065
Yue Chene9638cc2016-10-10 12:37:54 -07006066#if CONFIG_MOTION_VAR
6067 if (cpi->sf.adaptive_motion_search && mbmi->motion_mode == SIMPLE_TRANSLATION)
6068#else
6069 if (cpi->sf.adaptive_motion_search)
6070#endif // CONFIG_MOTION_VAR
6071 x->pred_mv[ref] = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006072
6073 if (scaled_ref_frame) {
6074 int i;
6075 for (i = 0; i < MAX_MB_PLANE; i++)
6076 xd->plane[i].pre[ref_idx] = backup_yv12[i];
6077 }
6078}
6079
6080static INLINE void restore_dst_buf(MACROBLOCKD *xd,
6081 uint8_t *orig_dst[MAX_MB_PLANE],
6082 int orig_dst_stride[MAX_MB_PLANE]) {
6083 int i;
6084 for (i = 0; i < MAX_MB_PLANE; i++) {
6085 xd->plane[i].dst.buf = orig_dst[i];
6086 xd->plane[i].dst.stride = orig_dst_stride[i];
6087 }
6088}
6089
Yaowu Xuc27fc142016-08-22 16:08:15 -07006090#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07006091static void do_masked_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006092 const uint8_t *mask, int mask_stride,
6093 BLOCK_SIZE bsize, int mi_row, int mi_col,
6094 int_mv *tmp_mv, int *rate_mv, int ref_idx,
6095 int mv_idx) {
6096 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07006097 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006098 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6099 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
6100 int bestsme = INT_MAX;
6101 int step_param;
6102 int sadpb = x->sadperbit16;
6103 MV mvp_full;
6104 int ref = mbmi->ref_frame[ref_idx];
6105 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
6106
6107 int tmp_col_min = x->mv_col_min;
6108 int tmp_col_max = x->mv_col_max;
6109 int tmp_row_min = x->mv_row_min;
6110 int tmp_row_max = x->mv_row_max;
6111
6112 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07006113 av1_get_scaled_ref_frame(cpi, ref);
Urvang Joshi368fbc92016-10-17 16:31:34 -07006114 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006115
6116 MV pred_mv[3];
6117 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6118 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
6119 pred_mv[2] = x->pred_mv[ref];
6120
6121#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006122 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006123#endif
6124
6125 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006126 // Swap out the reference frame for a version that's been scaled to
6127 // match the resolution of the current frame, allowing the existing
6128 // motion search code to be used without additional modifications.
6129 for (i = 0; i < MAX_MB_PLANE; i++)
6130 backup_yv12[i] = xd->plane[i].pre[ref_idx];
6131
Yaowu Xuf883b422016-08-30 14:01:10 -07006132 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006133 }
6134
Yaowu Xuf883b422016-08-30 14:01:10 -07006135 av1_set_mv_search_range(x, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006136
6137 // Work out the size of the first step in the mv step search.
6138 // 0 here is maximum length first step. 1 is MAX >> 1 etc.
6139 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6140 // Take wtd average of the step_params based on the last frame's
6141 // max mv magnitude and that based on the best ref mvs of the current
6142 // block for the given reference.
6143 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006144 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07006145 2;
6146 } else {
6147 step_param = cpi->mv_step_param;
6148 }
6149
6150 // TODO(debargha): is show_frame needed here?
6151 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size && cm->show_frame) {
6152 int boffset =
6153 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07006154 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
6155 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006156 }
6157
6158 if (cpi->sf.adaptive_motion_search) {
6159 int bwl = b_width_log2_lookup[bsize];
6160 int bhl = b_height_log2_lookup[bsize];
6161 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
6162
6163 if (tlevel < 5) step_param += 2;
6164
6165 // prev_mv_sad is not setup for dynamically scaled frames.
6166 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006167 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
6168 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
6169 x->pred_mv[ref].row = 0;
6170 x->pred_mv[ref].col = 0;
6171 tmp_mv->as_int = INVALID_MV;
6172
6173 if (scaled_ref_frame) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07006174 int j;
6175 for (j = 0; j < MAX_MB_PLANE; ++j)
6176 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006177 }
6178 return;
6179 }
6180 }
6181 }
6182 }
6183
6184 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
6185
6186 mvp_full.col >>= 3;
6187 mvp_full.row >>= 3;
6188
Yaowu Xuf883b422016-08-30 14:01:10 -07006189 bestsme = av1_masked_full_pixel_diamond(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006190 cpi, x, mask, mask_stride, &mvp_full, step_param, sadpb,
6191 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
6192 &tmp_mv->as_mv, ref_idx);
6193
6194 x->mv_col_min = tmp_col_min;
6195 x->mv_col_max = tmp_col_max;
6196 x->mv_row_min = tmp_row_min;
6197 x->mv_row_max = tmp_row_max;
6198
6199 if (bestsme < INT_MAX) {
6200 int dis; /* TODO: use dis in distortion calculation later. */
Yaowu Xuf883b422016-08-30 14:01:10 -07006201 av1_find_best_masked_sub_pixel_tree_up(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006202 cpi, x, mask, mask_stride, mi_row, mi_col, &tmp_mv->as_mv, &ref_mv,
6203 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
6204 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
6205 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], ref_idx,
6206 cpi->sf.use_upsampled_references);
6207 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006208 *rate_mv = av1_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmvjointcost,
6209 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006210
6211 if (cpi->sf.adaptive_motion_search && cm->show_frame)
6212 x->pred_mv[ref] = tmp_mv->as_mv;
6213
6214 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006215 for (i = 0; i < MAX_MB_PLANE; i++)
6216 xd->plane[i].pre[ref_idx] = backup_yv12[i];
6217 }
6218}
6219
Urvang Joshi52648442016-10-13 17:27:51 -07006220static void do_masked_motion_search_indexed(const AV1_COMP *const cpi,
6221 MACROBLOCK *x, int wedge_index,
6222 int wedge_sign, BLOCK_SIZE bsize,
6223 int mi_row, int mi_col,
6224 int_mv *tmp_mv, int *rate_mv,
6225 int mv_idx[2], int which) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006226 // NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both
6227 MACROBLOCKD *xd = &x->e_mbd;
6228 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6229 BLOCK_SIZE sb_type = mbmi->sb_type;
6230 const uint8_t *mask;
6231 const int mask_stride = 4 * num_4x4_blocks_wide_lookup[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07006232 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006233
6234 if (which == 0 || which == 2)
6235 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
6236 &tmp_mv[0], &rate_mv[0], 0, mv_idx[0]);
6237
6238 if (which == 1 || which == 2) {
6239 // get the negative mask
Yaowu Xuf883b422016-08-30 14:01:10 -07006240 mask = av1_get_contiguous_soft_mask(wedge_index, !wedge_sign, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006241 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
6242 &tmp_mv[1], &rate_mv[1], 1, mv_idx[1]);
6243 }
6244}
6245#endif // CONFIG_EXT_INTER
6246
6247// In some situations we want to discount tha pparent cost of a new motion
6248// vector. Where there is a subtle motion field and especially where there is
6249// low spatial complexity then it can be hard to cover the cost of a new motion
6250// vector in a single block, even if that motion vector reduces distortion.
6251// However, once established that vector may be usable through the nearest and
6252// near mv modes to reduce distortion in subsequent blocks and also improve
6253// visual quality.
Urvang Joshi52648442016-10-13 17:27:51 -07006254static int discount_newmv_test(const AV1_COMP *const cpi, int this_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006255 int_mv this_mv,
6256 int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME],
6257 int ref_frame) {
6258 return (!cpi->rc.is_src_frame_alt_ref && (this_mode == NEWMV) &&
6259 (this_mv.as_int != 0) &&
6260 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
6261 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
6262 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
6263 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
6264}
6265
Yaowu Xu671f2bd2016-09-30 15:07:57 -07006266#define LEFT_TOP_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
6267#define RIGHT_BOTTOM_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006268
6269// TODO(jingning): this mv clamping function should be block size dependent.
6270static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
6271 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
6272 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
6273 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
6274 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
6275}
6276
6277#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006278static int estimate_wedge_sign(const AV1_COMP *cpi, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006279 const BLOCK_SIZE bsize, const uint8_t *pred0,
6280 int stride0, const uint8_t *pred1, int stride1) {
6281 const struct macroblock_plane *const p = &x->plane[0];
6282 const uint8_t *src = p->src.buf;
6283 int src_stride = p->src.stride;
6284 const int f_index = bsize - BLOCK_8X8;
6285 const int bw = 4 << (b_width_log2_lookup[bsize]);
6286 const int bh = 4 << (b_height_log2_lookup[bsize]);
6287 uint32_t esq[2][4], var;
6288 int64_t tl, br;
6289
Yaowu Xuf883b422016-08-30 14:01:10 -07006290#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006291 if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6292 pred0 = CONVERT_TO_BYTEPTR(pred0);
6293 pred1 = CONVERT_TO_BYTEPTR(pred1);
6294 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006295#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006296
6297 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred0, stride0, &esq[0][0]);
6298 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred0 + bw / 2,
6299 stride0, &esq[0][1]);
6300 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
6301 pred0 + bh / 2 * stride0, stride0, &esq[0][2]);
6302 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
6303 pred0 + bh / 2 * stride0 + bw / 2, stride0,
6304 &esq[0][3]);
6305 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred1, stride1, &esq[1][0]);
6306 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred1 + bw / 2,
6307 stride1, &esq[1][1]);
6308 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
6309 pred1 + bh / 2 * stride1, stride0, &esq[1][2]);
6310 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
6311 pred1 + bh / 2 * stride1 + bw / 2, stride0,
6312 &esq[1][3]);
6313 (void)var;
6314
6315 tl = (int64_t)(esq[0][0] + esq[0][1] + esq[0][2]) -
6316 (int64_t)(esq[1][0] + esq[1][1] + esq[1][2]);
6317 br = (int64_t)(esq[1][3] + esq[1][1] + esq[1][2]) -
6318 (int64_t)(esq[0][3] + esq[0][1] + esq[0][2]);
6319 return (tl + br > 0);
6320}
6321#endif // CONFIG_EXT_INTER
6322
6323#if !CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07006324static InterpFilter predict_interp_filter(
Yaowu Xuf883b422016-08-30 14:01:10 -07006325 const AV1_COMP *cpi, const MACROBLOCK *x, const BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006326 const int mi_row, const int mi_col,
James Zern7b9407a2016-05-18 23:48:05 -07006327 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME]) {
6328 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuf883b422016-08-30 14:01:10 -07006329 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006330 const MACROBLOCKD *xd = &x->e_mbd;
6331 int bsl = mi_width_log2_lookup[bsize];
6332 int pred_filter_search =
6333 cpi->sf.cb_pred_filter_search
6334 ? (((mi_row + mi_col) >> bsl) +
6335 get_chessboard_index(cm->current_video_frame)) &
6336 0x1
6337 : 0;
6338 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6339 const int is_comp_pred = has_second_ref(mbmi);
6340 const int this_mode = mbmi->mode;
6341 int refs[2] = { mbmi->ref_frame[0],
6342 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Yaowu Xuc27fc142016-08-22 16:08:15 -07006343 if (pred_filter_search) {
James Zern7b9407a2016-05-18 23:48:05 -07006344 InterpFilter af = SWITCHABLE, lf = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006345 if (xd->up_available) af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
6346 if (xd->left_available) lf = xd->mi[-1]->mbmi.interp_filter;
6347
6348#if CONFIG_EXT_INTER
6349 if ((this_mode != NEWMV && this_mode != NEWFROMNEARMV &&
6350 this_mode != NEW_NEWMV) ||
6351 (af == lf))
6352#else
6353 if ((this_mode != NEWMV) || (af == lf))
6354#endif // CONFIG_EXT_INTER
6355 best_filter = af;
6356 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006357 if (is_comp_pred) {
6358 if (cpi->sf.adaptive_mode_search) {
6359#if CONFIG_EXT_INTER
6360 switch (this_mode) {
6361 case NEAREST_NEARESTMV:
6362 if (single_filter[NEARESTMV][refs[0]] ==
6363 single_filter[NEARESTMV][refs[1]])
6364 best_filter = single_filter[NEARESTMV][refs[0]];
6365 break;
6366 case NEAREST_NEARMV:
6367 if (single_filter[NEARESTMV][refs[0]] ==
6368 single_filter[NEARMV][refs[1]])
6369 best_filter = single_filter[NEARESTMV][refs[0]];
6370 break;
6371 case NEAR_NEARESTMV:
6372 if (single_filter[NEARMV][refs[0]] ==
6373 single_filter[NEARESTMV][refs[1]])
6374 best_filter = single_filter[NEARMV][refs[0]];
6375 break;
6376 case NEAR_NEARMV:
6377 if (single_filter[NEARMV][refs[0]] == single_filter[NEARMV][refs[1]])
6378 best_filter = single_filter[NEARMV][refs[0]];
6379 break;
6380 case ZERO_ZEROMV:
6381 if (single_filter[ZEROMV][refs[0]] == single_filter[ZEROMV][refs[1]])
6382 best_filter = single_filter[ZEROMV][refs[0]];
6383 break;
6384 case NEW_NEWMV:
6385 if (single_filter[NEWMV][refs[0]] == single_filter[NEWMV][refs[1]])
6386 best_filter = single_filter[NEWMV][refs[0]];
6387 break;
6388 case NEAREST_NEWMV:
6389 if (single_filter[NEARESTMV][refs[0]] ==
6390 single_filter[NEWMV][refs[1]])
6391 best_filter = single_filter[NEARESTMV][refs[0]];
6392 break;
6393 case NEAR_NEWMV:
6394 if (single_filter[NEARMV][refs[0]] == single_filter[NEWMV][refs[1]])
6395 best_filter = single_filter[NEARMV][refs[0]];
6396 break;
6397 case NEW_NEARESTMV:
6398 if (single_filter[NEWMV][refs[0]] ==
6399 single_filter[NEARESTMV][refs[1]])
6400 best_filter = single_filter[NEWMV][refs[0]];
6401 break;
6402 case NEW_NEARMV:
6403 if (single_filter[NEWMV][refs[0]] == single_filter[NEARMV][refs[1]])
6404 best_filter = single_filter[NEWMV][refs[0]];
6405 break;
6406 default:
6407 if (single_filter[this_mode][refs[0]] ==
6408 single_filter[this_mode][refs[1]])
6409 best_filter = single_filter[this_mode][refs[0]];
6410 break;
6411 }
6412#else
6413 if (single_filter[this_mode][refs[0]] ==
6414 single_filter[this_mode][refs[1]])
6415 best_filter = single_filter[this_mode][refs[0]];
6416#endif // CONFIG_EXT_INTER
6417 }
6418 }
Angie Chiang75c22092016-10-25 12:19:16 -07006419 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
6420 best_filter = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006421 }
6422 return best_filter;
6423}
6424#endif
6425
6426#if CONFIG_EXT_INTER
6427// Choose the best wedge index and sign
Yaowu Xuf883b422016-08-30 14:01:10 -07006428static int64_t pick_wedge(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006429 const BLOCK_SIZE bsize, const uint8_t *const p0,
6430 const uint8_t *const p1, int *const best_wedge_sign,
6431 int *const best_wedge_index) {
6432 const MACROBLOCKD *const xd = &x->e_mbd;
6433 const struct buf_2d *const src = &x->plane[0].src;
6434 const int bw = 4 * num_4x4_blocks_wide_lookup[bsize];
6435 const int bh = 4 * num_4x4_blocks_high_lookup[bsize];
6436 const int N = bw * bh;
6437 int rate;
6438 int64_t dist;
6439 int64_t rd, best_rd = INT64_MAX;
6440 int wedge_index;
6441 int wedge_sign;
6442 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
6443 const uint8_t *mask;
6444 uint64_t sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006445#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006446 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
6447 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
6448#else
6449 const int bd_round = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07006450#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006451
6452 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
6453 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
6454 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
6455 DECLARE_ALIGNED(32, int16_t, ds[MAX_SB_SQUARE]);
6456
6457 int64_t sign_limit;
6458
Yaowu Xuf883b422016-08-30 14:01:10 -07006459#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006460 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006461 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006462 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006463 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006464 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006465 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006466 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
6467 } else // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07006468#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006469 {
Yaowu Xuf883b422016-08-30 14:01:10 -07006470 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
6471 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
6472 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006473 }
6474
Yaowu Xuf883b422016-08-30 14:01:10 -07006475 sign_limit = ((int64_t)aom_sum_squares_i16(r0, N) -
6476 (int64_t)aom_sum_squares_i16(r1, N)) *
Yaowu Xuc27fc142016-08-22 16:08:15 -07006477 (1 << WEDGE_WEIGHT_BITS) / 2;
6478
Yaowu Xuf883b422016-08-30 14:01:10 -07006479 av1_wedge_compute_delta_squares(ds, r0, r1, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006480
6481 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006482 mask = av1_get_contiguous_soft_mask(wedge_index, 0, bsize);
6483 wedge_sign = av1_wedge_sign_from_residuals(ds, mask, N, sign_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006484
Yaowu Xuf883b422016-08-30 14:01:10 -07006485 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
6486 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006487 sse = ROUND_POWER_OF_TWO(sse, bd_round);
6488
6489 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
6490 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
6491
6492 if (rd < best_rd) {
6493 *best_wedge_index = wedge_index;
6494 *best_wedge_sign = wedge_sign;
6495 best_rd = rd;
6496 }
6497 }
6498
6499 return best_rd;
6500}
6501
6502// Choose the best wedge index the specified sign
6503static int64_t pick_wedge_fixed_sign(
Yaowu Xuf883b422016-08-30 14:01:10 -07006504 const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006505 const BLOCK_SIZE bsize, const uint8_t *const p0, const uint8_t *const p1,
6506 const int wedge_sign, int *const best_wedge_index) {
6507 const MACROBLOCKD *const xd = &x->e_mbd;
6508 const struct buf_2d *const src = &x->plane[0].src;
6509 const int bw = 4 * num_4x4_blocks_wide_lookup[bsize];
6510 const int bh = 4 * num_4x4_blocks_high_lookup[bsize];
6511 const int N = bw * bh;
6512 int rate;
6513 int64_t dist;
6514 int64_t rd, best_rd = INT64_MAX;
6515 int wedge_index;
6516 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
6517 const uint8_t *mask;
6518 uint64_t sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006519#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006520 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
6521 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
6522#else
6523 const int bd_round = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07006524#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006525
6526 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
6527 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
6528
Yaowu Xuf883b422016-08-30 14:01:10 -07006529#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006530 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006531 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006532 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006533 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006534 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
6535 } else // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07006536#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006537 {
Yaowu Xuf883b422016-08-30 14:01:10 -07006538 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
6539 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006540 }
6541
6542 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006543 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
6544 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006545 sse = ROUND_POWER_OF_TWO(sse, bd_round);
6546
6547 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
6548 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
6549
6550 if (rd < best_rd) {
6551 *best_wedge_index = wedge_index;
6552 best_rd = rd;
6553 }
6554 }
6555
6556 return best_rd;
6557}
6558
Yaowu Xuf883b422016-08-30 14:01:10 -07006559static int64_t pick_interinter_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006560 const MACROBLOCK *const x,
6561 const BLOCK_SIZE bsize,
6562 const uint8_t *const p0,
6563 const uint8_t *const p1) {
6564 const MACROBLOCKD *const xd = &x->e_mbd;
6565 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6566 const int bw = 4 * num_4x4_blocks_wide_lookup[bsize];
6567
6568 int64_t rd;
6569 int wedge_index = -1;
6570 int wedge_sign = 0;
6571
6572 assert(is_interinter_wedge_used(bsize));
6573
6574 if (cpi->sf.fast_wedge_sign_estimate) {
6575 wedge_sign = estimate_wedge_sign(cpi, x, bsize, p0, bw, p1, bw);
6576 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, wedge_sign, &wedge_index);
6577 } else {
6578 rd = pick_wedge(cpi, x, bsize, p0, p1, &wedge_sign, &wedge_index);
6579 }
6580
6581 mbmi->interinter_wedge_sign = wedge_sign;
6582 mbmi->interinter_wedge_index = wedge_index;
6583 return rd;
6584}
6585
Yaowu Xuf883b422016-08-30 14:01:10 -07006586static int64_t pick_interintra_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006587 const MACROBLOCK *const x,
6588 const BLOCK_SIZE bsize,
6589 const uint8_t *const p0,
6590 const uint8_t *const p1) {
6591 const MACROBLOCKD *const xd = &x->e_mbd;
6592 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6593
6594 int64_t rd;
6595 int wedge_index = -1;
6596
6597 assert(is_interintra_wedge_used(bsize));
6598
6599 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, 0, &wedge_index);
6600
6601 mbmi->interintra_wedge_sign = 0;
6602 mbmi->interintra_wedge_index = wedge_index;
6603 return rd;
6604}
6605#endif // CONFIG_EXT_INTER
6606
6607static int64_t handle_inter_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07006608 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int *rate2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006609 int64_t *distortion, int *skippable, int *rate_y, int *rate_uv,
6610 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
6611 int mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07006612#if CONFIG_MOTION_VAR
Yue Chene9638cc2016-10-10 12:37:54 -07006613 uint8_t *above_pred_buf[3], int above_pred_stride[3],
6614 uint8_t *left_pred_buf[3], int left_pred_stride[3],
Yue Chencb60b182016-10-13 15:18:22 -07006615#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006616#if CONFIG_EXT_INTER
6617 int_mv single_newmvs[2][TOTAL_REFS_PER_FRAME],
6618 int single_newmvs_rate[2][TOTAL_REFS_PER_FRAME],
6619 int *compmode_interintra_cost, int *compmode_wedge_cost,
6620 int64_t (*const modelled_rd)[TOTAL_REFS_PER_FRAME],
6621#else
6622 int_mv single_newmv[TOTAL_REFS_PER_FRAME],
6623#endif // CONFIG_EXT_INTER
James Zern7b9407a2016-05-18 23:48:05 -07006624 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006625 int (*single_skippable)[TOTAL_REFS_PER_FRAME], int64_t *psse,
6626 const int64_t ref_best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07006627 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006628 MACROBLOCKD *xd = &x->e_mbd;
6629 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6630 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6631 const int is_comp_pred = has_second_ref(mbmi);
6632 const int this_mode = mbmi->mode;
6633 int_mv *frame_mv = mode_mv[this_mode];
6634 int i;
6635 int refs[2] = { mbmi->ref_frame[0],
6636 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
6637 int_mv cur_mv[2];
6638 int rate_mv = 0;
6639#if CONFIG_EXT_INTER
Angie Chiang75c22092016-10-25 12:19:16 -07006640 int pred_exists = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006641 const int bw = 4 * num_4x4_blocks_wide_lookup[bsize];
6642 int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
6643 int_mv single_newmv[TOTAL_REFS_PER_FRAME];
6644 const unsigned int *const interintra_mode_cost =
6645 cpi->interintra_mode_cost[size_group_lookup[bsize]];
6646 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
6647#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07006648 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006649#endif
6650#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006651#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006652 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
6653#else
6654 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07006655#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006656 uint8_t *tmp_buf;
6657
Yue Chencb60b182016-10-13 15:18:22 -07006658#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07006659 int allow_motvar =
6660#if CONFIG_EXT_INTER
6661 !is_comp_interintra_pred &&
6662#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07006663 is_motion_variation_allowed(mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006664 int rate2_nocoeff = 0, best_rate2 = INT_MAX, best_skippable, best_xskip,
6665 best_disable_skip = 0;
6666 int best_rate_y, best_rate_uv;
6667#if CONFIG_VAR_TX
6668 uint8_t best_blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
6669#endif // CONFIG_VAR_TX
6670 int64_t best_distortion = INT64_MAX;
Angie Chiang75c22092016-10-25 12:19:16 -07006671 int64_t best_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006672 MB_MODE_INFO best_mbmi;
6673#if CONFIG_EXT_INTER
6674 int rate2_bmc_nocoeff;
6675 int rate_mv_bmc;
6676 MB_MODE_INFO best_bmc_mbmi;
6677#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07006678#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang75c22092016-10-25 12:19:16 -07006679 int64_t rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006680 uint8_t *orig_dst[MAX_MB_PLANE];
6681 int orig_dst_stride[MAX_MB_PLANE];
Angie Chiang75c22092016-10-25 12:19:16 -07006682 uint8_t *tmp_dst[MAX_MB_PLANE];
6683 int tmp_dst_stride[MAX_MB_PLANE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006684 int rs = 0;
Angie Chiang75c22092016-10-25 12:19:16 -07006685 InterpFilter assign_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006686
6687 int skip_txfm_sb = 0;
6688 int64_t skip_sse_sb = INT64_MAX;
6689 int64_t distortion_y = 0, distortion_uv = 0;
6690 int16_t mode_ctx = mbmi_ext->mode_context[refs[0]];
6691
6692#if CONFIG_EXT_INTER
6693 *compmode_interintra_cost = 0;
6694 mbmi->use_wedge_interintra = 0;
6695 *compmode_wedge_cost = 0;
6696 mbmi->use_wedge_interinter = 0;
6697
6698 // is_comp_interintra_pred implies !is_comp_pred
6699 assert(!is_comp_interintra_pred || (!is_comp_pred));
6700 // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
6701 assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
6702#endif // CONFIG_EXT_INTER
6703
6704#if CONFIG_REF_MV
6705#if CONFIG_EXT_INTER
6706 if (is_comp_pred)
6707 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
6708 else
6709#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006710 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
6711 mbmi->ref_frame, bsize, -1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006712#endif
6713
Yaowu Xuf883b422016-08-30 14:01:10 -07006714#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006715 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
6716 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf_);
6717 else
Yaowu Xuf883b422016-08-30 14:01:10 -07006718#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006719 tmp_buf = tmp_buf_;
6720
6721 if (is_comp_pred) {
6722 if (frame_mv[refs[0]].as_int == INVALID_MV ||
6723 frame_mv[refs[1]].as_int == INVALID_MV)
6724 return INT64_MAX;
6725 }
6726
Yue Chene9638cc2016-10-10 12:37:54 -07006727 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006728 if (have_newmv_in_inter_mode(this_mode)) {
6729 if (is_comp_pred) {
6730#if CONFIG_EXT_INTER
6731 for (i = 0; i < 2; ++i) {
6732 single_newmv[refs[i]].as_int = single_newmvs[mv_idx][refs[i]].as_int;
6733 }
6734
6735 if (this_mode == NEW_NEWMV) {
6736 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
6737 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
6738
6739 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
6740 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, NULL,
6741 single_newmv, &rate_mv, 0);
6742 } else {
6743#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006744 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006745#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07006746 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
6747 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
6748 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006749#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006750 av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006751#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07006752 rate_mv += av1_mv_bit_cost(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006753 &frame_mv[refs[1]].as_mv, &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
6754 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
6755 }
6756 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
6757 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07006758 rate_mv = av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
6759 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
6760 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006761 } else {
6762 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07006763 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
6764 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
6765 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006766 }
6767#else
6768 // Initialize mv using single prediction mode result.
6769 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
6770 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
6771
6772 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
6773 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col,
6774 single_newmv, &rate_mv, 0);
6775 } else {
6776#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006777 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006778#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07006779 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
6780 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
6781 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006782#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006783 av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006784#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07006785 rate_mv += av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
6786 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
6787 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006788 }
6789#endif // CONFIG_EXT_INTER
6790 } else {
6791#if CONFIG_EXT_INTER
6792 if (is_comp_interintra_pred) {
6793 x->best_mv = single_newmvs[mv_idx][refs[0]];
6794 rate_mv = single_newmvs_rate[mv_idx][refs[0]];
6795 } else {
6796 single_motion_search(cpi, x, bsize, mi_row, mi_col, 0, mv_idx,
6797 &rate_mv);
6798 single_newmvs[mv_idx][refs[0]] = x->best_mv;
6799 single_newmvs_rate[mv_idx][refs[0]] = rate_mv;
6800 }
6801#else
6802 single_motion_search(cpi, x, bsize, mi_row, mi_col, &rate_mv);
6803 single_newmv[refs[0]] = x->best_mv;
6804#endif // CONFIG_EXT_INTER
6805
6806 if (x->best_mv.as_int == INVALID_MV) return INT64_MAX;
6807
6808 frame_mv[refs[0]] = x->best_mv;
6809 xd->mi[0]->bmi[0].as_mv[0] = x->best_mv;
6810
6811 // Estimate the rate implications of a new mv but discount this
6812 // under certain circumstances where we want to help initiate a weak
6813 // motion field, where the distortion gain for a single block may not
6814 // be enough to overcome the cost of a new mv.
6815 if (discount_newmv_test(cpi, this_mode, x->best_mv, mode_mv, refs[0])) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006816 rate_mv = AOMMAX((rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006817 }
6818 }
6819 *rate2 += rate_mv;
6820 }
6821
6822 for (i = 0; i < is_comp_pred + 1; ++i) {
6823 cur_mv[i] = frame_mv[refs[i]];
6824// Clip "next_nearest" so that it does not extend to far out of image
6825#if CONFIG_EXT_INTER
6826 if (this_mode != NEWMV && this_mode != NEWFROMNEARMV)
6827#else
6828 if (this_mode != NEWMV)
6829#endif // CONFIG_EXT_INTER
6830 clamp_mv2(&cur_mv[i].as_mv, xd);
6831
6832 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
6833 mbmi->mv[i].as_int = cur_mv[i].as_int;
6834 }
6835
6836#if CONFIG_REF_MV
6837#if CONFIG_EXT_INTER
6838 if (this_mode == NEAREST_NEARESTMV) {
6839#else
6840 if (this_mode == NEARESTMV && is_comp_pred) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006841 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006842#endif // CONFIG_EXT_INTER
6843 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
6844 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
6845 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
6846
6847 for (i = 0; i < 2; ++i) {
6848 clamp_mv2(&cur_mv[i].as_mv, xd);
6849 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
6850 mbmi->mv[i].as_int = cur_mv[i].as_int;
6851 }
6852 }
6853 }
6854
6855#if CONFIG_EXT_INTER
6856 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
6857 if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
6858 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
6859
6860 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
6861 clamp_mv2(&cur_mv[0].as_mv, xd);
6862 if (mv_check_bounds(x, &cur_mv[0].as_mv)) return INT64_MAX;
6863 mbmi->mv[0].as_int = cur_mv[0].as_int;
6864 }
6865
6866 if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
6867 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
6868
6869 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
6870 clamp_mv2(&cur_mv[1].as_mv, xd);
6871 if (mv_check_bounds(x, &cur_mv[1].as_mv)) return INT64_MAX;
6872 mbmi->mv[1].as_int = cur_mv[1].as_int;
6873 }
6874 }
6875
6876 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
6877 if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV ||
6878 this_mode == NEAR_NEARMV) {
6879 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][1].this_mv;
6880
6881 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
6882 clamp_mv2(&cur_mv[0].as_mv, xd);
6883 if (mv_check_bounds(x, &cur_mv[0].as_mv)) return INT64_MAX;
6884 mbmi->mv[0].as_int = cur_mv[0].as_int;
6885 }
6886
6887 if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV ||
6888 this_mode == NEAR_NEARMV) {
6889 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][1].comp_mv;
6890
6891 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
6892 clamp_mv2(&cur_mv[1].as_mv, xd);
6893 if (mv_check_bounds(x, &cur_mv[1].as_mv)) return INT64_MAX;
6894 mbmi->mv[1].as_int = cur_mv[1].as_int;
6895 }
6896 }
6897#else
6898 if (this_mode == NEARMV && is_comp_pred) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006899 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006900 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
6901 int ref_mv_idx = mbmi->ref_mv_idx + 1;
6902 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
6903 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
6904
6905 for (i = 0; i < 2; ++i) {
6906 clamp_mv2(&cur_mv[i].as_mv, xd);
6907 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
6908 mbmi->mv[i].as_int = cur_mv[i].as_int;
6909 }
6910 }
6911 }
6912#endif // CONFIG_EXT_INTER
6913#endif // CONFIG_REF_MV
6914
6915 // do first prediction into the destination buffer. Do the next
6916 // prediction into a temporary buffer. Then keep track of which one
6917 // of these currently holds the best predictor, and use the other
6918 // one for future predictions. In the end, copy from tmp_buf to
6919 // dst if necessary.
6920 for (i = 0; i < MAX_MB_PLANE; i++) {
Angie Chiang75c22092016-10-25 12:19:16 -07006921 tmp_dst[i] = tmp_buf + i * MAX_SB_SQUARE;
6922 tmp_dst_stride[i] = MAX_SB_SIZE;
6923 }
6924 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006925 orig_dst[i] = xd->plane[i].dst.buf;
6926 orig_dst_stride[i] = xd->plane[i].dst.stride;
6927 }
6928
6929 // We don't include the cost of the second reference here, because there
6930 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
6931 // words if you present them in that order, the second one is always known
6932 // if the first is known.
6933 //
6934 // Under some circumstances we discount the cost of new mv mode to encourage
6935 // initiation of a motion field.
6936 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]], mode_mv,
6937 refs[0])) {
6938#if CONFIG_REF_MV && CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006939 *rate2 += AOMMIN(cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx),
Yaowu Xuc27fc142016-08-22 16:08:15 -07006940 cost_mv_ref(cpi, NEARESTMV, is_comp_pred, mode_ctx));
6941#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006942 *rate2 += AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
Yaowu Xuc27fc142016-08-22 16:08:15 -07006943 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
6944#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
6945 } else {
6946#if CONFIG_REF_MV && CONFIG_EXT_INTER
6947 *rate2 += cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx);
6948#else
6949 *rate2 += cost_mv_ref(cpi, this_mode, mode_ctx);
6950#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
6951 }
6952
6953 if (RDCOST(x->rdmult, x->rddiv, *rate2, 0) > ref_best_rd &&
6954#if CONFIG_EXT_INTER
6955 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV
6956#else
6957 mbmi->mode != NEARESTMV
6958#endif // CONFIG_EXT_INTER
6959 )
6960 return INT64_MAX;
6961
Angie Chiang75c22092016-10-25 12:19:16 -07006962 if (cm->interp_filter == SWITCHABLE) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006963#if !CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07006964 assign_filter =
6965 predict_interp_filter(cpi, x, bsize, mi_row, mi_col, single_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006966#endif
Angie Chiang75c22092016-10-25 12:19:16 -07006967#if CONFIG_EXT_INTERP || CONFIG_DUAL_FILTER
6968 if (!av1_is_interp_needed(xd)) assign_filter = EIGHTTAP_REGULAR;
6969#endif
6970 } else {
6971 assign_filter = cm->interp_filter;
6972 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006973
Angie Chiang75c22092016-10-25 12:19:16 -07006974 { // Do interpolation filter search in the parentheses
6975 int tmp_rate;
6976 int64_t tmp_dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006977#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07006978 mbmi->interp_filter[0] =
6979 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
6980 mbmi->interp_filter[1] =
6981 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
6982 mbmi->interp_filter[2] =
6983 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
6984 mbmi->interp_filter[3] =
6985 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006986#else
Angie Chiang75c22092016-10-25 12:19:16 -07006987 mbmi->interp_filter =
6988 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006989#endif
Angie Chiang75c22092016-10-25 12:19:16 -07006990 rs = av1_get_switchable_rate(cpi, xd);
6991 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
6992 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
6993 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
6994 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006995
Angie Chiang75c22092016-10-25 12:19:16 -07006996 if (assign_filter == SWITCHABLE) {
6997 // do interp_filter search
6998 if (av1_is_interp_needed(xd)) {
6999 int best_in_temp = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007000#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007001 InterpFilter best_filter[4];
7002 av1_copy(best_filter, mbmi->interp_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007003#else
Angie Chiang75c22092016-10-25 12:19:16 -07007004 InterpFilter best_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007005#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007006 restore_dst_buf(xd, tmp_dst, tmp_dst_stride);
7007#if CONFIG_DUAL_FILTER
7008 // EIGHTTAP_REGULAR mode is calculated beforehand
7009 for (i = 1; i < SWITCHABLE_FILTERS * SWITCHABLE_FILTERS; ++i)
7010#else
7011 // EIGHTTAP_REGULAR mode is calculated beforehand
7012 for (i = 1; i < SWITCHABLE_FILTERS; ++i)
7013#endif
7014 {
7015 int tmp_skip_sb = 0;
7016 int64_t tmp_skip_sse = INT64_MAX;
7017 int tmp_rs;
Angie Chiang3655dcd2016-10-28 09:05:27 -07007018 int64_t tmp_rd;
Angie Chiang75c22092016-10-25 12:19:16 -07007019#if CONFIG_DUAL_FILTER
7020 mbmi->interp_filter[0] = filter_sets[i][0];
7021 mbmi->interp_filter[1] = filter_sets[i][1];
7022 mbmi->interp_filter[2] = filter_sets[i][0];
7023 mbmi->interp_filter[3] = filter_sets[i][1];
7024#else
7025 mbmi->interp_filter = i;
7026#endif
7027 tmp_rs = av1_get_switchable_rate(cpi, xd);
7028 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
7029 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7030 &tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
7031 tmp_rd = RDCOST(x->rdmult, x->rddiv, tmp_rs + tmp_rate, tmp_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007032
Angie Chiang75c22092016-10-25 12:19:16 -07007033 if (tmp_rd < rd) {
7034 rd = tmp_rd;
7035 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007036#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007037 av1_copy(best_filter, mbmi->interp_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007038#else
Angie Chiang75c22092016-10-25 12:19:16 -07007039 best_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007040#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007041 skip_txfm_sb = tmp_skip_sb;
7042 skip_sse_sb = tmp_skip_sse;
7043 best_in_temp = !best_in_temp;
7044 if (best_in_temp) {
7045 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7046 } else {
7047 restore_dst_buf(xd, tmp_dst, tmp_dst_stride);
7048 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007049 }
7050 }
Angie Chiang75c22092016-10-25 12:19:16 -07007051 if (best_in_temp) {
7052 restore_dst_buf(xd, tmp_dst, tmp_dst_stride);
7053 } else {
7054 restore_dst_buf(xd, orig_dst, orig_dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007055 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007056#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007057 av1_copy(mbmi->interp_filter, best_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007058#else
Angie Chiang75c22092016-10-25 12:19:16 -07007059 mbmi->interp_filter = best_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007060#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007061 } else {
Angie Chiang75c22092016-10-25 12:19:16 -07007062#if !CONFIG_EXT_INTERP && !CONFIG_DUAL_FILTER
7063 int tmp_rs;
7064 InterpFilter best_filter = mbmi->interp_filter;
7065 rs = av1_get_switchable_rate(cpi, xd);
7066 for (i = 1; i < SWITCHABLE_FILTERS; ++i) {
7067 mbmi->interp_filter = i;
7068 tmp_rs = av1_get_switchable_rate(cpi, xd);
7069 if (tmp_rs < rs) {
7070 rs = tmp_rs;
7071 best_filter = i;
7072 }
7073 }
7074 mbmi->interp_filter = best_filter;
7075#else
7076 assert(0);
7077#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007078 }
7079 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007080 }
7081
Yaowu Xuc27fc142016-08-22 16:08:15 -07007082#if CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07007083#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007084 best_bmc_mbmi = *mbmi;
7085 rate_mv_bmc = rate_mv;
7086 rate2_bmc_nocoeff = *rate2;
7087 if (cm->interp_filter == SWITCHABLE) rate2_bmc_nocoeff += rs;
Yue Chencb60b182016-10-13 15:18:22 -07007088#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007089
7090 if (is_comp_pred && is_interinter_wedge_used(bsize)) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07007091 int rate_sum, rs2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007092 int64_t dist_sum;
7093 int64_t best_rd_nowedge = INT64_MAX;
7094 int64_t best_rd_wedge = INT64_MAX;
7095 int tmp_skip_txfm_sb;
7096 int64_t tmp_skip_sse_sb;
7097
Urvang Joshi368fbc92016-10-17 16:31:34 -07007098 rs2 = av1_cost_bit(cm->fc->wedge_interinter_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007099 mbmi->use_wedge_interinter = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07007100 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
7101 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007102 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7103 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7104 if (rd != INT64_MAX)
Urvang Joshi368fbc92016-10-17 16:31:34 -07007105 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007106 best_rd_nowedge = rd;
7107
7108 // Disbale wedge search if source variance is small
7109 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
7110 best_rd_nowedge / 3 < ref_best_rd) {
7111 uint8_t pred0[2 * MAX_SB_SQUARE];
7112 uint8_t pred1[2 * MAX_SB_SQUARE];
7113 uint8_t *preds0[1] = { pred0 };
7114 uint8_t *preds1[1] = { pred1 };
7115 int strides[1] = { bw };
7116
7117 mbmi->use_wedge_interinter = 1;
Urvang Joshi368fbc92016-10-17 16:31:34 -07007118 rs2 = av1_cost_literal(get_interinter_wedge_bits(bsize)) +
7119 av1_cost_bit(cm->fc->wedge_interinter_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007120
Yaowu Xuf883b422016-08-30 14:01:10 -07007121 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007122 xd, bsize, 0, 0, mi_row, mi_col, 0, preds0, strides);
Yaowu Xuf883b422016-08-30 14:01:10 -07007123 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007124 xd, bsize, 0, 0, mi_row, mi_col, 1, preds1, strides);
7125
7126 // Choose the best wedge
7127 best_rd_wedge = pick_interinter_wedge(cpi, x, bsize, pred0, pred1);
Urvang Joshi368fbc92016-10-17 16:31:34 -07007128 best_rd_wedge += RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007129
7130 if (have_newmv_in_inter_mode(this_mode)) {
7131 int_mv tmp_mv[2];
7132 int rate_mvs[2], tmp_rate_mv = 0;
7133 if (this_mode == NEW_NEWMV) {
7134 int mv_idxs[2] = { 0, 0 };
7135 do_masked_motion_search_indexed(
7136 cpi, x, mbmi->interinter_wedge_index, mbmi->interinter_wedge_sign,
7137 bsize, mi_row, mi_col, tmp_mv, rate_mvs, mv_idxs, 2);
7138 tmp_rate_mv = rate_mvs[0] + rate_mvs[1];
7139 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7140 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7141 } else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
7142 int mv_idxs[2] = { 0, 0 };
7143 do_masked_motion_search_indexed(
7144 cpi, x, mbmi->interinter_wedge_index, mbmi->interinter_wedge_sign,
7145 bsize, mi_row, mi_col, tmp_mv, rate_mvs, mv_idxs, 0);
7146 tmp_rate_mv = rate_mvs[0];
7147 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7148 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
7149 int mv_idxs[2] = { 0, 0 };
7150 do_masked_motion_search_indexed(
7151 cpi, x, mbmi->interinter_wedge_index, mbmi->interinter_wedge_sign,
7152 bsize, mi_row, mi_col, tmp_mv, rate_mvs, mv_idxs, 1);
7153 tmp_rate_mv = rate_mvs[1];
7154 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7155 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007156 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007157 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7158 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
Urvang Joshi368fbc92016-10-17 16:31:34 -07007159 rd =
7160 RDCOST(x->rdmult, x->rddiv, rs2 + tmp_rate_mv + rate_sum, dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007161 if (rd < best_rd_wedge) {
7162 best_rd_wedge = rd;
7163 } else {
7164 mbmi->mv[0].as_int = cur_mv[0].as_int;
7165 mbmi->mv[1].as_int = cur_mv[1].as_int;
7166 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07007167 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0, preds0,
7168 strides, preds1, strides);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007169 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007170 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007171 rd =
7172 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7173 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7174 if (rd != INT64_MAX)
Urvang Joshi368fbc92016-10-17 16:31:34 -07007175 rd = RDCOST(x->rdmult, x->rddiv, rs2 + tmp_rate_mv + rate_sum,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007176 dist_sum);
7177 best_rd_wedge = rd;
7178
7179 if (best_rd_wedge < best_rd_nowedge) {
7180 mbmi->use_wedge_interinter = 1;
7181 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
7182 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
7183 *rate2 += tmp_rate_mv - rate_mv;
7184 rate_mv = tmp_rate_mv;
7185 } else {
7186 mbmi->use_wedge_interinter = 0;
7187 mbmi->mv[0].as_int = cur_mv[0].as_int;
7188 mbmi->mv[1].as_int = cur_mv[1].as_int;
7189 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
7190 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
7191 }
7192 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07007193 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0, preds0,
7194 strides, preds1, strides);
7195 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007196 rd =
7197 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7198 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7199 if (rd != INT64_MAX)
Urvang Joshi368fbc92016-10-17 16:31:34 -07007200 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007201 best_rd_wedge = rd;
7202 if (best_rd_wedge < best_rd_nowedge) {
7203 mbmi->use_wedge_interinter = 1;
7204 } else {
7205 mbmi->use_wedge_interinter = 0;
7206 }
7207 }
7208 }
7209 if (ref_best_rd < INT64_MAX &&
Yaowu Xuf883b422016-08-30 14:01:10 -07007210 AOMMIN(best_rd_wedge, best_rd_nowedge) / 3 > ref_best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007211 return INT64_MAX;
7212
7213 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007214
7215 if (mbmi->use_wedge_interinter)
7216 *compmode_wedge_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07007217 av1_cost_literal(get_interinter_wedge_bits(bsize)) +
7218 av1_cost_bit(cm->fc->wedge_interinter_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007219 else
7220 *compmode_wedge_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07007221 av1_cost_bit(cm->fc->wedge_interinter_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007222 }
7223
7224 if (is_comp_interintra_pred) {
7225 INTERINTRA_MODE best_interintra_mode = II_DC_PRED;
7226 int64_t best_interintra_rd = INT64_MAX;
7227 int rmode, rate_sum;
7228 int64_t dist_sum;
7229 int j;
7230 int64_t best_interintra_rd_nowedge = INT64_MAX;
7231 int64_t best_interintra_rd_wedge = INT64_MAX;
7232 int rwedge;
7233 int_mv tmp_mv;
7234 int tmp_rate_mv = 0;
7235 int tmp_skip_txfm_sb;
7236 int64_t tmp_skip_sse_sb;
7237 DECLARE_ALIGNED(16, uint8_t, intrapred_[2 * MAX_SB_SQUARE]);
7238 uint8_t *intrapred;
7239
Yaowu Xuf883b422016-08-30 14:01:10 -07007240#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007241 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
7242 intrapred = CONVERT_TO_BYTEPTR(intrapred_);
7243 else
Yaowu Xuf883b422016-08-30 14:01:10 -07007244#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007245 intrapred = intrapred_;
7246
7247 mbmi->ref_frame[1] = NONE;
7248 for (j = 0; j < MAX_MB_PLANE; j++) {
7249 xd->plane[j].dst.buf = tmp_buf + j * MAX_SB_SQUARE;
7250 xd->plane[j].dst.stride = bw;
7251 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007252 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007253 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7254 mbmi->ref_frame[1] = INTRA_FRAME;
7255 mbmi->use_wedge_interintra = 0;
7256
7257 for (j = 0; j < INTERINTRA_MODES; ++j) {
7258 mbmi->interintra_mode = (INTERINTRA_MODE)j;
7259 rmode = interintra_mode_cost[mbmi->interintra_mode];
Yaowu Xuf883b422016-08-30 14:01:10 -07007260 av1_build_intra_predictors_for_interintra(xd, bsize, 0, intrapred, bw);
7261 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007262 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7263 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7264 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate_mv + rate_sum, dist_sum);
7265 if (rd < best_interintra_rd) {
7266 best_interintra_rd = rd;
7267 best_interintra_mode = mbmi->interintra_mode;
7268 }
7269 }
7270 mbmi->interintra_mode = best_interintra_mode;
7271 rmode = interintra_mode_cost[mbmi->interintra_mode];
Yaowu Xuf883b422016-08-30 14:01:10 -07007272 av1_build_intra_predictors_for_interintra(xd, bsize, 0, intrapred, bw);
7273 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
7274 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007275 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7276 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7277 if (rd != INT64_MAX)
7278 rd = RDCOST(x->rdmult, x->rddiv, rate_mv + rmode + rate_sum, dist_sum);
7279 best_interintra_rd = rd;
7280
7281 if (ref_best_rd < INT64_MAX && best_interintra_rd > 2 * ref_best_rd) {
7282 return INT64_MAX;
7283 }
7284 if (is_interintra_wedge_used(bsize)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007285 rwedge = av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007286 if (rd != INT64_MAX)
7287 rd = RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge + rate_sum,
7288 dist_sum);
7289 best_interintra_rd_nowedge = rd;
7290
7291 // Disbale wedge search if source variance is small
7292 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh) {
7293 mbmi->use_wedge_interintra = 1;
7294
Yaowu Xuf883b422016-08-30 14:01:10 -07007295 rwedge = av1_cost_literal(get_interintra_wedge_bits(bsize)) +
7296 av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007297
7298 best_interintra_rd_wedge =
7299 pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
7300
7301 best_interintra_rd_wedge +=
7302 RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge, 0);
7303 // Refine motion vector.
7304 if (have_newmv_in_inter_mode(this_mode)) {
7305 // get negative of mask
Yaowu Xuf883b422016-08-30 14:01:10 -07007306 const uint8_t *mask = av1_get_contiguous_soft_mask(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007307 mbmi->interintra_wedge_index, 1, bsize);
7308 do_masked_motion_search(cpi, x, mask, bw, bsize, mi_row, mi_col,
7309 &tmp_mv, &tmp_rate_mv, 0, mv_idx);
7310 mbmi->mv[0].as_int = tmp_mv.as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07007311 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007312 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7313 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7314 rd = RDCOST(x->rdmult, x->rddiv,
7315 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
7316 if (rd < best_interintra_rd_wedge) {
7317 best_interintra_rd_wedge = rd;
7318 } else {
7319 tmp_mv.as_int = cur_mv[0].as_int;
7320 tmp_rate_mv = rate_mv;
7321 }
7322 } else {
7323 tmp_mv.as_int = cur_mv[0].as_int;
7324 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07007325 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007326 }
7327 // Evaluate closer to true rd
Yaowu Xuf883b422016-08-30 14:01:10 -07007328 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007329 rd =
7330 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7331 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7332 if (rd != INT64_MAX)
7333 rd = RDCOST(x->rdmult, x->rddiv,
7334 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
7335 best_interintra_rd_wedge = rd;
7336 if (best_interintra_rd_wedge < best_interintra_rd_nowedge) {
7337 mbmi->use_wedge_interintra = 1;
7338 best_interintra_rd = best_interintra_rd_wedge;
7339 mbmi->mv[0].as_int = tmp_mv.as_int;
7340 *rate2 += tmp_rate_mv - rate_mv;
7341 rate_mv = tmp_rate_mv;
7342 } else {
7343 mbmi->use_wedge_interintra = 0;
7344 best_interintra_rd = best_interintra_rd_nowedge;
7345 mbmi->mv[0].as_int = cur_mv[0].as_int;
7346 }
7347 } else {
7348 mbmi->use_wedge_interintra = 0;
7349 best_interintra_rd = best_interintra_rd_nowedge;
7350 }
7351 }
7352
7353 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007354 *compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07007355 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007356 *compmode_interintra_cost += interintra_mode_cost[mbmi->interintra_mode];
7357 if (is_interintra_wedge_used(bsize)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007358 *compmode_interintra_cost += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007359 cm->fc->wedge_interintra_prob[bsize], mbmi->use_wedge_interintra);
7360 if (mbmi->use_wedge_interintra) {
7361 *compmode_interintra_cost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07007362 av1_cost_literal(get_interintra_wedge_bits(bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007363 }
7364 }
7365 } else if (is_interintra_allowed(mbmi)) {
7366 *compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07007367 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007368 }
7369
7370#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07007371 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007372#if CONFIG_DUAL_FILTER
7373 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = EIGHTTAP_REGULAR;
7374#else
7375 mbmi->interp_filter = EIGHTTAP_REGULAR;
7376#endif
7377 pred_exists = 0;
7378 }
7379#endif // CONFIG_EXT_INTERP
Angie Chiang75c22092016-10-25 12:19:16 -07007380 if (pred_exists == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007381 int tmp_rate;
7382 int64_t tmp_dist;
Yaowu Xuf883b422016-08-30 14:01:10 -07007383 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007384 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7385 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7386 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
7387 }
Angie Chiang75c22092016-10-25 12:19:16 -07007388#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07007389
7390#if CONFIG_DUAL_FILTER
7391 if (!is_comp_pred) single_filter[this_mode][refs[0]] = mbmi->interp_filter[0];
7392#else
7393 if (!is_comp_pred) single_filter[this_mode][refs[0]] = mbmi->interp_filter;
7394#endif
7395
7396#if CONFIG_EXT_INTER
7397 if (modelled_rd != NULL) {
7398 if (is_comp_pred) {
7399 const int mode0 = compound_ref0_mode(this_mode);
7400 const int mode1 = compound_ref1_mode(this_mode);
7401 int64_t mrd =
Yaowu Xuf883b422016-08-30 14:01:10 -07007402 AOMMIN(modelled_rd[mode0][refs[0]], modelled_rd[mode1][refs[1]]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007403 if (rd / 4 * 3 > mrd && ref_best_rd < INT64_MAX) {
7404 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7405 return INT64_MAX;
7406 }
7407 } else if (!is_comp_interintra_pred) {
7408 modelled_rd[this_mode][refs[0]] = rd;
7409 }
7410 }
7411#endif // CONFIG_EXT_INTER
7412
7413 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
7414 // if current pred_error modeled rd is substantially more than the best
7415 // so far, do not bother doing full rd
7416 if (rd / 2 > ref_best_rd) {
7417 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7418 return INT64_MAX;
7419 }
7420 }
7421
7422 if (cm->interp_filter == SWITCHABLE) *rate2 += rs;
Yue Chencb60b182016-10-13 15:18:22 -07007423#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007424 rate2_nocoeff = *rate2;
Yue Chencb60b182016-10-13 15:18:22 -07007425#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007426
Yue Chencb60b182016-10-13 15:18:22 -07007427#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007428 best_rd = INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007429 for (mbmi->motion_mode = SIMPLE_TRANSLATION;
7430 mbmi->motion_mode < (allow_motvar ? MOTION_MODES : 1);
7431 mbmi->motion_mode++) {
Angie Chianga2b56d32016-10-25 17:34:59 -07007432 int64_t tmp_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007433#if CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07007434 int tmp_rate2 = mbmi->motion_mode != SIMPLE_TRANSLATION ? rate2_bmc_nocoeff
7435 : rate2_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007436#else
7437 int tmp_rate2 = rate2_nocoeff;
7438#endif // CONFIG_EXT_INTER
7439#if CONFIG_EXT_INTERP
7440#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07007441 InterpFilter obmc_interp_filter[2][2] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007442 { mbmi->interp_filter[0], mbmi->interp_filter[1] }, // obmc == 0
7443 { mbmi->interp_filter[0], mbmi->interp_filter[1] } // obmc == 1
7444 };
7445#else
James Zern7b9407a2016-05-18 23:48:05 -07007446 InterpFilter obmc_interp_filter[2] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007447 mbmi->interp_filter, // obmc == 0
7448 mbmi->interp_filter // obmc == 1
7449 };
7450#endif // CONFIG_DUAL_FILTER
7451#endif // CONFIG_EXT_INTERP
7452
Yue Chencb60b182016-10-13 15:18:22 -07007453#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007454 int tmp_rate;
7455 int64_t tmp_dist;
Yue Chencb60b182016-10-13 15:18:22 -07007456 if (mbmi->motion_mode == OBMC_CAUSAL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007457#if CONFIG_EXT_INTER
7458 *mbmi = best_bmc_mbmi;
Yue Chencb60b182016-10-13 15:18:22 -07007459 mbmi->motion_mode = OBMC_CAUSAL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007460#endif // CONFIG_EXT_INTER
7461 if (!is_comp_pred && have_newmv_in_inter_mode(this_mode)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007462 int tmp_rate_mv = 0;
7463
Yue Chene9638cc2016-10-10 12:37:54 -07007464 single_motion_search(cpi, x, bsize, mi_row, mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007465#if CONFIG_EXT_INTER
Yue Chene9638cc2016-10-10 12:37:54 -07007466 0, mv_idx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007467#endif // CONFIG_EXT_INTER
Yue Chene9638cc2016-10-10 12:37:54 -07007468 &tmp_rate_mv);
7469 mbmi->mv[0].as_int = x->best_mv.as_int;
7470 if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
7471 refs[0])) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007472 tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007473 }
7474#if CONFIG_EXT_INTER
7475 tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
7476#else
7477 tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
7478#endif // CONFIG_EXT_INTER
7479#if CONFIG_EXT_INTERP
7480#if CONFIG_DUAL_FILTER
7481 if (!has_subpel_mv_component(xd->mi[0], xd, 0))
7482 obmc_interp_filter[1][0] = mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
7483 if (!has_subpel_mv_component(xd->mi[0], xd, 1))
7484 obmc_interp_filter[1][1] = mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
7485#else
Yaowu Xuf883b422016-08-30 14:01:10 -07007486 if (!av1_is_interp_needed(xd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07007487 obmc_interp_filter[1] = mbmi->interp_filter = EIGHTTAP_REGULAR;
7488#endif // CONFIG_DUAL_FILTER
7489 // This is not quite correct with CONFIG_DUAL_FILTER when a filter
7490 // is needed in only one direction
Yaowu Xuf883b422016-08-30 14:01:10 -07007491 if (!av1_is_interp_needed(xd)) tmp_rate2 -= rs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007492#endif // CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07007493 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007494#if CONFIG_EXT_INTER
7495 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07007496 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007497#endif // CONFIG_EXT_INTER
7498 }
Yue Chene9638cc2016-10-10 12:37:54 -07007499 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, above_pred_buf,
7500 above_pred_stride, left_pred_buf,
7501 left_pred_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007502 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7503 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7504 }
Yue Chencb60b182016-10-13 15:18:22 -07007505#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007506
7507#if CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07007508 if (mbmi->motion_mode == WARPED_CAUSAL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007509 // TODO(yuec): Add code
7510 }
7511#endif // CONFIG_WARPED_MOTION
7512 x->skip = 0;
7513
7514 *rate2 = tmp_rate2;
Yue Chencb60b182016-10-13 15:18:22 -07007515 if (allow_motvar) *rate2 += cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007516 *distortion = 0;
Yue Chencb60b182016-10-13 15:18:22 -07007517#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007518 if (!skip_txfm_sb) {
7519 int skippable_y, skippable_uv;
7520 int64_t sseuv = INT64_MAX;
7521 int64_t rdcosty = INT64_MAX;
7522
7523 // Y cost and distortion
Yaowu Xuf883b422016-08-30 14:01:10 -07007524 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007525#if CONFIG_VAR_TX
Jingning Han94d5bfc2016-10-21 10:14:36 -07007526 if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id]) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007527 select_tx_type_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
7528 bsize, ref_best_rd);
7529 } else {
7530 int idx, idy;
7531 super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
7532 bsize, ref_best_rd);
7533 for (idy = 0; idy < xd->n8_h; ++idy)
7534 for (idx = 0; idx < xd->n8_w; ++idx)
7535 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
7536 memset(x->blk_skip[0], skippable_y,
7537 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7538 }
7539#else
7540 super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse, bsize,
7541 ref_best_rd);
7542#endif // CONFIG_VAR_TX
7543
7544 if (*rate_y == INT_MAX) {
7545 *rate2 = INT_MAX;
7546 *distortion = INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007547#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7548 if (mbmi->motion_mode != SIMPLE_TRANSLATION) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007549 continue;
7550 } else {
Yue Chencb60b182016-10-13 15:18:22 -07007551#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007552 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7553 return INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007554#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007555 }
Yue Chencb60b182016-10-13 15:18:22 -07007556#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007557 }
7558
7559 *rate2 += *rate_y;
7560 *distortion += distortion_y;
7561
7562 rdcosty = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
Yaowu Xuf883b422016-08-30 14:01:10 -07007563 rdcosty = AOMMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, *psse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007564
7565#if CONFIG_VAR_TX
7566 if (!inter_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv,
7567 &sseuv, bsize, ref_best_rd - rdcosty))
7568#else
7569 if (!super_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv,
7570 &sseuv, bsize, ref_best_rd - rdcosty))
7571#endif // CONFIG_VAR_TX
7572 {
7573 *rate2 = INT_MAX;
7574 *distortion = INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007575#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007576 continue;
7577#else
7578 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7579 return INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007580#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007581 }
7582
7583 *psse += sseuv;
7584 *rate2 += *rate_uv;
7585 *distortion += distortion_uv;
7586 *skippable = skippable_y && skippable_uv;
Yue Chencb60b182016-10-13 15:18:22 -07007587#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007588 if (*skippable) {
7589 *rate2 -= *rate_uv + *rate_y;
7590 *rate_y = 0;
7591 *rate_uv = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07007592 *rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007593 mbmi->skip = 0;
7594 // here mbmi->skip temporarily plays a role as what this_skip2 does
7595 } else if (!xd->lossless[mbmi->segment_id] &&
7596 (RDCOST(x->rdmult, x->rddiv,
7597 *rate_y + *rate_uv +
Yaowu Xuf883b422016-08-30 14:01:10 -07007598 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Yaowu Xuc27fc142016-08-22 16:08:15 -07007599 *distortion) >=
7600 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007601 av1_cost_bit(av1_get_skip_prob(cm, xd), 1), *psse))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007602 *rate2 -= *rate_uv + *rate_y;
Yaowu Xuf883b422016-08-30 14:01:10 -07007603 *rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007604 *distortion = *psse;
7605 *rate_y = 0;
7606 *rate_uv = 0;
7607 mbmi->skip = 1;
7608 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07007609 *rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007610 mbmi->skip = 0;
7611 }
7612 *disable_skip = 0;
Yue Chencb60b182016-10-13 15:18:22 -07007613#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007614 } else {
7615 x->skip = 1;
7616 *disable_skip = 1;
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07007617 mbmi->tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007618
7619// The cost of skip bit needs to be added.
Yue Chencb60b182016-10-13 15:18:22 -07007620#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007621 mbmi->skip = 0;
Yue Chencb60b182016-10-13 15:18:22 -07007622#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuf883b422016-08-30 14:01:10 -07007623 *rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007624
7625 *distortion = skip_sse_sb;
7626 *psse = skip_sse_sb;
7627 *rate_y = 0;
7628 *rate_uv = 0;
7629 *skippable = 1;
7630 }
Sarah Parkere5299862016-08-16 14:57:37 -07007631#if CONFIG_GLOBAL_MOTION
7632 if (this_mode == ZEROMV) {
7633 *rate2 += GLOBAL_MOTION_RATE(mbmi->ref_frame[0]);
7634 if (is_comp_pred) *rate2 += GLOBAL_MOTION_RATE(mbmi->ref_frame[1]);
7635 }
7636#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007637
Yue Chencb60b182016-10-13 15:18:22 -07007638#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007639 tmp_rd = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
Yue Chencb60b182016-10-13 15:18:22 -07007640 if (mbmi->motion_mode == SIMPLE_TRANSLATION || (tmp_rd < best_rd)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007641#if CONFIG_EXT_INTERP
7642#if CONFIG_DUAL_FILTER
Yue Chencb60b182016-10-13 15:18:22 -07007643 mbmi->interp_filter[0] = obmc_interp_filter[mbmi->motion_mode][0];
7644 mbmi->interp_filter[1] = obmc_interp_filter[mbmi->motion_mode][1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007645#else
Yue Chencb60b182016-10-13 15:18:22 -07007646 mbmi->interp_filter = obmc_interp_filter[mbmi->motion_mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007647#endif // CONFIG_DUAL_FILTER
7648#endif // CONFIG_EXT_INTERP
7649 best_mbmi = *mbmi;
7650 best_rd = tmp_rd;
7651 best_rate2 = *rate2;
7652 best_rate_y = *rate_y;
7653 best_rate_uv = *rate_uv;
7654#if CONFIG_VAR_TX
7655 for (i = 0; i < MAX_MB_PLANE; ++i)
7656 memcpy(best_blk_skip[i], x->blk_skip[i],
7657 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7658#endif // CONFIG_VAR_TX
7659 best_distortion = *distortion;
7660 best_skippable = *skippable;
7661 best_xskip = x->skip;
7662 best_disable_skip = *disable_skip;
Yaowu Xuf883b422016-08-30 14:01:10 -07007663#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007664 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007665 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007666 cpi, &xd->plane[0].dst, bsize, xd->bd);
7667 } else {
7668 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07007669 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007670 }
7671#else
7672 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07007673 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
7674#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007675 }
7676 }
7677
7678 if (best_rd == INT64_MAX) {
7679 *rate2 = INT_MAX;
7680 *distortion = INT64_MAX;
7681 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7682 return INT64_MAX;
7683 }
7684 *mbmi = best_mbmi;
7685 *rate2 = best_rate2;
7686 *rate_y = best_rate_y;
7687 *rate_uv = best_rate_uv;
7688#if CONFIG_VAR_TX
7689 for (i = 0; i < MAX_MB_PLANE; ++i)
7690 memcpy(x->blk_skip[i], best_blk_skip[i],
7691 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7692#endif // CONFIG_VAR_TX
7693 *distortion = best_distortion;
7694 *skippable = best_skippable;
7695 x->skip = best_xskip;
7696 *disable_skip = best_disable_skip;
Yue Chencb60b182016-10-13 15:18:22 -07007697#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007698
7699 if (!is_comp_pred) single_skippable[this_mode][refs[0]] = *skippable;
7700
Yue Chencb60b182016-10-13 15:18:22 -07007701#if !(CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION)
Yaowu Xuf883b422016-08-30 14:01:10 -07007702#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007703 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007704 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007705 cpi, &xd->plane[0].dst, bsize, xd->bd);
7706 } else {
7707 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07007708 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007709 }
7710#else
7711 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07007712 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
7713#endif // CONFIG_AOM_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07007714#endif // !(CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007715
7716 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7717 return 0; // The rate-distortion cost will be re-calculated by caller.
7718}
7719
Urvang Joshi52648442016-10-13 17:27:51 -07007720void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
7721 RD_COST *rd_cost, BLOCK_SIZE bsize,
7722 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
7723 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007724 MACROBLOCKD *const xd = &x->e_mbd;
7725 struct macroblockd_plane *const pd = xd->plane;
7726 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
7727 int y_skip = 0, uv_skip = 0;
7728 int64_t dist_y = 0, dist_uv = 0;
7729 TX_SIZE max_uv_tx_size;
7730 ctx->skip = 0;
7731 xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
7732 xd->mi[0]->mbmi.ref_frame[1] = NONE;
7733
7734 if (bsize >= BLOCK_8X8) {
7735 if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y,
7736 &y_skip, bsize, best_rd) >= best_rd) {
7737 rd_cost->rate = INT_MAX;
7738 return;
7739 }
7740 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007741 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07007742 &dist_y, &y_skip, best_rd) >= best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007743 rd_cost->rate = INT_MAX;
7744 return;
7745 }
7746 }
Debargha Mukherjee2f123402016-08-30 17:43:38 -07007747 max_uv_tx_size = uv_txsize_lookup[bsize][xd->mi[0]->mbmi.tx_size]
7748 [pd[1].subsampling_x][pd[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007749 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007750 &uv_skip, AOMMAX(BLOCK_8X8, bsize), max_uv_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007751
7752 if (y_skip && uv_skip) {
7753 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
Yaowu Xuf883b422016-08-30 14:01:10 -07007754 av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007755 rd_cost->dist = dist_y + dist_uv;
7756 } else {
7757 rd_cost->rate =
Yaowu Xuf883b422016-08-30 14:01:10 -07007758 rate_y + rate_uv + av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007759 rd_cost->dist = dist_y + dist_uv;
7760 }
7761
7762 ctx->mic = *xd->mi[0];
7763 ctx->mbmi_ext = *x->mbmi_ext;
7764 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
7765}
7766
Yaowu Xuc27fc142016-08-22 16:08:15 -07007767// Do we have an internal image edge (e.g. formatting bars).
Urvang Joshi52648442016-10-13 17:27:51 -07007768int av1_internal_image_edge(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007769 return (cpi->oxcf.pass == 2) &&
7770 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
7771 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
7772}
7773
7774// Checks to see if a super block is on a horizontal image edge.
7775// In most cases this is the "real" edge unless there are formatting
7776// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07007777int av1_active_h_edge(const AV1_COMP *cpi, int mi_row, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007778 int top_edge = 0;
7779 int bottom_edge = cpi->common.mi_rows;
7780 int is_active_h_edge = 0;
7781
7782 // For two pass account for any formatting bars detected.
7783 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07007784 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007785
7786 // The inactive region is specified in MBs not mi units.
7787 // The image edge is in the following MB row.
7788 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
7789
7790 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07007791 bottom_edge = AOMMAX(top_edge, bottom_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007792 }
7793
7794 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
7795 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
7796 is_active_h_edge = 1;
7797 }
7798 return is_active_h_edge;
7799}
7800
7801// Checks to see if a super block is on a vertical image edge.
7802// In most cases this is the "real" edge unless there are formatting
7803// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07007804int av1_active_v_edge(const AV1_COMP *cpi, int mi_col, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007805 int left_edge = 0;
7806 int right_edge = cpi->common.mi_cols;
7807 int is_active_v_edge = 0;
7808
7809 // For two pass account for any formatting bars detected.
7810 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07007811 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007812
7813 // The inactive region is specified in MBs not mi units.
7814 // The image edge is in the following MB row.
7815 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
7816
7817 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07007818 right_edge = AOMMAX(left_edge, right_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007819 }
7820
7821 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
7822 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
7823 is_active_v_edge = 1;
7824 }
7825 return is_active_v_edge;
7826}
7827
7828// Checks to see if a super block is at the edge of the active image.
7829// In most cases this is the "real" edge unless there are formatting
7830// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07007831int av1_active_edge_sb(const AV1_COMP *cpi, int mi_row, int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007832 return av1_active_h_edge(cpi, mi_row, cpi->common.mib_size) ||
7833 av1_active_v_edge(cpi, mi_col, cpi->common.mib_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007834}
7835
Urvang Joshib100db72016-10-12 16:28:56 -07007836#if CONFIG_PALETTE
Urvang Joshi52648442016-10-13 17:27:51 -07007837static void restore_uv_color_map(const AV1_COMP *const cpi, MACROBLOCK *x) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007838 MACROBLOCKD *const xd = &x->e_mbd;
7839 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7840 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
7841 const BLOCK_SIZE bsize = mbmi->sb_type;
7842 const int rows =
7843 (4 * num_4x4_blocks_high_lookup[bsize]) >> (xd->plane[1].subsampling_y);
7844 const int cols =
7845 (4 * num_4x4_blocks_wide_lookup[bsize]) >> (xd->plane[1].subsampling_x);
7846 int src_stride = x->plane[1].src.stride;
7847 const uint8_t *const src_u = x->plane[1].src.buf;
7848 const uint8_t *const src_v = x->plane[2].src.buf;
7849 float *const data = x->palette_buffer->kmeans_data_buf;
7850 float centroids[2 * PALETTE_MAX_SIZE];
7851 uint8_t *const color_map = xd->plane[1].color_index_map;
7852 int r, c;
Yaowu Xuf883b422016-08-30 14:01:10 -07007853#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007854 const uint16_t *const src_u16 = CONVERT_TO_SHORTPTR(src_u);
7855 const uint16_t *const src_v16 = CONVERT_TO_SHORTPTR(src_v);
Yaowu Xuf883b422016-08-30 14:01:10 -07007856#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007857 (void)cpi;
7858
7859 for (r = 0; r < rows; ++r) {
7860 for (c = 0; c < cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007861#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007862 if (cpi->common.use_highbitdepth) {
7863 data[(r * cols + c) * 2] = src_u16[r * src_stride + c];
7864 data[(r * cols + c) * 2 + 1] = src_v16[r * src_stride + c];
7865 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07007866#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007867 data[(r * cols + c) * 2] = src_u[r * src_stride + c];
7868 data[(r * cols + c) * 2 + 1] = src_v[r * src_stride + c];
Yaowu Xuf883b422016-08-30 14:01:10 -07007869#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007870 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007871#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007872 }
7873 }
7874
7875 for (r = 1; r < 3; ++r) {
7876 for (c = 0; c < pmi->palette_size[1]; ++c) {
7877 centroids[c * 2 + r - 1] = pmi->palette_colors[r * PALETTE_MAX_SIZE + c];
7878 }
7879 }
7880
Yaowu Xuf883b422016-08-30 14:01:10 -07007881 av1_calc_indices(data, centroids, color_map, rows * cols,
7882 pmi->palette_size[1], 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007883}
Urvang Joshib100db72016-10-12 16:28:56 -07007884#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007885
hui su5db97432016-10-14 16:10:14 -07007886#if CONFIG_FILTER_INTRA
7887static void pick_filter_intra_interframe(
7888 const AV1_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
Urvang Joshi52648442016-10-13 17:27:51 -07007889 BLOCK_SIZE bsize, int *rate_uv_intra, int *rate_uv_tokenonly,
7890 int64_t *dist_uv, int *skip_uv, PREDICTION_MODE *mode_uv,
hui su5db97432016-10-14 16:10:14 -07007891 FILTER_INTRA_MODE_INFO *filter_intra_mode_info_uv,
7892#if CONFIG_EXT_INTRA
7893 int8_t *uv_angle_delta,
7894#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07007895#if CONFIG_PALETTE
7896 PALETTE_MODE_INFO *pmi_uv, int palette_ctx,
7897#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007898 int skip_mask, unsigned int *ref_costs_single, int64_t *best_rd,
7899 int64_t *best_intra_rd, PREDICTION_MODE *best_intra_mode,
7900 int *best_mode_index, int *best_skip2, int *best_mode_skippable,
7901#if CONFIG_SUPERTX
7902 int *returnrate_nocoef,
7903#endif // CONFIG_SUPERTX
7904 int64_t *best_pred_rd, MB_MODE_INFO *best_mbmode, RD_COST *rd_cost) {
Urvang Joshi52648442016-10-13 17:27:51 -07007905 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007906 MACROBLOCKD *const xd = &x->e_mbd;
7907 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07007908#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007909 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07007910#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007911 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
7912 int rate2 = 0, rate_y = INT_MAX, skippable = 0, rate_uv, rate_dummy, i;
7913 int dc_mode_index;
7914 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
7915 int64_t distortion2 = 0, distortion_y = 0, this_rd = *best_rd, distortion_uv;
7916 TX_SIZE uv_tx;
7917
7918 for (i = 0; i < MAX_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07007919 if (av1_mode_order[i].mode == DC_PRED &&
7920 av1_mode_order[i].ref_frame[0] == INTRA_FRAME)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007921 break;
7922 dc_mode_index = i;
7923 assert(i < MAX_MODES);
7924
7925 // TODO(huisu): use skip_mask for further speedup.
7926 (void)skip_mask;
7927 mbmi->mode = DC_PRED;
7928 mbmi->uv_mode = DC_PRED;
7929 mbmi->ref_frame[0] = INTRA_FRAME;
7930 mbmi->ref_frame[1] = NONE;
hui su5db97432016-10-14 16:10:14 -07007931 if (!rd_pick_filter_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
7932 &skippable, bsize, intra_mode_cost[mbmi->mode],
7933 &this_rd, 0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007934 return;
hui su5db97432016-10-14 16:10:14 -07007935 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007936 if (rate_y == INT_MAX) return;
7937
Debargha Mukherjee2f123402016-08-30 17:43:38 -07007938 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
7939 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007940 if (rate_uv_intra[uv_tx] == INT_MAX) {
7941 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
7942 &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx],
7943 &skip_uv[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07007944#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007945 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07007946#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07007947 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
7948#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07007949 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui su5db97432016-10-14 16:10:14 -07007950#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07007951 }
7952
7953 rate_uv = rate_uv_tokenonly[uv_tx];
7954 distortion_uv = dist_uv[uv_tx];
7955 skippable = skippable && skip_uv[uv_tx];
7956 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07007957#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007958 if (cm->allow_screen_content_tools) {
7959 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
7960 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
7961 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
7962 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
7963 }
Urvang Joshib100db72016-10-12 16:28:56 -07007964#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07007965#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07007966 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui su5db97432016-10-14 16:10:14 -07007967#endif // CONFIG_EXT_INTRA
7968 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
7969 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
7970 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
7971 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
7972 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007973 }
7974
7975 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
7976 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07007977#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007978 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07007979 rate2 += av1_cost_bit(
7980 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07007981#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007982
7983 if (!xd->lossless[mbmi->segment_id]) {
7984 // super_block_yrd above includes the cost of the tx_size in the
7985 // tokenonly rate, but for intra blocks, tx_size is always coded
7986 // (prediction granularity), so we account for it in the full rate,
7987 // not the tokenonly rate.
clang-format67948d32016-09-07 22:40:40 -07007988 rate_y -= cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
Jingning Hanb0a71302016-10-25 16:28:49 -07007989 [tx_size_to_depth(mbmi->tx_size)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007990 }
7991
hui su5db97432016-10-14 16:10:14 -07007992 rate2 += av1_cost_bit(cm->fc->filter_intra_probs[0],
7993 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
7994 rate2 += write_uniform_cost(
7995 FILTER_INTRA_MODES, mbmi->filter_intra_mode_info.filter_intra_mode[0]);
7996#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07007997 if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
7998 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
7999 MAX_ANGLE_DELTAS + mbmi->angle_delta[1]);
8000 }
hui su5db97432016-10-14 16:10:14 -07008001#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008002 if (mbmi->mode == DC_PRED) {
hui su5db97432016-10-14 16:10:14 -07008003 rate2 +=
8004 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
8005 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
8006 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
8007 rate2 +=
8008 write_uniform_cost(FILTER_INTRA_MODES,
8009 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008010 }
8011 distortion2 = distortion_y + distortion_uv;
Angie Chiangff6d8902016-10-21 11:02:09 -07008012 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07008013#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008014 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008015 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008016 cpi, &xd->plane[0].dst, bsize, xd->bd);
8017 } else {
8018 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008019 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008020 }
8021#else
8022 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008023 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
8024#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008025
8026 rate2 += ref_costs_single[INTRA_FRAME];
8027
8028 if (skippable) {
8029 rate2 -= (rate_y + rate_uv);
8030 rate_y = 0;
8031 rate_uv = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07008032 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008033 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07008034 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008035 }
8036 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008037
8038 if (this_rd < *best_intra_rd) {
8039 *best_intra_rd = this_rd;
8040 *best_intra_mode = mbmi->mode;
8041 }
8042 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07008043 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008044
8045 if (this_rd < *best_rd) {
8046 *best_mode_index = dc_mode_index;
8047 mbmi->mv[0].as_int = 0;
8048 rd_cost->rate = rate2;
8049#if CONFIG_SUPERTX
8050 if (x->skip)
8051 *returnrate_nocoef = rate2;
8052 else
8053 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07008054 *returnrate_nocoef -= av1_cost_bit(av1_get_skip_prob(cm, xd), skippable);
8055 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
8056 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008057#endif // CONFIG_SUPERTX
8058 rd_cost->dist = distortion2;
8059 rd_cost->rdcost = this_rd;
8060 *best_rd = this_rd;
8061 *best_mbmode = *mbmi;
8062 *best_skip2 = 0;
8063 *best_mode_skippable = skippable;
8064 }
8065}
hui su5db97432016-10-14 16:10:14 -07008066#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008067
Yue Chencb60b182016-10-13 15:18:22 -07008068#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008069static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
8070 const MACROBLOCKD *xd, int mi_row,
8071 int mi_col, const uint8_t *above,
8072 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -07008073 int left_stride);
Yue Chencb60b182016-10-13 15:18:22 -07008074#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008075
Urvang Joshi52648442016-10-13 17:27:51 -07008076void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
Yaowu Xuf883b422016-08-30 14:01:10 -07008077 MACROBLOCK *x, int mi_row, int mi_col,
8078 RD_COST *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008079#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07008080 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008081#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07008082 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
8083 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07008084 const AV1_COMMON *const cm = &cpi->common;
8085 const RD_OPT *const rd_opt = &cpi->rd;
8086 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008087 MACROBLOCKD *const xd = &x->e_mbd;
8088 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008089#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008090 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07008091#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008092 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
8093 const struct segmentation *const seg = &cm->seg;
8094 PREDICTION_MODE this_mode;
8095 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
8096 unsigned char segment_id = mbmi->segment_id;
8097 int comp_pred, i, k;
8098 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8099 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
8100#if CONFIG_EXT_INTER
8101 int_mv single_newmvs[2][TOTAL_REFS_PER_FRAME] = { { { 0 } }, { { 0 } } };
8102 int single_newmvs_rate[2][TOTAL_REFS_PER_FRAME] = { { 0 }, { 0 } };
8103 int64_t modelled_rd[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8104#else
8105 int_mv single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
8106#endif // CONFIG_EXT_INTER
James Zern7b9407a2016-05-18 23:48:05 -07008107 InterpFilter single_inter_filter[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008108 int single_skippable[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8109 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
8110 0,
Yaowu Xuf883b422016-08-30 14:01:10 -07008111 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008112#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008113 AOM_LAST2_FLAG,
8114 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008115#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008116 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008117#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008118 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008119#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008120 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07008121 };
8122 int64_t best_rd = best_rd_so_far;
8123 int best_rate_y = INT_MAX, best_rate_uv = INT_MAX;
8124 int64_t best_pred_diff[REFERENCE_MODES];
8125 int64_t best_pred_rd[REFERENCE_MODES];
8126 MB_MODE_INFO best_mbmode;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07008127#if CONFIG_REF_MV
8128 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
8129 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8130#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008131 int best_mode_skippable = 0;
8132 int midx, best_mode_index = -1;
8133 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
8134 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -07008135 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008136 int64_t best_intra_rd = INT64_MAX;
8137 unsigned int best_pred_sse = UINT_MAX;
8138 PREDICTION_MODE best_intra_mode = DC_PRED;
8139 int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES];
Urvang Joshi368fbc92016-10-17 16:31:34 -07008140 int64_t dist_uvs[TX_SIZES];
8141 int skip_uvs[TX_SIZES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008142 PREDICTION_MODE mode_uv[TX_SIZES];
Urvang Joshib100db72016-10-12 16:28:56 -07008143#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008144 PALETTE_MODE_INFO pmi_uv[TX_SIZES];
Urvang Joshib100db72016-10-12 16:28:56 -07008145#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008146#if CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008147 int8_t uv_angle_delta[TX_SIZES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008148 int is_directional_mode, angle_stats_ready = 0;
8149 int rate_overhead, rate_dummy;
8150 uint8_t directional_mode_skip_mask[INTRA_MODES];
8151#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008152#if CONFIG_FILTER_INTRA
8153 int8_t dc_skipped = 1;
8154 FILTER_INTRA_MODE_INFO filter_intra_mode_info_uv[TX_SIZES];
8155#endif // CONFIG_FILTER_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07008156 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008157 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
8158 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
8159 int best_skip2 = 0;
8160 uint8_t ref_frame_skip_mask[2] = { 0 };
8161#if CONFIG_EXT_INTER
8162 uint32_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
8163 MV_REFERENCE_FRAME best_single_inter_ref = LAST_FRAME;
8164 int64_t best_single_inter_rd = INT64_MAX;
8165#else
8166 uint16_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
8167#endif // CONFIG_EXT_INTER
8168 int mode_skip_start = sf->mode_skip_start + 1;
8169 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
8170 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
8171 int64_t mode_threshold[MAX_MODES];
8172 int *mode_map = tile_data->mode_map[bsize];
8173 const int mode_search_skip_flags = sf->mode_search_skip_flags;
8174 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07008175#if CONFIG_PALETTE || CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008176 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
8177 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07008178#endif // CONFIG_PALETTE || CONFIG_EXT_INTRA
8179#if CONFIG_PALETTE
8180 int palette_ctx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008181 const MODE_INFO *above_mi = xd->above_mi;
8182 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshib100db72016-10-12 16:28:56 -07008183#endif // CONFIG_PALETTE
Yue Chencb60b182016-10-13 15:18:22 -07008184#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008185#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008186 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8187 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8188#else
8189 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
8190 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07008191#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008192 DECLARE_ALIGNED(16, int32_t, weighted_src_buf[MAX_SB_SQUARE]);
8193 DECLARE_ALIGNED(16, int32_t, mask2d_buf[MAX_SB_SQUARE]);
8194 uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
8195 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8196 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8197 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8198 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8199 int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8200 int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8201
Yaowu Xuf883b422016-08-30 14:01:10 -07008202#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008203 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
8204 int len = sizeof(uint16_t);
8205 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
8206 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
8207 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_SB_SQUARE * len);
8208 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
8209 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
8210 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_SB_SQUARE * len);
8211 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07008212#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008213 dst_buf1[0] = tmp_buf1;
8214 dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
8215 dst_buf1[2] = tmp_buf1 + 2 * MAX_SB_SQUARE;
8216 dst_buf2[0] = tmp_buf2;
8217 dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
8218 dst_buf2[2] = tmp_buf2 + 2 * MAX_SB_SQUARE;
Yaowu Xuf883b422016-08-30 14:01:10 -07008219#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008220 }
Yaowu Xuf883b422016-08-30 14:01:10 -07008221#endif // CONFIG_AOM_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07008222#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008223
Yaowu Xuf883b422016-08-30 14:01:10 -07008224 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008225
Urvang Joshib100db72016-10-12 16:28:56 -07008226#if CONFIG_PALETTE
8227 av1_zero(pmi_uv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008228 if (cm->allow_screen_content_tools) {
8229 if (above_mi)
8230 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
8231 if (left_mi)
8232 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
8233 }
Urvang Joshib100db72016-10-12 16:28:56 -07008234#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008235
8236#if CONFIG_EXT_INTRA
8237 memset(directional_mode_skip_mask, 0,
8238 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
8239#endif // CONFIG_EXT_INTRA
8240
8241 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
8242 &comp_mode_p);
8243
8244 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
8245 for (i = 0; i < TX_SIZES; i++) rate_uv_intra[i] = INT_MAX;
8246 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
8247 for (i = 0; i < MB_MODE_COUNT; ++i) {
8248 for (k = 0; k < TOTAL_REFS_PER_FRAME; ++k) {
8249 single_inter_filter[i][k] = SWITCHABLE;
8250 single_skippable[i][k] = 0;
8251 }
8252 }
8253
8254 rd_cost->rate = INT_MAX;
8255#if CONFIG_SUPERTX
8256 *returnrate_nocoef = INT_MAX;
8257#endif // CONFIG_SUPERTX
8258
8259 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
8260 x->pred_mv_sad[ref_frame] = INT_MAX;
8261 x->mbmi_ext->mode_context[ref_frame] = 0;
8262#if CONFIG_REF_MV && CONFIG_EXT_INTER
8263 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
8264#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
8265 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
8266 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
8267 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
8268 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
8269 }
8270 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkere5299862016-08-16 14:57:37 -07008271#if CONFIG_GLOBAL_MOTION
8272 frame_mv[ZEROMV][ref_frame].as_int =
8273 cm->global_motion[ref_frame].motion_params.wmmat[0].as_int;
8274#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008275 frame_mv[ZEROMV][ref_frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07008276#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008277#if CONFIG_EXT_INTER
8278 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
8279 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
8280 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
8281#endif // CONFIG_EXT_INTER
8282 }
8283
8284#if CONFIG_REF_MV
8285 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
8286 MODE_INFO *const mi = xd->mi[0];
8287 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
8288 x->mbmi_ext->mode_context[ref_frame] = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07008289 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
8290 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07008291#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008292 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008293#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008294 candidates, mi_row, mi_col, NULL, NULL,
8295 mbmi_ext->mode_context);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008296 }
8297#endif // CONFIG_REF_MV
8298
Yue Chencb60b182016-10-13 15:18:22 -07008299#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008300 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1,
8301 dst_width1, dst_height1, dst_stride1);
8302 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2,
8303 dst_width2, dst_height2, dst_stride2);
8304 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yue Chene9638cc2016-10-10 12:37:54 -07008305 x->mask_buf = mask2d_buf;
8306 x->wsrc_buf = weighted_src_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008307 calc_target_weighted_pred(cm, x, xd, mi_row, mi_col, dst_buf1[0],
Yue Chene9638cc2016-10-10 12:37:54 -07008308 dst_stride1[0], dst_buf2[0], dst_stride2[0]);
Yue Chencb60b182016-10-13 15:18:22 -07008309#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008310
8311 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
8312 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
8313// Skip checking missing references in both single and compound reference
8314// modes. Note that a mode will be skipped iff both reference frames
8315// are masked out.
8316#if CONFIG_EXT_REFS
8317 if (ref_frame == BWDREF_FRAME || ref_frame == ALTREF_FRAME) {
8318 ref_frame_skip_mask[0] |= (1 << ref_frame);
8319 ref_frame_skip_mask[1] |= ((1 << ref_frame) | 0x01);
8320 } else {
8321#endif // CONFIG_EXT_REFS
8322 ref_frame_skip_mask[0] |= (1 << ref_frame);
8323 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8324#if CONFIG_EXT_REFS
8325 }
8326#endif // CONFIG_EXT_REFS
8327 } else {
8328 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
8329 // Skip fixed mv modes for poor references
8330 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
8331 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
8332 break;
8333 }
8334 }
8335 }
8336 // If the segment reference frame feature is enabled....
8337 // then do nothing if the current ref frame is not allowed..
8338 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
8339 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
8340 ref_frame_skip_mask[0] |= (1 << ref_frame);
8341 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8342 }
8343 }
8344
8345 // Disable this drop out case if the ref frame
8346 // segment level feature is enabled for this segment. This is to
8347 // prevent the possibility that we end up unable to pick any mode.
8348 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
8349 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
8350 // unless ARNR filtering is enabled in which case we want
8351 // an unfiltered alternative. We allow near/nearest as well
8352 // because they may result in zero-zero MVs but be cheaper.
8353 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Sarah Parkere5299862016-08-16 14:57:37 -07008354 int_mv zeromv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008355 ref_frame_skip_mask[0] = (1 << LAST_FRAME) |
8356#if CONFIG_EXT_REFS
8357 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
8358 (1 << BWDREF_FRAME) |
8359#endif // CONFIG_EXT_REFS
8360 (1 << GOLDEN_FRAME);
8361 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
8362 // TODO(zoeliu): To further explore whether following needs to be done for
8363 // BWDREF_FRAME as well.
8364 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
Sarah Parkere5299862016-08-16 14:57:37 -07008365#if CONFIG_GLOBAL_MOTION
8366 zeromv.as_int =
8367 cm->global_motion[ALTREF_FRAME].motion_params.wmmat[0].as_int;
8368#else
8369 zeromv.as_int = 0;
8370#endif // CONFIG_GLOBAL_MOTION
8371 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008372 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008373 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008374 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
8375#if CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07008376 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008377 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008378 if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008379 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008380 if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008381 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008382 if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008383 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV);
8384#endif // CONFIG_EXT_INTER
8385 }
8386 }
8387
8388 if (cpi->rc.is_src_frame_alt_ref) {
8389 if (sf->alt_ref_search_fp) {
8390 assert(cpi->ref_frame_flags & flag_list[ALTREF_FRAME]);
8391 mode_skip_mask[ALTREF_FRAME] = 0;
8392 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
8393 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
8394 }
8395 }
8396
8397 if (sf->alt_ref_search_fp)
8398 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
8399 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
8400 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
8401
8402 if (sf->adaptive_mode_search) {
8403 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
8404 cpi->rc.frames_since_golden >= 3)
8405 if (x->pred_mv_sad[GOLDEN_FRAME] > (x->pred_mv_sad[LAST_FRAME] << 1))
8406 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
8407 }
8408
8409 if (bsize > sf->max_intra_bsize) {
8410 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
8411 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
8412 }
8413
8414 mode_skip_mask[INTRA_FRAME] |=
8415 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
8416
8417 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i) mode_threshold[i] = 0;
8418 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
8419 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
8420
8421 midx = sf->schedule_mode_search ? mode_skip_start : 0;
8422 while (midx > 4) {
8423 uint8_t end_pos = 0;
8424 for (i = 5; i < midx; ++i) {
8425 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
8426 uint8_t tmp = mode_map[i];
8427 mode_map[i] = mode_map[i - 1];
8428 mode_map[i - 1] = tmp;
8429 end_pos = i;
8430 }
8431 }
8432 midx = end_pos;
8433 }
8434
8435 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
8436 x->use_default_intra_tx_type = 1;
8437 else
8438 x->use_default_intra_tx_type = 0;
8439
8440 if (cpi->sf.tx_type_search.fast_inter_tx_type_search)
8441 x->use_default_inter_tx_type = 1;
8442 else
8443 x->use_default_inter_tx_type = 0;
8444
8445#if CONFIG_EXT_INTER
8446 for (i = 0; i < MB_MODE_COUNT; ++i)
8447 for (ref_frame = 0; ref_frame < TOTAL_REFS_PER_FRAME; ++ref_frame)
8448 modelled_rd[i][ref_frame] = INT64_MAX;
8449#endif // CONFIG_EXT_INTER
8450
8451 for (midx = 0; midx < MAX_MODES; ++midx) {
8452 int mode_index;
8453 int mode_excluded = 0;
8454 int64_t this_rd = INT64_MAX;
8455 int disable_skip = 0;
8456 int compmode_cost = 0;
8457#if CONFIG_EXT_INTER
8458 int compmode_interintra_cost = 0;
8459 int compmode_wedge_cost = 0;
8460#endif // CONFIG_EXT_INTER
8461 int rate2 = 0, rate_y = 0, rate_uv = 0;
8462 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
8463 int skippable = 0;
8464 int this_skip2 = 0;
8465 int64_t total_sse = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008466#if CONFIG_REF_MV
8467 uint8_t ref_frame_type;
8468#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008469 mode_index = mode_map[midx];
Yaowu Xuf883b422016-08-30 14:01:10 -07008470 this_mode = av1_mode_order[mode_index].mode;
8471 ref_frame = av1_mode_order[mode_index].ref_frame[0];
8472 second_ref_frame = av1_mode_order[mode_index].ref_frame[1];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07008473#if CONFIG_REF_MV
8474 mbmi->ref_mv_idx = 0;
8475#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008476
8477#if CONFIG_EXT_INTER
8478 if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
8479 // Mode must by compatible
8480 assert(is_interintra_allowed_mode(this_mode));
8481
8482 if (!is_interintra_allowed_bsize(bsize)) continue;
8483 }
8484
8485 if (is_inter_compound_mode(this_mode)) {
8486 frame_mv[this_mode][ref_frame].as_int =
8487 frame_mv[compound_ref0_mode(this_mode)][ref_frame].as_int;
8488 frame_mv[this_mode][second_ref_frame].as_int =
8489 frame_mv[compound_ref1_mode(this_mode)][second_ref_frame].as_int;
8490 }
8491#endif // CONFIG_EXT_INTER
8492
8493 // Look at the reference frame of the best mode so far and set the
8494 // skip mask to look at a subset of the remaining modes.
8495 if (midx == mode_skip_start && best_mode_index >= 0) {
8496 switch (best_mbmode.ref_frame[0]) {
8497 case INTRA_FRAME: break;
8498 case LAST_FRAME:
8499 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
8500 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8501 break;
8502#if CONFIG_EXT_REFS
8503 case LAST2_FRAME:
8504 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
8505 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8506 break;
8507 case LAST3_FRAME:
8508 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
8509 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8510 break;
8511#endif // CONFIG_EXT_REFS
8512 case GOLDEN_FRAME:
8513 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
8514 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8515 break;
8516#if CONFIG_EXT_REFS
8517 case BWDREF_FRAME:
8518 ref_frame_skip_mask[0] |= BWDREF_FRAME_MODE_MASK;
8519 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8520 break;
8521#endif // CONFIG_EXT_REFS
8522 case ALTREF_FRAME: ref_frame_skip_mask[0] |= ALTREF_FRAME_MODE_MASK;
8523#if CONFIG_EXT_REFS
8524 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8525#endif // CONFIG_EXT_REFS
8526 break;
8527 case NONE:
8528 case TOTAL_REFS_PER_FRAME:
8529 assert(0 && "Invalid Reference frame");
8530 break;
8531 }
8532 }
8533
8534 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -07008535 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -07008536 continue;
8537
8538 if (mode_skip_mask[ref_frame] & (1 << this_mode)) continue;
8539
8540 // Test best rd so far against threshold for trying this mode.
8541 if (best_mode_skippable && sf->schedule_mode_search)
8542 mode_threshold[mode_index] <<= 1;
8543
8544 if (best_rd < mode_threshold[mode_index]) continue;
8545
8546 comp_pred = second_ref_frame > INTRA_FRAME;
8547 if (comp_pred) {
8548 if (!cpi->allow_comp_inter_inter) continue;
8549
8550 // Skip compound inter modes if ARF is not available.
8551 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
8552
8553 // Do not allow compound prediction if the segment level reference frame
8554 // feature is in use as in this case there can only be one reference.
8555 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
8556
8557 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
8558 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
8559 continue;
8560
8561 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
8562 } else {
8563 if (ref_frame != INTRA_FRAME)
8564 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
8565 }
8566
8567 if (ref_frame == INTRA_FRAME) {
8568 if (sf->adaptive_mode_search)
8569 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
8570 continue;
8571
8572 if (this_mode != DC_PRED) {
8573 // Disable intra modes other than DC_PRED for blocks with low variance
8574 // Threshold for intra skipping based on source variance
8575 // TODO(debargha): Specialize the threshold for super block sizes
8576 const unsigned int skip_intra_var_thresh = 64;
8577 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
8578 x->source_variance < skip_intra_var_thresh)
8579 continue;
8580 // Only search the oblique modes if the best so far is
8581 // one of the neighboring directional modes
8582 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
8583 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
8584 if (best_mode_index >= 0 && best_mbmode.ref_frame[0] > INTRA_FRAME)
8585 continue;
8586 }
8587 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
8588 if (conditional_skipintra(this_mode, best_intra_mode)) continue;
8589 }
8590 }
Sarah Parkere5299862016-08-16 14:57:37 -07008591#if CONFIG_GLOBAL_MOTION
8592 } else if (get_gmtype(&cm->global_motion[ref_frame]) == GLOBAL_ZERO &&
8593 (!comp_pred ||
8594 get_gmtype(&cm->global_motion[second_ref_frame]) ==
8595 GLOBAL_ZERO)) {
8596#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008597 } else {
Sarah Parkere5299862016-08-16 14:57:37 -07008598#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008599 const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame };
8600 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
8601#if CONFIG_REF_MV && CONFIG_EXT_INTER
8602 mbmi_ext->compound_mode_context,
8603#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
8604 frame_mv, this_mode, ref_frames, bsize, -1))
8605 continue;
8606 }
8607
8608 mbmi->mode = this_mode;
8609 mbmi->uv_mode = DC_PRED;
8610 mbmi->ref_frame[0] = ref_frame;
8611 mbmi->ref_frame[1] = second_ref_frame;
Urvang Joshib100db72016-10-12 16:28:56 -07008612#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008613 pmi->palette_size[0] = 0;
8614 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07008615#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07008616#if CONFIG_FILTER_INTRA
8617 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
8618 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
8619#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008620 // Evaluate all sub-pel filters irrespective of whether we can use
8621 // them for this frame.
8622#if CONFIG_DUAL_FILTER
8623 for (i = 0; i < 4; ++i) {
8624 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
8625 ? EIGHTTAP_REGULAR
8626 : cm->interp_filter;
8627 }
8628#else
8629 mbmi->interp_filter =
8630 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
8631#endif
8632 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chencb60b182016-10-13 15:18:22 -07008633 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008634
8635 x->skip = 0;
8636 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
8637
8638 // Select prediction reference frames.
8639 for (i = 0; i < MAX_MB_PLANE; i++) {
8640 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
8641 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
8642 }
8643
8644#if CONFIG_EXT_INTER
Debargha Mukherjeecb603792016-10-04 13:10:23 -07008645 mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008646#endif // CONFIG_EXT_INTER
8647
8648 if (ref_frame == INTRA_FRAME) {
8649 TX_SIZE uv_tx;
8650 struct macroblockd_plane *const pd = &xd->plane[1];
8651#if CONFIG_EXT_INTRA
8652 is_directional_mode = (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED);
8653 if (is_directional_mode) {
8654 if (!angle_stats_ready) {
8655 const int src_stride = x->plane[0].src.stride;
8656 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuf883b422016-08-30 14:01:10 -07008657#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008658 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
8659 highbd_angle_estimation(src, src_stride, rows, cols,
8660 directional_mode_skip_mask);
8661 else
8662#endif
8663 angle_estimation(src, src_stride, rows, cols,
8664 directional_mode_skip_mask);
8665 angle_stats_ready = 1;
8666 }
8667 if (directional_mode_skip_mask[mbmi->mode]) continue;
8668 rate_overhead = write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0) +
8669 intra_mode_cost[mbmi->mode];
8670 rate_y = INT_MAX;
8671 this_rd =
8672 rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
8673 &skippable, bsize, rate_overhead, best_rd);
8674 } else {
8675 mbmi->angle_delta[0] = 0;
8676 super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable, NULL, bsize,
8677 best_rd);
8678 }
8679#else
8680 super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable, NULL, bsize,
8681 best_rd);
8682#endif // CONFIG_EXT_INTRA
8683
8684 if (rate_y == INT_MAX) continue;
8685
hui su5db97432016-10-14 16:10:14 -07008686#if CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008687 if (mbmi->mode == DC_PRED) dc_skipped = 0;
hui su5db97432016-10-14 16:10:14 -07008688#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008689
Debargha Mukherjee2f123402016-08-30 17:43:38 -07008690 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][pd->subsampling_x]
8691 [pd->subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008692 if (rate_uv_intra[uv_tx] == INT_MAX) {
8693 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -07008694 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
8695 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07008696#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008697 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008698#endif // CONFIG_PALETTE
8699
Yaowu Xuc27fc142016-08-22 16:08:15 -07008700#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008701 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
8702#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008703#if CONFIG_FILTER_INTRA
8704 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
8705#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008706 }
8707
8708 rate_uv = rate_uv_tokenonly[uv_tx];
Urvang Joshi368fbc92016-10-17 16:31:34 -07008709 distortion_uv = dist_uvs[uv_tx];
8710 skippable = skippable && skip_uvs[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008711 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07008712#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008713 if (cm->allow_screen_content_tools) {
8714 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
8715 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
8716 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
8717 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
8718 }
Urvang Joshib100db72016-10-12 16:28:56 -07008719#endif // CONFIG_PALETTE
8720
Yaowu Xuc27fc142016-08-22 16:08:15 -07008721#if CONFIG_EXT_INTRA
8722 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008723#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008724#if CONFIG_FILTER_INTRA
8725 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
8726 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
8727 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
8728 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
8729 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
8730 }
8731#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008732
8733 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
8734 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07008735#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008736 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07008737 rate2 += av1_cost_bit(
8738 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07008739#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008740
8741 if (!xd->lossless[mbmi->segment_id]) {
8742 // super_block_yrd above includes the cost of the tx_size in the
8743 // tokenonly rate, but for intra blocks, tx_size is always coded
8744 // (prediction granularity), so we account for it in the full rate,
8745 // not the tokenonly rate.
Jingning Hanb0a71302016-10-25 16:28:49 -07008746 rate_y -=
8747 cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
8748 [tx_size_to_depth(mbmi->tx_size)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008749 }
8750#if CONFIG_EXT_INTRA
8751 if (is_directional_mode) {
8752 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07008753 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008754 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
8755 MAX_ANGLE_DELTAS + mbmi->angle_delta[0]);
8756 p_angle =
8757 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07008758 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07008759 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
8760 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008761 if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
8762 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
8763 MAX_ANGLE_DELTAS + mbmi->angle_delta[1]);
8764 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008765#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008766#if CONFIG_FILTER_INTRA
8767 if (mbmi->mode == DC_PRED) {
8768 rate2 +=
8769 av1_cost_bit(cm->fc->filter_intra_probs[0],
8770 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
8771 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
8772 rate2 += write_uniform_cost(
8773 FILTER_INTRA_MODES,
8774 mbmi->filter_intra_mode_info.filter_intra_mode[0]);
8775 }
8776 }
8777 if (mbmi->uv_mode == DC_PRED) {
8778 rate2 +=
8779 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
8780 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
8781 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
8782 rate2 += write_uniform_cost(
8783 FILTER_INTRA_MODES,
8784 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
8785 }
8786#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008787 if (this_mode != DC_PRED && this_mode != TM_PRED)
8788 rate2 += intra_cost_penalty;
8789 distortion2 = distortion_y + distortion_uv;
Angie Chiangff6d8902016-10-21 11:02:09 -07008790 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 1);
Yaowu Xuf883b422016-08-30 14:01:10 -07008791#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008792 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008793 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008794 cpi, &xd->plane[0].dst, bsize, xd->bd);
8795 } else {
8796 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008797 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008798 }
8799#else
8800 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008801 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
8802#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008803 } else {
8804#if CONFIG_REF_MV
8805 int_mv backup_ref_mv[2];
8806
8807 backup_ref_mv[0] = mbmi_ext->ref_mvs[ref_frame][0];
8808 if (comp_pred) backup_ref_mv[1] = mbmi_ext->ref_mvs[second_ref_frame][0];
8809#endif
8810#if CONFIG_EXT_INTER
8811 if (second_ref_frame == INTRA_FRAME) {
8812 if (best_single_inter_ref != ref_frame) continue;
Debargha Mukherjeecb603792016-10-04 13:10:23 -07008813 mbmi->interintra_mode = intra_to_interintra_mode[best_intra_mode];
hui su5db97432016-10-14 16:10:14 -07008814// TODO(debargha|geza.lore):
8815// Should we use ext_intra modes for interintra?
Yaowu Xuc27fc142016-08-22 16:08:15 -07008816#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008817 mbmi->angle_delta[0] = 0;
8818 mbmi->angle_delta[1] = 0;
8819 mbmi->intra_filter = INTRA_FILTER_LINEAR;
8820#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008821#if CONFIG_FILTER_INTRA
8822 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
8823 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
8824#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008825 }
8826#endif // CONFIG_EXT_INTER
8827#if CONFIG_REF_MV
8828 mbmi->ref_mv_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07008829 ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008830
8831 if (this_mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
8832 int ref;
8833 for (ref = 0; ref < 1 + comp_pred; ++ref) {
8834 int_mv this_mv =
8835 (ref == 0) ? mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv
8836 : mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
8837 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << 3, xd->n8_h << 3, xd);
8838 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
8839 }
8840 }
8841#endif
8842 this_rd = handle_inter_mode(
8843 cpi, x, bsize, &rate2, &distortion2, &skippable, &rate_y, &rate_uv,
8844 &disable_skip, frame_mv, mi_row, mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07008845#if CONFIG_MOTION_VAR
Yue Chene9638cc2016-10-10 12:37:54 -07008846 dst_buf1, dst_stride1, dst_buf2, dst_stride2,
Yue Chencb60b182016-10-13 15:18:22 -07008847#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008848#if CONFIG_EXT_INTER
8849 single_newmvs, single_newmvs_rate, &compmode_interintra_cost,
8850 &compmode_wedge_cost, modelled_rd,
8851#else
8852 single_newmv,
8853#endif // CONFIG_EXT_INTER
8854 single_inter_filter, single_skippable, &total_sse, best_rd);
8855
8856#if CONFIG_REF_MV
8857 // TODO(jingning): This needs some refactoring to improve code quality
8858 // and reduce redundant steps.
8859 if ((mbmi->mode == NEARMV &&
8860 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
8861 (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
8862 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
8863 MB_MODE_INFO backup_mbmi = *mbmi;
8864 int backup_skip = x->skip;
8865 int64_t tmp_ref_rd = this_rd;
8866 int ref_idx;
8867
8868 // TODO(jingning): This should be deprecated shortly.
8869 int idx_offset = (mbmi->mode == NEARMV) ? 1 : 0;
8870 int ref_set =
Yaowu Xuf883b422016-08-30 14:01:10 -07008871 AOMMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 1 - idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008872
8873 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07008874 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008875 // Dummy
8876 int_mv backup_fmv[2];
8877 backup_fmv[0] = frame_mv[NEWMV][ref_frame];
8878 if (comp_pred) backup_fmv[1] = frame_mv[NEWMV][second_ref_frame];
8879
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07008880 rate2 += (rate2 < INT_MAX ? cpi->drl_mode_cost0[drl_ctx][0] : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008881
8882 if (this_rd < INT64_MAX) {
8883 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
8884 RDCOST(x->rdmult, x->rddiv, 0, total_sse))
8885 tmp_ref_rd =
8886 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -07008887 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Yaowu Xuc27fc142016-08-22 16:08:15 -07008888 distortion2);
8889 else
8890 tmp_ref_rd =
8891 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -07008892 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
Yaowu Xuc27fc142016-08-22 16:08:15 -07008893 rate_y - rate_uv,
8894 total_sse);
8895 }
8896#if CONFIG_VAR_TX
8897 for (i = 0; i < MAX_MB_PLANE; ++i)
8898 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
8899 sizeof(uint8_t) * ctx->num_4x4_blk);
8900#endif
8901
8902 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
8903 int64_t tmp_alt_rd = INT64_MAX;
8904 int tmp_rate = 0, tmp_rate_y = 0, tmp_rate_uv = 0;
8905 int tmp_skip = 1;
8906 int64_t tmp_dist = 0, tmp_sse = 0;
8907 int dummy_disable_skip = 0;
8908 int ref;
8909 int_mv cur_mv;
8910
8911 mbmi->ref_mv_idx = 1 + ref_idx;
8912
8913 for (ref = 0; ref < 1 + comp_pred; ++ref) {
8914 int_mv this_mv =
8915 (ref == 0)
8916 ? mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
8917 .this_mv
8918 : mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
8919 .comp_mv;
8920 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << 3, xd->n8_h << 3, xd);
8921 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
8922 }
8923
8924 cur_mv =
8925 mbmi_ext->ref_mv_stack[ref_frame][mbmi->ref_mv_idx + idx_offset]
8926 .this_mv;
8927 clamp_mv2(&cur_mv.as_mv, xd);
8928
8929 if (!mv_check_bounds(x, &cur_mv.as_mv)) {
clang-format67948d32016-09-07 22:40:40 -07008930 int dummy_single_skippable[MB_MODE_COUNT]
8931 [TOTAL_REFS_PER_FRAME] = { { 0 } };
Yaowu Xuc27fc142016-08-22 16:08:15 -07008932#if CONFIG_EXT_INTER
8933 int_mv dummy_single_newmvs[2][TOTAL_REFS_PER_FRAME] = { { { 0 } },
8934 { { 0 } } };
8935 int dummy_single_newmvs_rate[2][TOTAL_REFS_PER_FRAME] = { { 0 },
8936 { 0 } };
8937 int dummy_compmode_interintra_cost = 0;
8938 int dummy_compmode_wedge_cost = 0;
8939#else
8940 int_mv dummy_single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
8941#endif
8942
8943 frame_mv[NEARMV][ref_frame] = cur_mv;
8944 tmp_alt_rd = handle_inter_mode(
8945 cpi, x, bsize, &tmp_rate, &tmp_dist, &tmp_skip, &tmp_rate_y,
8946 &tmp_rate_uv, &dummy_disable_skip, frame_mv, mi_row, mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07008947#if CONFIG_MOTION_VAR
Yue Chene9638cc2016-10-10 12:37:54 -07008948 dst_buf1, dst_stride1, dst_buf2, dst_stride2,
Yue Chencb60b182016-10-13 15:18:22 -07008949#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008950#if CONFIG_EXT_INTER
8951 dummy_single_newmvs, dummy_single_newmvs_rate,
8952 &dummy_compmode_interintra_cost, &dummy_compmode_wedge_cost,
8953 NULL,
8954#else
8955 dummy_single_newmv,
8956#endif
Jingning Han72120962016-10-24 09:32:41 -07008957 single_inter_filter, dummy_single_skippable, &tmp_sse, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008958 }
8959
8960 for (i = 0; i < mbmi->ref_mv_idx; ++i) {
8961 uint8_t drl1_ctx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07008962 drl1_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
8963 i + idx_offset);
Yi Luoe8e8cd82016-09-21 10:45:01 -07008964 tmp_rate +=
8965 (tmp_rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][1] : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008966 }
8967
8968 if (mbmi_ext->ref_mv_count[ref_frame_type] >
8969 mbmi->ref_mv_idx + idx_offset + 1 &&
8970 ref_idx < ref_set - 1) {
8971 uint8_t drl1_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07008972 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
8973 mbmi->ref_mv_idx + idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008974 tmp_rate += cpi->drl_mode_cost0[drl1_ctx][0];
8975 }
8976
8977 if (tmp_alt_rd < INT64_MAX) {
Yue Chencb60b182016-10-13 15:18:22 -07008978#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008979 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv, tmp_rate, tmp_dist);
8980#else
8981 if (RDCOST(x->rdmult, x->rddiv, tmp_rate_y + tmp_rate_uv,
8982 tmp_dist) < RDCOST(x->rdmult, x->rddiv, 0, tmp_sse))
Yaowu Xuf883b422016-08-30 14:01:10 -07008983 tmp_alt_rd =
8984 RDCOST(x->rdmult, x->rddiv,
8985 tmp_rate + av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
8986 tmp_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008987 else
Yaowu Xuf883b422016-08-30 14:01:10 -07008988 tmp_alt_rd =
8989 RDCOST(x->rdmult, x->rddiv,
8990 tmp_rate + av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
8991 tmp_rate_y - tmp_rate_uv,
8992 tmp_sse);
Yue Chencb60b182016-10-13 15:18:22 -07008993#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008994 }
8995
8996 if (tmp_ref_rd > tmp_alt_rd) {
8997 rate2 = tmp_rate;
8998 disable_skip = dummy_disable_skip;
8999 distortion2 = tmp_dist;
9000 skippable = tmp_skip;
9001 rate_y = tmp_rate_y;
9002 rate_uv = tmp_rate_uv;
9003 total_sse = tmp_sse;
9004 this_rd = tmp_alt_rd;
9005 tmp_ref_rd = tmp_alt_rd;
9006 backup_mbmi = *mbmi;
9007 backup_skip = x->skip;
9008#if CONFIG_VAR_TX
9009 for (i = 0; i < MAX_MB_PLANE; ++i)
9010 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
9011 sizeof(uint8_t) * ctx->num_4x4_blk);
9012#endif
9013 } else {
9014 *mbmi = backup_mbmi;
9015 x->skip = backup_skip;
9016 }
9017 }
9018
9019 frame_mv[NEARMV][ref_frame] = backup_mv;
9020 frame_mv[NEWMV][ref_frame] = backup_fmv[0];
9021 if (comp_pred) frame_mv[NEWMV][second_ref_frame] = backup_fmv[1];
9022#if CONFIG_VAR_TX
9023 for (i = 0; i < MAX_MB_PLANE; ++i)
9024 memcpy(x->blk_skip[i], x->blk_skip_drl[i],
9025 sizeof(uint8_t) * ctx->num_4x4_blk);
9026#endif
9027 }
9028 mbmi_ext->ref_mvs[ref_frame][0] = backup_ref_mv[0];
9029 if (comp_pred) mbmi_ext->ref_mvs[second_ref_frame][0] = backup_ref_mv[1];
9030#endif // CONFIG_REF_MV
9031
9032 if (this_rd == INT64_MAX) continue;
9033
Yaowu Xuf883b422016-08-30 14:01:10 -07009034 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009035
9036 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
9037 }
9038
9039#if CONFIG_EXT_INTER
9040 rate2 += compmode_interintra_cost;
9041 if (cm->reference_mode != SINGLE_REFERENCE && comp_pred)
Yue Chencb60b182016-10-13 15:18:22 -07009042#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
9043 if (mbmi->motion_mode == SIMPLE_TRANSLATION)
9044#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009045 rate2 += compmode_wedge_cost;
9046#endif // CONFIG_EXT_INTER
9047
9048 // Estimate the reference frame signaling cost and add it
9049 // to the rolling cost variable.
9050 if (comp_pred) {
9051 rate2 += ref_costs_comp[ref_frame];
9052#if CONFIG_EXT_REFS
9053 rate2 += ref_costs_comp[second_ref_frame];
9054#endif // CONFIG_EXT_REFS
9055 } else {
9056 rate2 += ref_costs_single[ref_frame];
9057 }
9058
Yue Chencb60b182016-10-13 15:18:22 -07009059#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009060 if (ref_frame == INTRA_FRAME) {
9061#else
9062 if (!disable_skip) {
Yue Chencb60b182016-10-13 15:18:22 -07009063#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009064 if (skippable) {
9065 // Back out the coefficient coding costs
9066 rate2 -= (rate_y + rate_uv);
9067 rate_y = 0;
9068 rate_uv = 0;
9069 // Cost the skip mb case
Yaowu Xuf883b422016-08-30 14:01:10 -07009070 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009071 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009072#if CONFIG_REF_MV
9073 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv + rate_skip0,
9074 distortion2) <
9075 RDCOST(x->rdmult, x->rddiv, rate_skip1, total_sse)) {
9076#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009077 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
9078 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009079#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009080 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -07009081 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009082 } else {
9083 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -07009084 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009085 distortion2 = total_sse;
9086 assert(total_sse >= 0);
9087 rate2 -= (rate_y + rate_uv);
9088 this_skip2 = 1;
9089 rate_y = 0;
9090 rate_uv = 0;
9091 }
9092 } else {
9093 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -07009094 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009095 }
9096
9097 // Calculate the final RD estimate for this mode.
9098 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yue Chencb60b182016-10-13 15:18:22 -07009099#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009100 } else {
9101 this_skip2 = mbmi->skip;
9102 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
9103 if (this_skip2) {
9104 rate_y = 0;
9105 rate_uv = 0;
9106 }
Yue Chencb60b182016-10-13 15:18:22 -07009107#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009108 }
9109
Yaowu Xuc27fc142016-08-22 16:08:15 -07009110 if (ref_frame == INTRA_FRAME) {
9111 // Keep record of best intra rd
9112 if (this_rd < best_intra_rd) {
9113 best_intra_rd = this_rd;
9114 best_intra_mode = mbmi->mode;
9115 }
9116#if CONFIG_EXT_INTER
9117 } else if (second_ref_frame == NONE) {
9118 if (this_rd < best_single_inter_rd) {
9119 best_single_inter_rd = this_rd;
9120 best_single_inter_ref = mbmi->ref_frame[0];
9121 }
9122#endif // CONFIG_EXT_INTER
9123 }
9124
9125 if (!disable_skip && ref_frame == INTRA_FRAME) {
9126 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009127 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009128 }
9129
9130 // Did this mode help.. i.e. is it the new best mode
9131 if (this_rd < best_rd || x->skip) {
9132 if (!mode_excluded) {
9133 // Note index of best mode so far
9134 best_mode_index = mode_index;
9135
9136 if (ref_frame == INTRA_FRAME) {
9137 /* required for left and above block mv */
9138 mbmi->mv[0].as_int = 0;
9139 } else {
9140 best_pred_sse = x->pred_sse[ref_frame];
9141 }
9142
9143 rd_cost->rate = rate2;
9144#if CONFIG_SUPERTX
9145 if (x->skip)
9146 *returnrate_nocoef = rate2;
9147 else
9148 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07009149 *returnrate_nocoef -= av1_cost_bit(
9150 av1_get_skip_prob(cm, xd), disable_skip || skippable || this_skip2);
9151 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
9152 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chencb60b182016-10-13 15:18:22 -07009153#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
9154 if (is_inter_block(mbmi) && is_motion_variation_allowed(mbmi))
9155 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
9156#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009157#endif // CONFIG_SUPERTX
9158 rd_cost->dist = distortion2;
9159 rd_cost->rdcost = this_rd;
9160 best_rd = this_rd;
9161 best_mbmode = *mbmi;
9162 best_skip2 = this_skip2;
9163 best_mode_skippable = skippable;
Yaowu Xuf883b422016-08-30 14:01:10 -07009164 best_rate_y = rate_y + av1_cost_bit(av1_get_skip_prob(cm, xd),
9165 this_skip2 || skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009166 best_rate_uv = rate_uv;
9167
9168#if CONFIG_VAR_TX
9169 for (i = 0; i < MAX_MB_PLANE; ++i)
9170 memcpy(ctx->blk_skip[i], x->blk_skip[i],
9171 sizeof(uint8_t) * ctx->num_4x4_blk);
9172#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009173 }
9174 }
9175
9176 /* keep record of best compound/single-only prediction */
9177 if (!disable_skip && ref_frame != INTRA_FRAME) {
9178 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
9179
9180 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
9181 single_rate = rate2 - compmode_cost;
9182 hybrid_rate = rate2;
9183 } else {
9184 single_rate = rate2;
9185 hybrid_rate = rate2 + compmode_cost;
9186 }
9187
9188 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
9189 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
9190
9191 if (!comp_pred) {
9192 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
9193 best_pred_rd[SINGLE_REFERENCE] = single_rd;
9194 } else {
9195 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
9196 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
9197 }
9198 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
9199 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
9200 }
9201
Yaowu Xuc27fc142016-08-22 16:08:15 -07009202 if (x->skip && !comp_pred) break;
9203 }
9204
9205 if (xd->lossless[mbmi->segment_id] == 0 && best_mode_index >= 0 &&
9206 ((sf->tx_type_search.fast_inter_tx_type_search == 1 &&
9207 is_inter_mode(best_mbmode.mode)) ||
9208 (sf->tx_type_search.fast_intra_tx_type_search == 1 &&
9209 !is_inter_mode(best_mbmode.mode)))) {
9210 int rate_y = 0, rate_uv = 0;
9211 int64_t dist_y = 0, dist_uv = 0;
9212 int skip_y = 0, skip_uv = 0, skip_blk = 0;
9213 int64_t sse_y = 0, sse_uv = 0;
9214
9215 x->use_default_inter_tx_type = 0;
9216 x->use_default_intra_tx_type = 0;
9217
9218 *mbmi = best_mbmode;
9219
9220 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
9221
9222 // Select prediction reference frames.
9223 for (i = 0; i < MAX_MB_PLANE; i++) {
9224 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
9225 if (has_second_ref(mbmi))
9226 xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
9227 }
9228
9229 if (is_inter_mode(mbmi->mode)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009230 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yue Chencb60b182016-10-13 15:18:22 -07009231#if CONFIG_MOTION_VAR
9232 if (mbmi->motion_mode == OBMC_CAUSAL)
Yaowu Xuf883b422016-08-30 14:01:10 -07009233 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1,
9234 dst_stride1, dst_buf2, dst_stride2);
Yue Chencb60b182016-10-13 15:18:22 -07009235#endif // CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009236 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009237#if CONFIG_VAR_TX
9238 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
9239 select_tx_type_yrd(cpi, x, &rate_y, &dist_y, &skip_y, &sse_y, bsize,
9240 INT64_MAX);
9241 } else {
9242 int idx, idy;
9243 super_block_yrd(cpi, x, &rate_y, &dist_y, &skip_y, &sse_y, bsize,
9244 INT64_MAX);
9245 for (idy = 0; idy < xd->n8_h; ++idy)
9246 for (idx = 0; idx < xd->n8_w; ++idx)
9247 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
9248 memset(x->blk_skip[0], skip_y,
9249 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
9250 }
9251
9252 inter_block_uvrd(cpi, x, &rate_uv, &dist_uv, &skip_uv, &sse_uv, bsize,
9253 INT64_MAX);
9254#else
9255 super_block_yrd(cpi, x, &rate_y, &dist_y, &skip_y, &sse_y, bsize,
9256 INT64_MAX);
9257 super_block_uvrd(cpi, x, &rate_uv, &dist_uv, &skip_uv, &sse_uv, bsize,
9258 INT64_MAX);
9259#endif // CONFIG_VAR_TX
9260 } else {
9261 super_block_yrd(cpi, x, &rate_y, &dist_y, &skip_y, &sse_y, bsize,
9262 INT64_MAX);
9263 super_block_uvrd(cpi, x, &rate_uv, &dist_uv, &skip_uv, &sse_uv, bsize,
9264 INT64_MAX);
9265 }
9266
9267 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, (dist_y + dist_uv)) >
9268 RDCOST(x->rdmult, x->rddiv, 0, (sse_y + sse_uv))) {
9269 skip_blk = 1;
Yaowu Xuf883b422016-08-30 14:01:10 -07009270 rate_y = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009271 rate_uv = 0;
9272 dist_y = sse_y;
9273 dist_uv = sse_uv;
9274 } else {
9275 skip_blk = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009276 rate_y += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009277 }
9278
9279 if (RDCOST(x->rdmult, x->rddiv, best_rate_y + best_rate_uv, rd_cost->dist) >
9280 RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, (dist_y + dist_uv))) {
9281#if CONFIG_VAR_TX
9282 int idx, idy;
9283#endif
9284 best_mbmode.tx_type = mbmi->tx_type;
9285 best_mbmode.tx_size = mbmi->tx_size;
9286#if CONFIG_VAR_TX
9287 for (idy = 0; idy < xd->n8_h; ++idy)
9288 for (idx = 0; idx < xd->n8_w; ++idx)
9289 best_mbmode.inter_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
9290
9291 for (i = 0; i < MAX_MB_PLANE; ++i)
9292 memcpy(ctx->blk_skip[i], x->blk_skip[i],
9293 sizeof(uint8_t) * ctx->num_4x4_blk);
9294#endif
9295 rd_cost->rate += (rate_y + rate_uv - best_rate_y - best_rate_uv);
9296 rd_cost->dist = dist_y + dist_uv;
9297 rd_cost->rdcost =
9298 RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
9299 best_skip2 = skip_blk;
9300 }
9301 }
9302
Urvang Joshib100db72016-10-12 16:28:56 -07009303#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009304 // Only try palette mode when the best mode so far is an intra mode.
9305 if (cm->allow_screen_content_tools && !is_inter_mode(best_mbmode.mode)) {
9306 PREDICTION_MODE mode_selected;
9307 int rate2 = 0, rate_y = 0;
9308#if CONFIG_SUPERTX
9309 int best_rate_nocoef;
9310#endif
9311 int64_t distortion2 = 0, distortion_y = 0, dummy_rd = best_rd, this_rd;
Urvang Joshi626591d2016-10-24 14:13:55 -07009312 int skippable = 0, rate_overhead_palette = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009313 TX_SIZE best_tx_size, uv_tx;
9314 TX_TYPE best_tx_type;
9315 PALETTE_MODE_INFO palette_mode_info;
9316 uint8_t *const best_palette_color_map =
9317 x->palette_buffer->best_palette_color_map;
9318 uint8_t *const color_map = xd->plane[0].color_index_map;
9319
9320 mbmi->mode = DC_PRED;
9321 mbmi->uv_mode = DC_PRED;
9322 mbmi->ref_frame[0] = INTRA_FRAME;
9323 mbmi->ref_frame[1] = NONE;
9324 palette_mode_info.palette_size[0] = 0;
Urvang Joshi626591d2016-10-24 14:13:55 -07009325 rate_overhead_palette = rd_pick_palette_intra_sby(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009326 cpi, x, bsize, palette_ctx, intra_mode_cost[DC_PRED],
9327 &palette_mode_info, best_palette_color_map, &best_tx_size,
9328 &best_tx_type, &mode_selected, &dummy_rd);
9329 if (palette_mode_info.palette_size[0] == 0) goto PALETTE_EXIT;
9330
9331 pmi->palette_size[0] = palette_mode_info.palette_size[0];
9332 if (palette_mode_info.palette_size[0] > 0) {
9333 memcpy(pmi->palette_colors, palette_mode_info.palette_colors,
9334 PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
9335 memcpy(color_map, best_palette_color_map,
9336 rows * cols * sizeof(best_palette_color_map[0]));
9337 }
9338 super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable, NULL, bsize,
9339 best_rd);
9340 if (rate_y == INT_MAX) goto PALETTE_EXIT;
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009341 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
9342 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009343 if (rate_uv_intra[uv_tx] == INT_MAX) {
9344 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -07009345 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
9346 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009347 pmi_uv[uv_tx] = *pmi;
9348#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009349 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
9350#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009351#if CONFIG_FILTER_INTRA
9352 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9353#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009354 }
9355 mbmi->uv_mode = mode_uv[uv_tx];
9356 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9357 if (pmi->palette_size[1] > 0)
9358 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9359 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9360 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9361#if CONFIG_EXT_INTRA
9362 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009363#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009364#if CONFIG_FILTER_INTRA
9365 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9366 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9367 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9368 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9369 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
9370 }
9371#endif // CONFIG_FILTER_INTRA
Yaowu Xuc287e272016-10-20 18:19:16 -07009372 skippable = skippable && skip_uvs[uv_tx];
9373 distortion2 = distortion_y + dist_uvs[uv_tx];
Urvang Joshi626591d2016-10-24 14:13:55 -07009374 rate2 = rate_y + rate_overhead_palette + rate_uv_intra[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009375 rate2 += ref_costs_single[INTRA_FRAME];
9376
9377 if (skippable) {
9378 rate2 -= (rate_y + rate_uv_tokenonly[uv_tx]);
9379#if CONFIG_SUPERTX
9380 best_rate_nocoef = rate2;
9381#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07009382 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009383 } else {
9384#if CONFIG_SUPERTX
9385 best_rate_nocoef = rate2 - (rate_y + rate_uv_tokenonly[uv_tx]);
9386#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07009387 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009388 }
9389 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
9390 if (this_rd < best_rd) {
9391 best_mode_index = 3;
9392 mbmi->mv[0].as_int = 0;
9393 rd_cost->rate = rate2;
9394#if CONFIG_SUPERTX
9395 *returnrate_nocoef = best_rate_nocoef;
9396#endif
9397 rd_cost->dist = distortion2;
9398 rd_cost->rdcost = this_rd;
9399 best_rd = this_rd;
9400 best_mbmode = *mbmi;
9401 best_skip2 = 0;
9402 best_mode_skippable = skippable;
9403 }
9404 }
9405PALETTE_EXIT:
Urvang Joshib100db72016-10-12 16:28:56 -07009406#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009407
hui su5db97432016-10-14 16:10:14 -07009408#if CONFIG_FILTER_INTRA
9409 // TODO(huisu): filter-intra is turned off in lossless mode for now to
Yaowu Xuc27fc142016-08-22 16:08:15 -07009410 // avoid a unit test failure
hui su5db97432016-10-14 16:10:14 -07009411 if (!xd->lossless[mbmi->segment_id] &&
Urvang Joshib100db72016-10-12 16:28:56 -07009412#if CONFIG_PALETTE
9413 mbmi->palette_mode_info.palette_size[0] == 0 &&
9414#endif // CONFIG_PALETTE
9415 !dc_skipped && best_mode_index >= 0 &&
9416 best_intra_rd < (best_rd + (best_rd >> 3))) {
hui su5db97432016-10-14 16:10:14 -07009417 pick_filter_intra_interframe(
Urvang Joshi368fbc92016-10-17 16:31:34 -07009418 cpi, x, ctx, bsize, rate_uv_intra, rate_uv_tokenonly, dist_uvs,
hui su5db97432016-10-14 16:10:14 -07009419 skip_uvs, mode_uv, filter_intra_mode_info_uv,
9420#if CONFIG_EXT_INTRA
9421 uv_angle_delta,
9422#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07009423#if CONFIG_PALETTE
9424 pmi_uv, palette_ctx,
9425#endif // CONFIG_PALETTE
9426 0, ref_costs_single, &best_rd, &best_intra_rd, &best_intra_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009427 &best_mode_index, &best_skip2, &best_mode_skippable,
9428#if CONFIG_SUPERTX
9429 returnrate_nocoef,
9430#endif // CONFIG_SUPERTX
9431 best_pred_rd, &best_mbmode, rd_cost);
9432 }
hui su5db97432016-10-14 16:10:14 -07009433#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009434
9435 // The inter modes' rate costs are not calculated precisely in some cases.
9436 // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
9437 // ZEROMV. Here, checks are added for those cases, and the mode decisions
9438 // are corrected.
9439 if (best_mbmode.mode == NEWMV
9440#if CONFIG_EXT_INTER
9441 || best_mbmode.mode == NEWFROMNEARMV || best_mbmode.mode == NEW_NEWMV
9442#endif // CONFIG_EXT_INTER
9443 ) {
9444 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
9445 best_mbmode.ref_frame[1] };
9446 int comp_pred_mode = refs[1] > INTRA_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -07009447 int_mv zeromv[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009448#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07009449 const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame);
Sarah Parkere5299862016-08-16 14:57:37 -07009450#endif // CONFIG_REF_MV
9451#if CONFIG_GLOBAL_MOTION
9452 zeromv[0].as_int = cm->global_motion[refs[0]].motion_params.wmmat[0].as_int;
9453 zeromv[1].as_int = cm->global_motion[refs[1]].motion_params.wmmat[0].as_int;
9454#else
9455 zeromv[0].as_int = 0;
9456 zeromv[1].as_int = 0;
9457#endif // CONFIG_GLOBAL_MOTION
9458#if CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07009459 if (!comp_pred_mode) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009460 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -07009461 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009462 : INT_MAX;
9463
9464 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
9465 int_mv cur_mv = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
9466 if (cur_mv.as_int == best_mbmode.mv[0].as_int) {
9467 best_mbmode.mode = NEARMV;
9468 best_mbmode.ref_mv_idx = i;
9469 }
9470 }
9471
9472 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
9473 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -07009474 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009475 best_mbmode.mode = ZEROMV;
9476 } else {
9477 int_mv nearestmv[2];
9478 int_mv nearmv[2];
9479
9480#if CONFIG_EXT_INTER
9481 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
9482 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][1].this_mv;
9483 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][1].comp_mv;
9484 } else {
9485 nearmv[0] = frame_mv[NEARMV][refs[0]];
9486 nearmv[1] = frame_mv[NEARMV][refs[1]];
9487 }
9488#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009489 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -07009490 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009491 : INT_MAX;
9492
9493 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
9494 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
9495 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
9496
9497 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
9498 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
9499 best_mbmode.mode = NEARMV;
9500 best_mbmode.ref_mv_idx = i;
9501 }
9502 }
9503#endif
9504 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
9505 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
9506 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
9507 } else {
9508 nearestmv[0] = frame_mv[NEARESTMV][refs[0]];
9509 nearestmv[1] = frame_mv[NEARESTMV][refs[1]];
9510 }
9511
9512 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
9513 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
9514#if CONFIG_EXT_INTER
9515 best_mbmode.mode = NEAREST_NEARESTMV;
9516 else if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
9517 nearmv[1].as_int == best_mbmode.mv[1].as_int)
9518 best_mbmode.mode = NEAREST_NEARMV;
9519 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
9520 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
9521 best_mbmode.mode = NEAR_NEARESTMV;
9522 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
9523 nearmv[1].as_int == best_mbmode.mv[1].as_int)
9524 best_mbmode.mode = NEAR_NEARMV;
9525 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
9526 best_mbmode.mode = ZERO_ZEROMV;
9527#else
9528 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -07009529 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
9530 best_mbmode.mv[1].as_int == zeromv[1].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009531 best_mbmode.mode = ZEROMV;
9532#endif // CONFIG_EXT_INTER
9533 }
9534#else
9535#if CONFIG_EXT_INTER
9536 if (!comp_pred_mode) {
9537#endif // CONFIG_EXT_INTER
9538 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
9539 ((comp_pred_mode &&
9540 frame_mv[NEARESTMV][refs[1]].as_int == best_mbmode.mv[1].as_int) ||
9541 !comp_pred_mode))
9542 best_mbmode.mode = NEARESTMV;
9543 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
9544 ((comp_pred_mode &&
9545 frame_mv[NEARMV][refs[1]].as_int ==
9546 best_mbmode.mv[1].as_int) ||
9547 !comp_pred_mode))
9548 best_mbmode.mode = NEARMV;
Sarah Parkere5299862016-08-16 14:57:37 -07009549 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
9550 ((comp_pred_mode &&
9551 best_mbmode.mv[1].as_int == zeromv[1].as_int) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07009552 !comp_pred_mode))
9553 best_mbmode.mode = ZEROMV;
9554#if CONFIG_EXT_INTER
9555 } else {
9556 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
9557 best_mbmode.ref_frame[1] };
9558
9559 if (frame_mv[NEAREST_NEARESTMV][refs[0]].as_int ==
9560 best_mbmode.mv[0].as_int &&
9561 frame_mv[NEAREST_NEARESTMV][refs[1]].as_int ==
9562 best_mbmode.mv[1].as_int)
9563 best_mbmode.mode = NEAREST_NEARESTMV;
9564 else if (frame_mv[NEAREST_NEARMV][refs[0]].as_int ==
9565 best_mbmode.mv[0].as_int &&
9566 frame_mv[NEAREST_NEARMV][refs[1]].as_int ==
9567 best_mbmode.mv[1].as_int)
9568 best_mbmode.mode = NEAREST_NEARMV;
9569 else if (frame_mv[NEAR_NEARESTMV][refs[0]].as_int ==
9570 best_mbmode.mv[0].as_int &&
9571 frame_mv[NEAR_NEARESTMV][refs[1]].as_int ==
9572 best_mbmode.mv[1].as_int)
9573 best_mbmode.mode = NEAR_NEARESTMV;
9574 else if (frame_mv[NEAR_NEARMV][refs[0]].as_int ==
9575 best_mbmode.mv[0].as_int &&
9576 frame_mv[NEAR_NEARMV][refs[1]].as_int ==
9577 best_mbmode.mv[1].as_int)
9578 best_mbmode.mode = NEAR_NEARMV;
9579 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
9580 best_mbmode.mode = ZERO_ZEROMV;
9581 }
9582#endif // CONFIG_EXT_INTER
9583#endif
9584 }
9585
9586#if CONFIG_REF_MV
9587 if (best_mbmode.ref_frame[0] > INTRA_FRAME && best_mbmode.mv[0].as_int == 0 &&
9588#if CONFIG_EXT_INTER
9589 (best_mbmode.ref_frame[1] <= INTRA_FRAME)
9590#else
9591 (best_mbmode.ref_frame[1] == NONE || best_mbmode.mv[1].as_int == 0)
9592#endif // CONFIG_EXT_INTER
9593 ) {
9594 int16_t mode_ctx = mbmi_ext->mode_context[best_mbmode.ref_frame[0]];
9595#if !CONFIG_EXT_INTER
9596 if (best_mbmode.ref_frame[1] > NONE)
9597 mode_ctx &= (mbmi_ext->mode_context[best_mbmode.ref_frame[1]] | 0x00ff);
9598#endif // !CONFIG_EXT_INTER
9599
9600 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) best_mbmode.mode = ZEROMV;
9601 }
9602#endif
9603
9604 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
9605 rd_cost->rate = INT_MAX;
9606 rd_cost->rdcost = INT64_MAX;
9607 return;
9608 }
9609
Yaowu Xuc27fc142016-08-22 16:08:15 -07009610#if CONFIG_DUAL_FILTER
9611 assert((cm->interp_filter == SWITCHABLE) ||
9612 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
9613 !is_inter_block(&best_mbmode));
9614 assert((cm->interp_filter == SWITCHABLE) ||
9615 (cm->interp_filter == best_mbmode.interp_filter[1]) ||
9616 !is_inter_block(&best_mbmode));
9617 if (best_mbmode.ref_frame[1] > INTRA_FRAME) {
9618 assert((cm->interp_filter == SWITCHABLE) ||
9619 (cm->interp_filter == best_mbmode.interp_filter[2]) ||
9620 !is_inter_block(&best_mbmode));
9621 assert((cm->interp_filter == SWITCHABLE) ||
9622 (cm->interp_filter == best_mbmode.interp_filter[3]) ||
9623 !is_inter_block(&best_mbmode));
9624 }
9625#else
9626 assert((cm->interp_filter == SWITCHABLE) ||
9627 (cm->interp_filter == best_mbmode.interp_filter) ||
9628 !is_inter_block(&best_mbmode));
9629#endif
9630
9631 if (!cpi->rc.is_src_frame_alt_ref)
Yaowu Xuf883b422016-08-30 14:01:10 -07009632 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
9633 sf->adaptive_rd_thresh, bsize, best_mode_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009634
9635 // macroblock modes
9636 *mbmi = best_mbmode;
9637 x->skip |= best_skip2;
9638
9639#if CONFIG_REF_MV
9640 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
9641 if (mbmi->mode != NEWMV)
9642 mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
9643 else
9644 mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
9645 }
9646#endif
9647
9648 for (i = 0; i < REFERENCE_MODES; ++i) {
9649 if (best_pred_rd[i] == INT64_MAX)
9650 best_pred_diff[i] = INT_MIN;
9651 else
9652 best_pred_diff[i] = best_rd - best_pred_rd[i];
9653 }
9654
9655 x->skip |= best_mode_skippable;
9656
9657 assert(best_mode_index >= 0);
9658
9659 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
9660 best_mode_skippable);
9661
Urvang Joshib100db72016-10-12 16:28:56 -07009662#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009663 if (cm->allow_screen_content_tools && pmi->palette_size[1] > 0) {
9664 restore_uv_color_map(cpi, x);
9665 }
Urvang Joshib100db72016-10-12 16:28:56 -07009666#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009667}
9668
Urvang Joshi52648442016-10-13 17:27:51 -07009669void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
9670 TileDataEnc *tile_data, MACROBLOCK *x,
9671 RD_COST *rd_cost, BLOCK_SIZE bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -07009672 PICK_MODE_CONTEXT *ctx,
9673 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07009674 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009675 MACROBLOCKD *const xd = &x->e_mbd;
9676 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
9677 unsigned char segment_id = mbmi->segment_id;
9678 const int comp_pred = 0;
9679 int i;
9680 int64_t best_pred_diff[REFERENCE_MODES];
9681 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
9682 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -07009683 aom_prob comp_mode_p;
James Zern7b9407a2016-05-18 23:48:05 -07009684 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009685 int64_t this_rd = INT64_MAX;
9686 int rate2 = 0;
9687 const int64_t distortion2 = 0;
9688
9689 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
9690 &comp_mode_p);
9691
9692 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
9693 for (i = LAST_FRAME; i < TOTAL_REFS_PER_FRAME; ++i)
9694 x->pred_mv_sad[i] = INT_MAX;
9695
9696 rd_cost->rate = INT_MAX;
9697
9698 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
9699
Urvang Joshib100db72016-10-12 16:28:56 -07009700#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009701 mbmi->palette_mode_info.palette_size[0] = 0;
9702 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07009703#endif // CONFIG_PALETTE
9704
hui su5db97432016-10-14 16:10:14 -07009705#if CONFIG_FILTER_INTRA
9706 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
9707 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
9708#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009709 mbmi->mode = ZEROMV;
Yue Chencb60b182016-10-13 15:18:22 -07009710 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009711 mbmi->uv_mode = DC_PRED;
9712 mbmi->ref_frame[0] = LAST_FRAME;
9713 mbmi->ref_frame[1] = NONE;
Sarah Parkere5299862016-08-16 14:57:37 -07009714#if CONFIG_GLOBAL_MOTION
9715 mbmi->mv[0].as_int =
9716 cm->global_motion[mbmi->ref_frame[0]].motion_params.wmmat[0].as_int;
9717#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009718 mbmi->mv[0].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07009719#endif // CONFIG_GLOBAL_MOTION
Jingning Han64088952016-07-11 11:24:24 -07009720 mbmi->tx_size = max_txsize_lookup[bsize];
Yaowu Xuee775b12016-10-18 10:00:21 -07009721 x->skip = 1;
Sarah Parkere5299862016-08-16 14:57:37 -07009722
Yaowu Xuc27fc142016-08-22 16:08:15 -07009723#if CONFIG_REF_MV
9724 mbmi->ref_mv_idx = 0;
9725 mbmi->pred_mv[0].as_int = 0;
9726#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009727
9728 if (cm->interp_filter != BILINEAR) {
9729 best_filter = EIGHTTAP_REGULAR;
9730 if (cm->interp_filter == SWITCHABLE &&
9731#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07009732 av1_is_interp_needed(xd) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07009733#endif // CONFIG_EXT_INTERP
9734 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
9735 int rs;
9736 int best_rs = INT_MAX;
9737 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
9738#if CONFIG_DUAL_FILTER
9739 int k;
9740 for (k = 0; k < 4; ++k) mbmi->interp_filter[k] = i;
9741#else
9742 mbmi->interp_filter = i;
9743#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07009744 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009745 if (rs < best_rs) {
9746 best_rs = rs;
9747#if CONFIG_DUAL_FILTER
9748 best_filter = mbmi->interp_filter[0];
9749#else
9750 best_filter = mbmi->interp_filter;
9751#endif
9752 }
9753 }
9754 }
9755 }
9756 // Set the appropriate filter
9757 if (cm->interp_filter == SWITCHABLE) {
9758#if CONFIG_DUAL_FILTER
9759 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = best_filter;
9760#else
9761 mbmi->interp_filter = best_filter;
9762#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07009763 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009764 } else {
9765#if CONFIG_DUAL_FILTER
9766 for (i = 0; i < 4; ++i) mbmi->interp_filter[0] = cm->interp_filter;
9767#else
9768 mbmi->interp_filter = cm->interp_filter;
9769#endif
9770 }
9771
9772 if (cm->reference_mode == REFERENCE_MODE_SELECT)
Yaowu Xuf883b422016-08-30 14:01:10 -07009773 rate2 += av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009774
9775 // Estimate the reference frame signaling cost and add it
9776 // to the rolling cost variable.
9777 rate2 += ref_costs_single[LAST_FRAME];
9778 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
9779
9780 rd_cost->rate = rate2;
9781 rd_cost->dist = distortion2;
9782 rd_cost->rdcost = this_rd;
9783
9784 if (this_rd >= best_rd_so_far) {
9785 rd_cost->rate = INT_MAX;
9786 rd_cost->rdcost = INT64_MAX;
9787 return;
9788 }
9789
9790#if CONFIG_DUAL_FILTER
9791 assert((cm->interp_filter == SWITCHABLE) ||
9792 (cm->interp_filter == mbmi->interp_filter[0]));
9793#else
9794 assert((cm->interp_filter == SWITCHABLE) ||
9795 (cm->interp_filter == mbmi->interp_filter));
9796#endif
9797
Yaowu Xuf883b422016-08-30 14:01:10 -07009798 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
9799 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009800
Yaowu Xuf883b422016-08-30 14:01:10 -07009801 av1_zero(best_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009802
9803 store_coding_context(x, ctx, THR_ZEROMV, best_pred_diff, 0);
9804}
9805
Urvang Joshi52648442016-10-13 17:27:51 -07009806void av1_rd_pick_inter_mode_sub8x8(const struct AV1_COMP *cpi,
9807 TileDataEnc *tile_data, struct macroblock *x,
9808 int mi_row, int mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -07009809 struct RD_COST *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009810#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009811 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009812#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009813 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
9814 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07009815 const AV1_COMMON *const cm = &cpi->common;
9816 const RD_OPT *const rd_opt = &cpi->rd;
9817 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009818 MACROBLOCKD *const xd = &x->e_mbd;
9819 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
9820 const struct segmentation *const seg = &cm->seg;
9821 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
9822 unsigned char segment_id = mbmi->segment_id;
9823 int comp_pred, i;
9824 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
9825 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
9826 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
9827 0,
Yaowu Xuf883b422016-08-30 14:01:10 -07009828 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009829#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009830 AOM_LAST2_FLAG,
9831 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009832#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009833 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009834#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009835 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009836#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009837 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07009838 };
9839 int64_t best_rd = best_rd_so_far;
9840 int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
9841 int64_t best_pred_diff[REFERENCE_MODES];
9842 int64_t best_pred_rd[REFERENCE_MODES];
9843 MB_MODE_INFO best_mbmode;
9844 int ref_index, best_ref_index = 0;
9845 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
9846 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -07009847 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009848#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07009849 InterpFilter tmp_best_filter[4] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009850#else
James Zern7b9407a2016-05-18 23:48:05 -07009851 InterpFilter tmp_best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009852#endif
Jingning Han3f167252016-06-07 16:11:42 -07009853 int rate_uv_intra, rate_uv_tokenonly = INT_MAX;
9854 int64_t dist_uv = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009855 int skip_uv;
9856 PREDICTION_MODE mode_uv = DC_PRED;
Yaowu Xuf883b422016-08-30 14:01:10 -07009857 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009858 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
9859#if CONFIG_EXT_INTER
9860 int_mv seg_mvs[4][2][TOTAL_REFS_PER_FRAME];
9861#else
9862 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME];
9863#endif // CONFIG_EXT_INTER
9864 b_mode_info best_bmodes[4];
9865 int best_skip2 = 0;
9866 int ref_frame_skip_mask[2] = { 0 };
9867 int internal_active_edge =
Yaowu Xuf883b422016-08-30 14:01:10 -07009868 av1_active_edge_sb(cpi, mi_row, mi_col) && av1_internal_image_edge(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009869
9870#if CONFIG_SUPERTX
9871 best_rd_so_far = INT64_MAX;
9872 best_rd = best_rd_so_far;
9873 best_yrd = best_rd_so_far;
9874#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009875 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009876
hui su5db97432016-10-14 16:10:14 -07009877#if CONFIG_FILTER_INTRA
9878 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
9879 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
9880#endif // CONFIG_FILTER_INTRA
Yue Chencb60b182016-10-13 15:18:22 -07009881 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009882#if CONFIG_EXT_INTER
9883 mbmi->use_wedge_interinter = 0;
9884 mbmi->use_wedge_interintra = 0;
9885#endif // CONFIG_EXT_INTER
9886
9887 for (i = 0; i < 4; i++) {
9888 int j;
9889#if CONFIG_EXT_INTER
9890 int k;
9891
9892 for (k = 0; k < 2; k++)
9893 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
9894 seg_mvs[i][k][j].as_int = INVALID_MV;
9895#else
9896 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
9897 seg_mvs[i][j].as_int = INVALID_MV;
9898#endif // CONFIG_EXT_INTER
9899 }
9900
9901 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
9902 &comp_mode_p);
9903
9904 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
9905 rate_uv_intra = INT_MAX;
9906
9907 rd_cost->rate = INT_MAX;
9908#if CONFIG_SUPERTX
9909 *returnrate_nocoef = INT_MAX;
9910#endif
9911
9912 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
9913 x->mbmi_ext->mode_context[ref_frame] = 0;
9914#if CONFIG_REF_MV && CONFIG_EXT_INTER
9915 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
9916#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
9917 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
9918 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
9919 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
9920 } else {
9921 ref_frame_skip_mask[0] |= (1 << ref_frame);
9922 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9923 }
9924 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
9925#if CONFIG_EXT_INTER
9926 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
9927#endif // CONFIG_EXT_INTER
9928 frame_mv[ZEROMV][ref_frame].as_int = 0;
9929 }
9930
Urvang Joshib100db72016-10-12 16:28:56 -07009931#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009932 mbmi->palette_mode_info.palette_size[0] = 0;
9933 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07009934#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009935
9936 for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
9937 int mode_excluded = 0;
9938 int64_t this_rd = INT64_MAX;
9939 int disable_skip = 0;
9940 int compmode_cost = 0;
9941 int rate2 = 0, rate_y = 0, rate_uv = 0;
9942 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
9943 int skippable = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009944 int this_skip2 = 0;
9945 int64_t total_sse = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009946
Yaowu Xuf883b422016-08-30 14:01:10 -07009947 ref_frame = av1_ref_order[ref_index].ref_frame[0];
9948 second_ref_frame = av1_ref_order[ref_index].ref_frame[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009949
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009950#if CONFIG_REF_MV
9951 mbmi->ref_mv_idx = 0;
9952#endif
9953
Yaowu Xuc27fc142016-08-22 16:08:15 -07009954 // Look at the reference frame of the best mode so far and set the
9955 // skip mask to look at a subset of the remaining modes.
9956 if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
9957 if (ref_index == 3) {
9958 switch (best_mbmode.ref_frame[0]) {
9959 case INTRA_FRAME: break;
9960 case LAST_FRAME:
9961 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
9962#if CONFIG_EXT_REFS
9963 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
9964 (1 << BWDREF_FRAME) |
9965#endif // CONFIG_EXT_REFS
9966 (1 << ALTREF_FRAME);
9967 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9968 break;
9969#if CONFIG_EXT_REFS
9970 case LAST2_FRAME:
9971 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST3_FRAME) |
9972 (1 << GOLDEN_FRAME) |
9973 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
9974 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9975 break;
9976 case LAST3_FRAME:
9977 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
9978 (1 << GOLDEN_FRAME) |
9979 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
9980 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9981 break;
9982#endif // CONFIG_EXT_REFS
9983 case GOLDEN_FRAME:
9984 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
9985#if CONFIG_EXT_REFS
9986 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
9987 (1 << BWDREF_FRAME) |
9988#endif // CONFIG_EXT_REFS
9989 (1 << ALTREF_FRAME);
9990 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9991 break;
9992#if CONFIG_EXT_REFS
9993 case BWDREF_FRAME:
9994 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
9995 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) |
9996 (1 << ALTREF_FRAME);
9997 ref_frame_skip_mask[1] |= (1 << ALTREF_FRAME) | 0x01;
9998 break;
9999#endif // CONFIG_EXT_REFS
10000 case ALTREF_FRAME:
10001 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
10002#if CONFIG_EXT_REFS
10003 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
10004 (1 << BWDREF_FRAME) |
10005#endif // CONFIG_EXT_REFS
10006 (1 << GOLDEN_FRAME);
10007#if CONFIG_EXT_REFS
10008 ref_frame_skip_mask[1] |= (1 << BWDREF_FRAME) | 0x01;
10009#endif // CONFIG_EXT_REFS
10010 break;
10011 case NONE:
10012 case TOTAL_REFS_PER_FRAME:
10013 assert(0 && "Invalid Reference frame");
10014 break;
10015 }
10016 }
10017 }
10018
10019 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010020 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010021 continue;
10022
10023 // Test best rd so far against threshold for trying this mode.
10024 if (!internal_active_edge &&
10025 rd_less_than_thresh(best_rd,
10026 rd_opt->threshes[segment_id][bsize][ref_index],
10027 tile_data->thresh_freq_fact[bsize][ref_index]))
10028 continue;
10029
10030 comp_pred = second_ref_frame > INTRA_FRAME;
10031 if (comp_pred) {
10032 if (!cpi->allow_comp_inter_inter) continue;
10033 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
10034 // Do not allow compound prediction if the segment level reference frame
10035 // feature is in use as in this case there can only be one reference.
10036 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
10037
10038 if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
10039 best_mbmode.ref_frame[0] == INTRA_FRAME)
10040 continue;
10041 }
10042
10043 // TODO(jingning, jkoleszar): scaling reference frame not supported for
10044 // sub8x8 blocks.
10045 if (ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010046 av1_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010047 continue;
10048
10049 if (second_ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010050 av1_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010051 continue;
10052
10053 if (comp_pred)
10054 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
10055 else if (ref_frame != INTRA_FRAME)
10056 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
10057
10058 // If the segment reference frame feature is enabled....
10059 // then do nothing if the current ref frame is not allowed..
10060 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
10061 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
10062 continue;
10063 // Disable this drop out case if the ref frame
10064 // segment level feature is enabled for this segment. This is to
10065 // prevent the possibility that we end up unable to pick any mode.
10066 } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
10067 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
10068 // unless ARNR filtering is enabled in which case we want
10069 // an unfiltered alternative. We allow near/nearest as well
10070 // because they may result in zero-zero MVs but be cheaper.
10071 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
10072 continue;
10073 }
10074
10075 mbmi->tx_size = TX_4X4;
10076 mbmi->uv_mode = DC_PRED;
10077 mbmi->ref_frame[0] = ref_frame;
10078 mbmi->ref_frame[1] = second_ref_frame;
10079// Evaluate all sub-pel filters irrespective of whether we can use
10080// them for this frame.
10081#if CONFIG_DUAL_FILTER
10082 for (i = 0; i < 4; ++i)
10083 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
10084 ? EIGHTTAP_REGULAR
10085 : cm->interp_filter;
10086#else
10087 mbmi->interp_filter =
10088 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
10089#endif
10090 x->skip = 0;
10091 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
10092
10093 // Select prediction reference frames.
10094 for (i = 0; i < MAX_MB_PLANE; i++) {
10095 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
10096 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
10097 }
10098
10099#if CONFIG_VAR_TX
10100 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
10101#endif
10102
10103 if (ref_frame == INTRA_FRAME) {
10104 int rate;
10105 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y, &distortion_y,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -070010106 NULL, best_rd) >= best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010107 continue;
10108 rate2 += rate;
10109 rate2 += intra_cost_penalty;
10110 distortion2 += distortion_y;
10111
10112 if (rate_uv_intra == INT_MAX) {
10113 choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4, &rate_uv_intra,
10114 &rate_uv_tokenonly, &dist_uv, &skip_uv, &mode_uv);
10115 }
10116 rate2 += rate_uv_intra;
10117 rate_uv = rate_uv_tokenonly;
10118 distortion2 += dist_uv;
10119 distortion_uv = dist_uv;
10120 mbmi->uv_mode = mode_uv;
10121 } else {
10122 int rate;
10123 int64_t distortion;
10124 int64_t this_rd_thresh;
10125 int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
10126 int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
10127 int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
10128 int tmp_best_skippable = 0;
10129 int switchable_filter_index;
10130 int_mv *second_ref =
10131 comp_pred ? &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL;
10132 b_mode_info tmp_best_bmodes[16]; // Should this be 4 ?
10133 MB_MODE_INFO tmp_best_mbmode;
10134#if CONFIG_DUAL_FILTER
10135#if CONFIG_EXT_INTERP
10136 BEST_SEG_INFO bsi[25];
10137#else
10138 BEST_SEG_INFO bsi[9];
10139#endif
10140#else
10141 BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
10142#endif
10143 int pred_exists = 0;
10144 int uv_skippable;
10145#if CONFIG_EXT_INTER
10146 int_mv compound_seg_newmvs[4][2];
10147 for (i = 0; i < 4; i++) {
10148 compound_seg_newmvs[i][0].as_int = INVALID_MV;
10149 compound_seg_newmvs[i][1].as_int = INVALID_MV;
10150 }
10151#endif // CONFIG_EXT_INTER
10152
10153 this_rd_thresh = (ref_frame == LAST_FRAME)
10154 ? rd_opt->threshes[segment_id][bsize][THR_LAST]
10155 : rd_opt->threshes[segment_id][bsize][THR_ALTR];
10156#if CONFIG_EXT_REFS
10157 this_rd_thresh = (ref_frame == LAST2_FRAME)
10158 ? rd_opt->threshes[segment_id][bsize][THR_LAST2]
10159 : this_rd_thresh;
10160 this_rd_thresh = (ref_frame == LAST3_FRAME)
10161 ? rd_opt->threshes[segment_id][bsize][THR_LAST3]
10162 : this_rd_thresh;
Zoe Liua6a6dd52016-10-18 13:03:12 -070010163 this_rd_thresh = (ref_frame == BWDREF_FRAME)
10164 ? rd_opt->threshes[segment_id][bsize][THR_BWDR]
10165 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010166#endif // CONFIG_EXT_REFS
10167 this_rd_thresh = (ref_frame == GOLDEN_FRAME)
10168 ? rd_opt->threshes[segment_id][bsize][THR_GOLD]
10169 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010170
10171 // TODO(any): Add search of the tx_type to improve rd performance at the
10172 // expense of speed.
10173 mbmi->tx_type = DCT_DCT;
10174
10175 if (cm->interp_filter != BILINEAR) {
10176#if CONFIG_DUAL_FILTER
10177 tmp_best_filter[0] = EIGHTTAP_REGULAR;
10178 tmp_best_filter[1] = EIGHTTAP_REGULAR;
10179 tmp_best_filter[2] = EIGHTTAP_REGULAR;
10180 tmp_best_filter[3] = EIGHTTAP_REGULAR;
10181#else
10182 tmp_best_filter = EIGHTTAP_REGULAR;
10183#endif
10184 if (x->source_variance < sf->disable_filter_search_var_thresh) {
10185#if CONFIG_DUAL_FILTER
10186 tmp_best_filter[0] = EIGHTTAP_REGULAR;
10187#else
10188 tmp_best_filter = EIGHTTAP_REGULAR;
10189#endif
10190 } else if (sf->adaptive_pred_interp_filter == 1 &&
10191 ctx->pred_interp_filter < SWITCHABLE) {
10192#if CONFIG_DUAL_FILTER
10193 tmp_best_filter[0] = ctx->pred_interp_filter;
10194#else
10195 tmp_best_filter = ctx->pred_interp_filter;
10196#endif
10197 } else if (sf->adaptive_pred_interp_filter == 2) {
10198#if CONFIG_DUAL_FILTER
10199 tmp_best_filter[0] = ctx->pred_interp_filter < SWITCHABLE
10200 ? ctx->pred_interp_filter
10201 : 0;
10202#else
10203 tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE
10204 ? ctx->pred_interp_filter
10205 : 0;
10206#endif
10207 } else {
10208#if CONFIG_DUAL_FILTER
10209 for (switchable_filter_index = 0;
10210#if CONFIG_EXT_INTERP
10211 switchable_filter_index < 25;
10212#else
10213 switchable_filter_index < 9;
10214#endif
10215 ++switchable_filter_index) {
10216#else
10217 for (switchable_filter_index = 0;
10218 switchable_filter_index < SWITCHABLE_FILTERS;
10219 ++switchable_filter_index) {
10220#endif
10221 int newbest, rs;
10222 int64_t rs_rd;
10223 MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
10224#if CONFIG_DUAL_FILTER
10225 mbmi->interp_filter[0] = filter_sets[switchable_filter_index][0];
10226 mbmi->interp_filter[1] = filter_sets[switchable_filter_index][1];
10227 mbmi->interp_filter[2] = filter_sets[switchable_filter_index][0];
10228 mbmi->interp_filter[3] = filter_sets[switchable_filter_index][1];
10229#else
10230 mbmi->interp_filter = switchable_filter_index;
10231#endif
10232 tmp_rd = rd_pick_best_sub8x8_mode(
10233 cpi, x, &mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
10234 &rate, &rate_y, &distortion, &skippable, &total_sse,
10235 (int)this_rd_thresh, seg_mvs,
10236#if CONFIG_EXT_INTER
10237 compound_seg_newmvs,
10238#endif // CONFIG_EXT_INTER
10239 bsi, switchable_filter_index, mi_row, mi_col);
10240#if CONFIG_EXT_INTERP
10241#if CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070010242 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010243 (mbmi->interp_filter[0] != EIGHTTAP_REGULAR ||
10244 mbmi->interp_filter[1] != EIGHTTAP_REGULAR)) // invalid config
10245 continue;
10246#else
Yaowu Xuf883b422016-08-30 14:01:10 -070010247 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010248 mbmi->interp_filter != EIGHTTAP_REGULAR) // invalid config
10249 continue;
10250#endif
10251#endif // CONFIG_EXT_INTERP
10252 if (tmp_rd == INT64_MAX) continue;
Yaowu Xuf883b422016-08-30 14:01:10 -070010253 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010254 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
10255 if (cm->interp_filter == SWITCHABLE) tmp_rd += rs_rd;
10256
10257 newbest = (tmp_rd < tmp_best_rd);
10258 if (newbest) {
10259#if CONFIG_DUAL_FILTER
10260 tmp_best_filter[0] = mbmi->interp_filter[0];
10261 tmp_best_filter[1] = mbmi->interp_filter[1];
10262 tmp_best_filter[2] = mbmi->interp_filter[2];
10263 tmp_best_filter[3] = mbmi->interp_filter[3];
10264#else
10265 tmp_best_filter = mbmi->interp_filter;
10266#endif
10267 tmp_best_rd = tmp_rd;
10268 }
10269 if ((newbest && cm->interp_filter == SWITCHABLE) ||
10270 (
10271#if CONFIG_DUAL_FILTER
10272 mbmi->interp_filter[0] == cm->interp_filter
10273#else
10274 mbmi->interp_filter == cm->interp_filter
10275#endif
10276 && cm->interp_filter != SWITCHABLE)) {
10277 tmp_best_rdu = tmp_rd;
10278 tmp_best_rate = rate;
10279 tmp_best_ratey = rate_y;
10280 tmp_best_distortion = distortion;
10281 tmp_best_sse = total_sse;
10282 tmp_best_skippable = skippable;
10283 tmp_best_mbmode = *mbmi;
10284 for (i = 0; i < 4; i++) {
10285 tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
10286 }
10287 pred_exists = 1;
10288 }
10289 } // switchable_filter_index loop
10290 }
10291 }
10292
10293 if (tmp_best_rdu == INT64_MAX && pred_exists) continue;
10294
10295#if CONFIG_DUAL_FILTER
10296 mbmi->interp_filter[0] =
10297 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[0]
10298 : cm->interp_filter);
10299 mbmi->interp_filter[1] =
10300 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[1]
10301 : cm->interp_filter);
10302 mbmi->interp_filter[2] =
10303 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[2]
10304 : cm->interp_filter);
10305 mbmi->interp_filter[3] =
10306 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[3]
10307 : cm->interp_filter);
10308#else
10309 mbmi->interp_filter =
10310 (cm->interp_filter == SWITCHABLE ? tmp_best_filter
10311 : cm->interp_filter);
10312#endif
10313
10314 if (!pred_exists) {
10315 // Handles the special case when a filter that is not in the
10316 // switchable list (bilinear) is indicated at the frame level
10317 tmp_rd = rd_pick_best_sub8x8_mode(
10318 cpi, x, &x->mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
10319 &rate, &rate_y, &distortion, &skippable, &total_sse,
10320 (int)this_rd_thresh, seg_mvs,
10321#if CONFIG_EXT_INTER
10322 compound_seg_newmvs,
10323#endif // CONFIG_EXT_INTER
10324 bsi, 0, mi_row, mi_col);
10325#if CONFIG_EXT_INTERP
10326#if CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070010327 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010328 (mbmi->interp_filter[0] != EIGHTTAP_REGULAR ||
10329 mbmi->interp_filter[1] != EIGHTTAP_REGULAR)) {
10330 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
10331 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
10332 }
10333#else
Yaowu Xuf883b422016-08-30 14:01:10 -070010334 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010335 mbmi->interp_filter != EIGHTTAP_REGULAR)
10336 mbmi->interp_filter = EIGHTTAP_REGULAR;
10337#endif // CONFIG_DUAL_FILTER
10338#endif // CONFIG_EXT_INTERP
10339 if (tmp_rd == INT64_MAX) continue;
10340 } else {
10341 total_sse = tmp_best_sse;
10342 rate = tmp_best_rate;
10343 rate_y = tmp_best_ratey;
10344 distortion = tmp_best_distortion;
10345 skippable = tmp_best_skippable;
10346 *mbmi = tmp_best_mbmode;
10347 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
10348 }
10349 // Add in the cost of the transform type
10350 if (!xd->lossless[mbmi->segment_id]) {
10351 int rate_tx_type = 0;
10352#if CONFIG_EXT_TX
10353 if (get_ext_tx_types(mbmi->tx_size, bsize, 1) > 1) {
10354 const int eset = get_ext_tx_set(mbmi->tx_size, bsize, 1);
10355 rate_tx_type =
10356 cpi->inter_tx_type_costs[eset][mbmi->tx_size][mbmi->tx_type];
10357 }
10358#else
10359 if (mbmi->tx_size < TX_32X32) {
10360 rate_tx_type = cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
10361 }
10362#endif
10363 rate += rate_tx_type;
10364 rate_y += rate_tx_type;
10365 }
10366
10367 rate2 += rate;
10368 distortion2 += distortion;
10369
10370 if (cm->interp_filter == SWITCHABLE)
Yaowu Xuf883b422016-08-30 14:01:10 -070010371 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010372
10373 if (!mode_excluded)
10374 mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
10375 : cm->reference_mode == COMPOUND_REFERENCE;
10376
Yaowu Xuf883b422016-08-30 14:01:10 -070010377 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010378
10379 tmp_best_rdu =
Yaowu Xuf883b422016-08-30 14:01:10 -070010380 best_rd - AOMMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
Yaowu Xuc27fc142016-08-22 16:08:15 -070010381 RDCOST(x->rdmult, x->rddiv, 0, total_sse));
10382
10383 if (tmp_best_rdu > 0) {
10384 // If even the 'Y' rd value of split is higher than best so far
10385 // then dont bother looking at UV
Yaowu Xuf883b422016-08-30 14:01:10 -070010386 av1_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col, BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010387#if CONFIG_VAR_TX
10388 if (!inter_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
10389 &uv_sse, BLOCK_8X8, tmp_best_rdu))
10390 continue;
10391#else
10392 if (!super_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
10393 &uv_sse, BLOCK_8X8, tmp_best_rdu))
10394 continue;
10395#endif
10396 rate2 += rate_uv;
10397 distortion2 += distortion_uv;
10398 skippable = skippable && uv_skippable;
10399 total_sse += uv_sse;
10400 } else {
10401 continue;
10402 }
10403 }
10404
10405 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
10406
10407 // Estimate the reference frame signaling cost and add it
10408 // to the rolling cost variable.
10409 if (second_ref_frame > INTRA_FRAME) {
10410 rate2 += ref_costs_comp[ref_frame];
10411#if CONFIG_EXT_REFS
10412 rate2 += ref_costs_comp[second_ref_frame];
10413#endif // CONFIG_EXT_REFS
10414 } else {
10415 rate2 += ref_costs_single[ref_frame];
10416 }
10417
10418 if (!disable_skip) {
10419 // Skip is never coded at the segment level for sub8x8 blocks and instead
10420 // always coded in the bitstream at the mode info level.
10421
10422 if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
10423 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
10424 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
10425 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010426 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010427 } else {
10428 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070010429 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010430 distortion2 = total_sse;
10431 assert(total_sse >= 0);
10432 rate2 -= (rate_y + rate_uv);
10433 rate_y = 0;
10434 rate_uv = 0;
10435 this_skip2 = 1;
10436 }
10437 } else {
10438 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010439 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010440 }
10441
10442 // Calculate the final RD estimate for this mode.
10443 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10444 }
10445
10446 if (!disable_skip && ref_frame == INTRA_FRAME) {
10447 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070010448 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010449 }
10450
10451 // Did this mode help.. i.e. is it the new best mode
10452 if (this_rd < best_rd || x->skip) {
10453 if (!mode_excluded) {
10454 // Note index of best mode so far
10455 best_ref_index = ref_index;
10456
10457 if (ref_frame == INTRA_FRAME) {
10458 /* required for left and above block mv */
10459 mbmi->mv[0].as_int = 0;
10460 }
10461
10462 rd_cost->rate = rate2;
10463#if CONFIG_SUPERTX
10464 *returnrate_nocoef = rate2 - rate_y - rate_uv;
10465 if (!disable_skip)
10466 *returnrate_nocoef -=
Yaowu Xuf883b422016-08-30 14:01:10 -070010467 av1_cost_bit(av1_get_skip_prob(cm, xd), this_skip2);
10468 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
10469 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010470 assert(*returnrate_nocoef > 0);
10471#endif // CONFIG_SUPERTX
10472 rd_cost->dist = distortion2;
10473 rd_cost->rdcost = this_rd;
10474 best_rd = this_rd;
10475 best_yrd =
10476 best_rd - RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
10477 best_mbmode = *mbmi;
10478 best_skip2 = this_skip2;
10479
10480#if CONFIG_VAR_TX
10481 for (i = 0; i < MAX_MB_PLANE; ++i)
10482 memset(ctx->blk_skip[i], 0, sizeof(uint8_t) * ctx->num_4x4_blk);
10483#endif
10484
10485 for (i = 0; i < 4; i++) best_bmodes[i] = xd->mi[0]->bmi[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010486 }
10487 }
10488
10489 /* keep record of best compound/single-only prediction */
10490 if (!disable_skip && ref_frame != INTRA_FRAME) {
10491 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
10492
10493 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
10494 single_rate = rate2 - compmode_cost;
10495 hybrid_rate = rate2;
10496 } else {
10497 single_rate = rate2;
10498 hybrid_rate = rate2 + compmode_cost;
10499 }
10500
10501 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
10502 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
10503
10504 if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE])
10505 best_pred_rd[SINGLE_REFERENCE] = single_rd;
10506 else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE])
10507 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
10508
10509 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
10510 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
10511 }
10512
Yaowu Xuc27fc142016-08-22 16:08:15 -070010513 if (x->skip && !comp_pred) break;
10514 }
10515
10516 if (best_rd >= best_rd_so_far) {
10517 rd_cost->rate = INT_MAX;
10518 rd_cost->rdcost = INT64_MAX;
10519#if CONFIG_SUPERTX
10520 *returnrate_nocoef = INT_MAX;
10521#endif // CONFIG_SUPERTX
10522 return;
10523 }
10524
Yaowu Xuc27fc142016-08-22 16:08:15 -070010525 if (best_rd == INT64_MAX) {
10526 rd_cost->rate = INT_MAX;
10527 rd_cost->dist = INT64_MAX;
10528 rd_cost->rdcost = INT64_MAX;
10529#if CONFIG_SUPERTX
10530 *returnrate_nocoef = INT_MAX;
10531#endif // CONFIG_SUPERTX
10532 return;
10533 }
10534
10535#if CONFIG_DUAL_FILTER
10536 assert((cm->interp_filter == SWITCHABLE) ||
10537 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
10538 !is_inter_block(&best_mbmode));
10539#else
10540 assert((cm->interp_filter == SWITCHABLE) ||
10541 (cm->interp_filter == best_mbmode.interp_filter) ||
10542 !is_inter_block(&best_mbmode));
10543#endif
10544
Yaowu Xuf883b422016-08-30 14:01:10 -070010545 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
10546 sf->adaptive_rd_thresh, bsize, best_ref_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010547
10548 // macroblock modes
10549 *mbmi = best_mbmode;
10550#if CONFIG_VAR_TX && CONFIG_EXT_TX && CONFIG_RECT_TX
10551 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
10552#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
10553
10554 x->skip |= best_skip2;
10555 if (!is_inter_block(&best_mbmode)) {
10556 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
10557 } else {
10558 for (i = 0; i < 4; ++i)
10559 memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
10560
Yaowu Xuc27fc142016-08-22 16:08:15 -070010561#if CONFIG_REF_MV
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -070010562 mbmi->pred_mv[0].as_int = xd->mi[0]->bmi[3].pred_mv[0].as_int;
10563 mbmi->pred_mv[1].as_int = xd->mi[0]->bmi[3].pred_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010564#endif
Yaowu Xu4306b6e2016-09-27 12:55:32 -070010565 mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
10566 mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010567 }
10568
10569 for (i = 0; i < REFERENCE_MODES; ++i) {
10570 if (best_pred_rd[i] == INT64_MAX)
10571 best_pred_diff[i] = INT_MIN;
10572 else
10573 best_pred_diff[i] = best_rd - best_pred_rd[i];
10574 }
10575
10576 store_coding_context(x, ctx, best_ref_index, best_pred_diff, 0);
10577}
10578
Yue Chencb60b182016-10-13 15:18:22 -070010579#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070010580// This function has a structure similar to av1_build_obmc_inter_prediction
Yaowu Xuc27fc142016-08-22 16:08:15 -070010581//
10582// The OBMC predictor is computed as:
10583//
10584// PObmc(x,y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070010585// AOM_BLEND_A64(Mh(x),
10586// AOM_BLEND_A64(Mv(y), P(x,y), PAbove(x,y)),
Yaowu Xuc27fc142016-08-22 16:08:15 -070010587// PLeft(x, y))
10588//
Yaowu Xuf883b422016-08-30 14:01:10 -070010589// Scaling up by AOM_BLEND_A64_MAX_ALPHA ** 2 and omitting the intermediate
Yaowu Xuc27fc142016-08-22 16:08:15 -070010590// rounding, this can be written as:
10591//
Yaowu Xuf883b422016-08-30 14:01:10 -070010592// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * Pobmc(x,y) =
Yaowu Xuc27fc142016-08-22 16:08:15 -070010593// Mh(x) * Mv(y) * P(x,y) +
10594// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070010595// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010596//
10597// Where :
10598//
Yaowu Xuf883b422016-08-30 14:01:10 -070010599// Cv(y) = AOM_BLEND_A64_MAX_ALPHA - Mv(y)
10600// Ch(y) = AOM_BLEND_A64_MAX_ALPHA - Mh(y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010601//
10602// This function computes 'wsrc' and 'mask' as:
10603//
10604// wsrc(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070010605// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * src(x, y) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070010606// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070010607// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010608//
10609// mask(x, y) = Mh(x) * Mv(y)
10610//
10611// These can then be used to efficiently approximate the error for any
10612// predictor P in the context of the provided neighbouring predictors by
10613// computing:
10614//
10615// error(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070010616// wsrc(x, y) - mask(x, y) * P(x, y) / (AOM_BLEND_A64_MAX_ALPHA ** 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010617//
Yaowu Xuf883b422016-08-30 14:01:10 -070010618static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010619 const MACROBLOCKD *xd, int mi_row,
10620 int mi_col, const uint8_t *above,
10621 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -070010622 int left_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010623 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
10624 int row, col, i;
10625 const int bw = 8 * xd->n8_w;
10626 const int bh = 8 * xd->n8_h;
Yue Chene9638cc2016-10-10 12:37:54 -070010627 int32_t *mask_buf = x->mask_buf;
10628 int32_t *wsrc_buf = x->wsrc_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010629 const int wsrc_stride = bw;
10630 const int mask_stride = bw;
Yaowu Xuf883b422016-08-30 14:01:10 -070010631 const int src_scale = AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA;
10632#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010633 const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
10634#else
10635 const int is_hbd = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010636#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010637
10638 // plane 0 should not be subsampled
10639 assert(xd->plane[0].subsampling_x == 0);
10640 assert(xd->plane[0].subsampling_y == 0);
10641
Yaowu Xuf883b422016-08-30 14:01:10 -070010642 av1_zero_array(wsrc_buf, bw * bh);
10643 for (i = 0; i < bw * bh; ++i) mask_buf[i] = AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010644
10645 // handle above row
10646 if (xd->up_available) {
10647 const int overlap = num_4x4_blocks_high_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070010648 const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010649 const int mi_row_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070010650 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010651
10652 assert(miw > 0);
10653
10654 i = 0;
10655 do { // for each mi in the above row
10656 const int mi_col_offset = i;
10657 const MB_MODE_INFO *const above_mbmi =
10658 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
10659 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -070010660 AOMMIN(xd->n8_w, num_8x8_blocks_wide_lookup[above_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010661 const int neighbor_bw = mi_step * MI_SIZE;
10662
10663 if (is_neighbor_overlappable(above_mbmi)) {
10664 const int tmp_stride = above_stride;
10665 int32_t *wsrc = wsrc_buf + (i * MI_SIZE);
10666 int32_t *mask = mask_buf + (i * MI_SIZE);
10667
10668 if (!is_hbd) {
10669 const uint8_t *tmp = above;
10670
10671 for (row = 0; row < overlap; ++row) {
10672 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070010673 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010674 for (col = 0; col < neighbor_bw; ++col) {
10675 wsrc[col] = m1 * tmp[col];
10676 mask[col] = m0;
10677 }
10678 wsrc += wsrc_stride;
10679 mask += mask_stride;
10680 tmp += tmp_stride;
10681 }
Yaowu Xuf883b422016-08-30 14:01:10 -070010682#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010683 } else {
10684 const uint16_t *tmp = CONVERT_TO_SHORTPTR(above);
10685
10686 for (row = 0; row < overlap; ++row) {
10687 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070010688 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010689 for (col = 0; col < neighbor_bw; ++col) {
10690 wsrc[col] = m1 * tmp[col];
10691 mask[col] = m0;
10692 }
10693 wsrc += wsrc_stride;
10694 mask += mask_stride;
10695 tmp += tmp_stride;
10696 }
Yaowu Xuf883b422016-08-30 14:01:10 -070010697#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010698 }
10699 }
10700
10701 above += neighbor_bw;
10702 i += mi_step;
10703 } while (i < miw);
10704 }
10705
10706 for (i = 0; i < bw * bh; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -070010707 wsrc_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
10708 mask_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010709 }
10710
10711 // handle left column
10712 if (xd->left_available) {
10713 const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070010714 const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010715 const int mi_col_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070010716 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010717
10718 assert(mih > 0);
10719
10720 i = 0;
10721 do { // for each mi in the left column
10722 const int mi_row_offset = i;
10723 const MB_MODE_INFO *const left_mbmi =
10724 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
10725 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -070010726 AOMMIN(xd->n8_h, num_8x8_blocks_high_lookup[left_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010727 const int neighbor_bh = mi_step * MI_SIZE;
10728
10729 if (is_neighbor_overlappable(left_mbmi)) {
10730 const int tmp_stride = left_stride;
10731 int32_t *wsrc = wsrc_buf + (i * MI_SIZE * wsrc_stride);
10732 int32_t *mask = mask_buf + (i * MI_SIZE * mask_stride);
10733
10734 if (!is_hbd) {
10735 const uint8_t *tmp = left;
10736
10737 for (row = 0; row < neighbor_bh; ++row) {
10738 for (col = 0; col < overlap; ++col) {
10739 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070010740 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
10741 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
10742 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
10743 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010744 }
10745 wsrc += wsrc_stride;
10746 mask += mask_stride;
10747 tmp += tmp_stride;
10748 }
Yaowu Xuf883b422016-08-30 14:01:10 -070010749#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010750 } else {
10751 const uint16_t *tmp = CONVERT_TO_SHORTPTR(left);
10752
10753 for (row = 0; row < neighbor_bh; ++row) {
10754 for (col = 0; col < overlap; ++col) {
10755 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070010756 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
10757 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
10758 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
10759 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010760 }
10761 wsrc += wsrc_stride;
10762 mask += mask_stride;
10763 tmp += tmp_stride;
10764 }
Yaowu Xuf883b422016-08-30 14:01:10 -070010765#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010766 }
10767 }
10768
10769 left += neighbor_bh * left_stride;
10770 i += mi_step;
10771 } while (i < mih);
10772 }
10773
10774 if (!is_hbd) {
10775 const uint8_t *src = x->plane[0].src.buf;
10776
10777 for (row = 0; row < bh; ++row) {
10778 for (col = 0; col < bw; ++col) {
10779 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
10780 }
10781 wsrc_buf += wsrc_stride;
10782 src += x->plane[0].src.stride;
10783 }
Yaowu Xuf883b422016-08-30 14:01:10 -070010784#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010785 } else {
10786 const uint16_t *src = CONVERT_TO_SHORTPTR(x->plane[0].src.buf);
10787
10788 for (row = 0; row < bh; ++row) {
10789 for (col = 0; col < bw; ++col) {
10790 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
10791 }
10792 wsrc_buf += wsrc_stride;
10793 src += x->plane[0].src.stride;
10794 }
Yaowu Xuf883b422016-08-30 14:01:10 -070010795#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010796 }
10797}
Yue Chencb60b182016-10-13 15:18:22 -070010798#endif // CONFIG_MOTION_VAR