blob: 1270bb60a82343f3608bcd5c81a1117546aae63e [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:
710 if ((tx_set >= 0) & !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D]))
711 return 0;
712 return prune_one_for_sby(cpi, bsize, x, xd);
713 break;
714#if CONFIG_EXT_TX
715 case PRUNE_TWO:
716 if ((tx_set >= 0) & !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D])) {
717 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 }
720 if ((tx_set >= 0) & !(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D]))
721 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.
995 const int ss_txfrm_size = num_4x4_blocks_txsize_log2_lookup[tx_size];
996 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;
Yaowu Xuf883b422016-08-30 14:01:10 -07001003 *out_dist = av1_highbd_block_error(coeff, dqcoeff, 16 << ss_txfrm_size,
1004 &this_sse, bd) >>
Yaowu Xuc27fc142016-08-22 16:08:15 -07001005 shift;
1006#else
1007 *out_dist =
Yaowu Xuf883b422016-08-30 14:01:10 -07001008 av1_block_error(coeff, dqcoeff, 16 << ss_txfrm_size, &this_sse) >>
Yaowu Xuc27fc142016-08-22 16:08:15 -07001009 shift;
Yaowu Xuf883b422016-08-30 14:01:10 -07001010#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001011 *out_sse = this_sse >> shift;
1012 } else {
1013 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
1014 const int bsw = 4 * num_4x4_blocks_wide_lookup[tx_bsize];
1015 const int bsh = 4 * num_4x4_blocks_high_lookup[tx_bsize];
1016 const int src_stride = x->plane[plane].src.stride;
1017 const int dst_stride = xd->plane[plane].dst.stride;
1018 const int src_idx = 4 * (blk_row * src_stride + blk_col);
1019 const int dst_idx = 4 * (blk_row * dst_stride + blk_col);
1020 const uint8_t *src = &x->plane[plane].src.buf[src_idx];
1021 const uint8_t *dst = &xd->plane[plane].dst.buf[dst_idx];
1022 const tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1023 const uint16_t eob = p->eobs[block];
1024
1025 unsigned int tmp;
1026
1027 assert(cpi != NULL);
1028
1029 cpi->fn_ptr[tx_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
1030 *out_sse = (int64_t)tmp * 16;
1031
1032 if (eob) {
1033 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Yaowu Xuf883b422016-08-30 14:01:10 -07001034#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001035 DECLARE_ALIGNED(16, uint16_t, recon16[MAX_TX_SQUARE]);
1036 uint8_t *recon = (uint8_t *)recon16;
1037#else
1038 DECLARE_ALIGNED(16, uint8_t, recon[MAX_TX_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07001039#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001040
1041 const PLANE_TYPE plane_type = plane == 0 ? PLANE_TYPE_Y : PLANE_TYPE_UV;
1042
1043 INV_TXFM_PARAM inv_txfm_param;
1044
1045 inv_txfm_param.tx_type = get_tx_type(plane_type, xd, block, tx_size);
1046 inv_txfm_param.tx_size = tx_size;
1047 inv_txfm_param.eob = eob;
1048 inv_txfm_param.lossless = xd->lossless[mbmi->segment_id];
1049
Yaowu Xuf883b422016-08-30 14:01:10 -07001050#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001051 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1052 recon = CONVERT_TO_BYTEPTR(recon);
1053 inv_txfm_param.bd = xd->bd;
Yaowu Xuf883b422016-08-30 14:01:10 -07001054 aom_highbd_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001055 NULL, 0, bsw, bsh, xd->bd);
1056 highbd_inv_txfm_add(dqcoeff, recon, MAX_TX_SIZE, &inv_txfm_param);
1057 } else
Yaowu Xuf883b422016-08-30 14:01:10 -07001058#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001059 {
Yaowu Xuf883b422016-08-30 14:01:10 -07001060 aom_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001061 bsw, bsh);
1062 inv_txfm_add(dqcoeff, recon, MAX_TX_SIZE, &inv_txfm_param);
1063 }
1064
1065 cpi->fn_ptr[tx_bsize].vf(src, src_stride, recon, MAX_TX_SIZE, &tmp);
1066 }
1067
1068 *out_dist = (int64_t)tmp * 16;
1069 }
1070}
1071
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001072static int rate_block(int plane, int block, int coeff_ctx, TX_SIZE tx_size,
Debargha Mukherjee29630542016-09-06 13:15:31 -07001073 struct rdcost_block_args *args) {
Angie Chiang22ba7512016-10-20 17:10:33 -07001074 return av1_cost_coeffs(&args->cpi->common, args->x, plane, block, coeff_ctx,
1075 tx_size, args->scan_order->scan,
1076 args->scan_order->neighbors,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001077 args->use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001078}
1079
1080static uint64_t sum_squares_2d(const int16_t *diff, int diff_stride,
1081 TX_SIZE tx_size) {
1082 uint64_t sse;
1083 switch (tx_size) {
1084#if CONFIG_EXT_TX
1085 case TX_4X8:
Yaowu Xuf883b422016-08-30 14:01:10 -07001086 sse = aom_sum_squares_2d_i16(diff, diff_stride, 4) +
1087 aom_sum_squares_2d_i16(diff + 4 * diff_stride, diff_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001088 break;
1089 case TX_8X4:
Yaowu Xuf883b422016-08-30 14:01:10 -07001090 sse = aom_sum_squares_2d_i16(diff, diff_stride, 4) +
1091 aom_sum_squares_2d_i16(diff + 4, diff_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001092 break;
1093 case TX_8X16:
Yaowu Xuf883b422016-08-30 14:01:10 -07001094 sse = aom_sum_squares_2d_i16(diff, diff_stride, 8) +
1095 aom_sum_squares_2d_i16(diff + 8 * diff_stride, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001096 break;
1097 case TX_16X8:
Yaowu Xuf883b422016-08-30 14:01:10 -07001098 sse = aom_sum_squares_2d_i16(diff, diff_stride, 8) +
1099 aom_sum_squares_2d_i16(diff + 8, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001100 break;
1101 case TX_16X32:
Yaowu Xuf883b422016-08-30 14:01:10 -07001102 sse = aom_sum_squares_2d_i16(diff, diff_stride, 16) +
1103 aom_sum_squares_2d_i16(diff + 16 * diff_stride, diff_stride, 16);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001104 break;
1105 case TX_32X16:
Yaowu Xuf883b422016-08-30 14:01:10 -07001106 sse = aom_sum_squares_2d_i16(diff, diff_stride, 16) +
1107 aom_sum_squares_2d_i16(diff + 16, diff_stride, 16);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001108 break;
1109#endif // CONFIG_EXT_TX
1110 default:
1111 assert(tx_size < TX_SIZES);
Yaowu Xuf883b422016-08-30 14:01:10 -07001112 sse = aom_sum_squares_2d_i16(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001113 diff, diff_stride, num_4x4_blocks_wide_txsize_lookup[tx_size] << 2);
1114 break;
1115 }
1116 return sse;
1117}
1118
1119static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
1120 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
1121 struct rdcost_block_args *args = arg;
1122 MACROBLOCK *const x = args->x;
1123 MACROBLOCKD *const xd = &x->e_mbd;
1124 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -07001125 const AV1_COMMON *cm = &args->cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001126 int64_t rd1, rd2, rd;
1127 int rate;
1128 int64_t dist;
1129 int64_t sse;
Debargha Mukherjee29630542016-09-06 13:15:31 -07001130
Yaowu Xuc27fc142016-08-22 16:08:15 -07001131 int coeff_ctx = combine_entropy_contexts(*(args->t_above + blk_col),
1132 *(args->t_left + blk_row));
1133
1134 if (args->exit_early) return;
1135
1136 if (!is_inter_block(mbmi)) {
Urvang Joshi454280d2016-10-14 16:51:44 -07001137 struct encode_b_args b_args = {
Angie Chiangff6d8902016-10-21 11:02:09 -07001138 (AV1_COMMON *)cm, x, NULL, &mbmi->skip, args->t_above, args->t_left, 1
Yaowu Xuc27fc142016-08-22 16:08:15 -07001139 };
Yaowu Xuf883b422016-08-30 14:01:10 -07001140 av1_encode_block_intra(plane, block, blk_row, blk_col, plane_bsize, tx_size,
Urvang Joshi454280d2016-10-14 16:51:44 -07001141 &b_args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001142
1143 if (args->cpi->sf.use_transform_domain_distortion) {
1144 dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size, &dist,
1145 &sse);
1146 } else {
1147 // Note that the encode block_intra call above already calls
1148 // inv_txfm_add, so we can't just call dist_block here.
1149 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Yaowu Xuf883b422016-08-30 14:01:10 -07001150 const aom_variance_fn_t variance = args->cpi->fn_ptr[tx_bsize].vf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001151
1152 const struct macroblock_plane *const p = &x->plane[plane];
1153 const struct macroblockd_plane *const pd = &xd->plane[plane];
1154
1155 const int src_stride = p->src.stride;
1156 const int dst_stride = pd->dst.stride;
1157 const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
1158
1159 const uint8_t *src = &p->src.buf[4 * (blk_row * src_stride + blk_col)];
1160 const uint8_t *dst = &pd->dst.buf[4 * (blk_row * dst_stride + blk_col)];
1161 const int16_t *diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
1162
1163 unsigned int tmp;
1164 sse = sum_squares_2d(diff, diff_stride, tx_size);
1165
Yaowu Xuf883b422016-08-30 14:01:10 -07001166#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001167 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
1168 sse = ROUND_POWER_OF_TWO(sse, (xd->bd - 8) * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07001169#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001170 sse = (int64_t)sse * 16;
1171
1172 variance(src, src_stride, dst, dst_stride, &tmp);
1173 dist = (int64_t)tmp * 16;
1174 }
1175 } else {
1176// full forward transform and quantization
1177#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07001178 av1_xform_quant_fp_nuq(cm, x, plane, block, blk_row, blk_col, plane_bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -07001179 tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001180#else
Angie Chiangff6d8902016-10-21 11:02:09 -07001181 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Yaowu Xuf883b422016-08-30 14:01:10 -07001182 AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001183#endif // CONFIG_NEW_QUANT
1184 if (x->plane[plane].eobs[block])
Angie Chiangff6d8902016-10-21 11:02:09 -07001185 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001186 dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size, &dist,
1187 &sse);
1188 }
1189
1190 rd = RDCOST(x->rdmult, x->rddiv, 0, dist);
1191 if (args->this_rd + rd > args->best_rd) {
1192 args->exit_early = 1;
1193 return;
1194 }
1195
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001196 rate = rate_block(plane, block, coeff_ctx, tx_size, args);
1197 args->t_above[blk_col] = (x->plane[plane].eobs[block] > 0);
1198 args->t_left[blk_row] = (x->plane[plane].eobs[block] > 0);
1199
Yaowu Xuc27fc142016-08-22 16:08:15 -07001200 rd1 = RDCOST(x->rdmult, x->rddiv, rate, dist);
1201 rd2 = RDCOST(x->rdmult, x->rddiv, 0, sse);
1202
1203 // TODO(jingning): temporarily enabled only for luma component
Yaowu Xuf883b422016-08-30 14:01:10 -07001204 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001205
1206 args->this_rate += rate;
1207 args->this_dist += dist;
1208 args->this_sse += sse;
1209 args->this_rd += rd;
1210
1211 if (args->this_rd > args->best_rd) {
1212 args->exit_early = 1;
1213 return;
1214 }
1215
1216 args->skippable &= !x->plane[plane].eobs[block];
1217}
1218
Yaowu Xuf883b422016-08-30 14:01:10 -07001219static void txfm_rd_in_plane(MACROBLOCK *x, const AV1_COMP *cpi, int *rate,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001220 int64_t *distortion, int *skippable, int64_t *sse,
1221 int64_t ref_best_rd, int plane, BLOCK_SIZE bsize,
1222 TX_SIZE tx_size, int use_fast_coef_casting) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001223 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001224 MACROBLOCKD *const xd = &x->e_mbd;
1225 const struct macroblockd_plane *const pd = &xd->plane[plane];
1226 TX_TYPE tx_type;
1227 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001228 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001229 args.x = x;
1230 args.cpi = cpi;
1231 args.best_rd = ref_best_rd;
1232 args.use_fast_coef_costing = use_fast_coef_casting;
1233 args.skippable = 1;
1234
1235 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1236
Yaowu Xuf883b422016-08-30 14:01:10 -07001237 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001238
1239 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001240 args.scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07001241 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001242
Yaowu Xuf883b422016-08-30 14:01:10 -07001243 av1_foreach_transformed_block_in_plane(xd, bsize, plane, block_rd_txfm,
1244 &args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001245 if (args.exit_early) {
1246 *rate = INT_MAX;
1247 *distortion = INT64_MAX;
1248 *sse = INT64_MAX;
1249 *skippable = 0;
1250 } else {
1251 *distortion = args.this_dist;
1252 *rate = args.this_rate;
1253 *sse = args.this_sse;
1254 *skippable = args.skippable;
1255 }
1256}
1257
1258#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001259void av1_txfm_rd_in_plane_supertx(MACROBLOCK *x, const AV1_COMP *cpi, int *rate,
1260 int64_t *distortion, int *skippable,
1261 int64_t *sse, int64_t ref_best_rd, int plane,
1262 BLOCK_SIZE bsize, TX_SIZE tx_size,
1263 int use_fast_coef_casting) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001264 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001265 MACROBLOCKD *const xd = &x->e_mbd;
1266 const struct macroblockd_plane *const pd = &xd->plane[plane];
1267 struct rdcost_block_args args;
1268 TX_TYPE tx_type;
1269
Yaowu Xuf883b422016-08-30 14:01:10 -07001270 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001271 args.cpi = cpi;
1272 args.x = x;
1273 args.best_rd = ref_best_rd;
1274 args.use_fast_coef_costing = use_fast_coef_casting;
1275
1276#if CONFIG_EXT_TX
1277 assert(tx_size < TX_SIZES);
1278#endif // CONFIG_EXT_TX
1279
1280 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1281
Yaowu Xuf883b422016-08-30 14:01:10 -07001282 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001283
1284 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001285 args.scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07001286 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001287
1288 block_rd_txfm(plane, 0, 0, 0, get_plane_block_size(bsize, pd), tx_size,
1289 &args);
1290
1291 if (args.exit_early) {
1292 *rate = INT_MAX;
1293 *distortion = INT64_MAX;
1294 *sse = INT64_MAX;
1295 *skippable = 0;
1296 } else {
1297 *distortion = args.this_dist;
1298 *rate = args.this_rate;
1299 *sse = args.this_sse;
1300 *skippable = !x->plane[plane].eobs[0];
1301 }
1302}
1303#endif // CONFIG_SUPERTX
1304
Urvang Joshi52648442016-10-13 17:27:51 -07001305static int64_t txfm_yrd(const AV1_COMP *const cpi, MACROBLOCK *x, int *r,
1306 int64_t *d, int *s, int64_t *sse, int64_t ref_best_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001307 BLOCK_SIZE bs, TX_TYPE tx_type, int tx_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07001308 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001309 MACROBLOCKD *const xd = &x->e_mbd;
1310 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1311 int64_t rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001312 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001313 int s0, s1;
1314 const int is_inter = is_inter_block(mbmi);
1315 const int tx_size_ctx = get_tx_size_context(xd);
1316 const int tx_size_cat =
1317 is_inter ? inter_tx_size_cat_lookup[bs] : intra_tx_size_cat_lookup[bs];
1318 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
1319 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
1320 const int r_tx_size =
1321 cpi->tx_size_cost[tx_size_cat][tx_size_ctx][coded_tx_size];
1322
1323 assert(skip_prob > 0);
1324#if CONFIG_EXT_TX && CONFIG_RECT_TX
1325 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed_bsize(bs)));
1326#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1327
Yaowu Xuf883b422016-08-30 14:01:10 -07001328 s0 = av1_cost_bit(skip_prob, 0);
1329 s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001330
1331 mbmi->tx_type = tx_type;
1332 mbmi->tx_size = tx_size;
1333 txfm_rd_in_plane(x, cpi, r, d, s, sse, ref_best_rd, 0, bs, tx_size,
1334 cpi->sf.use_fast_coef_costing);
1335 if (*r == INT_MAX) return INT64_MAX;
1336#if CONFIG_EXT_TX
1337 if (get_ext_tx_types(tx_size, bs, is_inter) > 1 &&
1338 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
1339 const int ext_tx_set = get_ext_tx_set(tx_size, bs, is_inter);
1340 if (is_inter) {
1341 if (ext_tx_set > 0)
clang-format67948d32016-09-07 22:40:40 -07001342 *r +=
1343 cpi->inter_tx_type_costs[ext_tx_set][txsize_sqr_map[mbmi->tx_size]]
1344 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001345 } else {
1346 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
1347 *r += cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->mode]
1348 [mbmi->tx_type];
1349 }
1350 }
1351#else
1352 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1353 !FIXED_TX_TYPE) {
1354 if (is_inter) {
1355 *r += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
1356 } else {
1357 *r += cpi->intra_tx_type_costs[mbmi->tx_size]
1358 [intra_mode_to_tx_type_context[mbmi->mode]]
1359 [mbmi->tx_type];
1360 }
1361 }
1362#endif // CONFIG_EXT_TX
1363
1364 if (*s) {
1365 if (is_inter) {
1366 rd = RDCOST(x->rdmult, x->rddiv, s1, *sse);
1367 } else {
1368 rd = RDCOST(x->rdmult, x->rddiv, s1 + r_tx_size * tx_select, *sse);
1369 }
1370 } else {
1371 rd = RDCOST(x->rdmult, x->rddiv, *r + s0 + r_tx_size * tx_select, *d);
1372 }
1373
1374 if (tx_select) *r += r_tx_size;
1375
1376 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] && !(*s))
Yaowu Xuf883b422016-08-30 14:01:10 -07001377 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, *sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001378
1379 return rd;
1380}
1381
Urvang Joshi52648442016-10-13 17:27:51 -07001382static int64_t choose_tx_size_fix_type(const AV1_COMP *const cpi, BLOCK_SIZE bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001383 MACROBLOCK *x, int *rate,
1384 int64_t *distortion, int *skip,
1385 int64_t *psse, int64_t ref_best_rd,
1386 TX_TYPE tx_type, int prune) {
Urvang Joshi52648442016-10-13 17:27:51 -07001387 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001388 MACROBLOCKD *const xd = &x->e_mbd;
1389 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1390 int r, s;
1391 int64_t d, sse;
1392 int64_t rd = INT64_MAX;
1393 int n;
1394 int start_tx, end_tx;
1395 int64_t best_rd = INT64_MAX, last_rd = INT64_MAX;
1396 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
1397 TX_SIZE best_tx_size = max_tx_size;
1398 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
1399 const int is_inter = is_inter_block(mbmi);
1400#if CONFIG_EXT_TX
1401#if CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001402 int evaluate_rect_tx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001403#endif // CONFIG_RECT_TX
1404 int ext_tx_set;
1405#endif // CONFIG_EXT_TX
1406
1407 if (tx_select) {
1408#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001409 evaluate_rect_tx = is_rect_tx_allowed(xd, mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001410#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1411 start_tx = max_tx_size;
Hui Sueafb2e62016-10-18 10:21:36 -07001412 end_tx = (max_tx_size == TX_32X32) ? TX_8X8 : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001413 } else {
1414 const TX_SIZE chosen_tx_size =
1415 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
1416#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001417 evaluate_rect_tx = is_rect_tx(chosen_tx_size);
1418 assert(IMPLIES(evaluate_rect_tx, is_rect_tx_allowed(xd, mbmi)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001419#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1420 start_tx = chosen_tx_size;
1421 end_tx = chosen_tx_size;
1422 }
1423
1424 *distortion = INT64_MAX;
1425 *rate = INT_MAX;
1426 *skip = 0;
1427 *psse = INT64_MAX;
1428
1429 mbmi->tx_type = tx_type;
1430
1431#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001432 if (evaluate_rect_tx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001433 const TX_SIZE rect_tx_size = max_txsize_rect_lookup[bs];
Urvang Joshi368fbc92016-10-17 16:31:34 -07001434 ext_tx_set = get_ext_tx_set(rect_tx_size, bs, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001435 if (ext_tx_used_inter[ext_tx_set][tx_type]) {
1436 rd = txfm_yrd(cpi, x, &r, &d, &s, &sse, ref_best_rd, bs, tx_type,
1437 rect_tx_size);
1438 best_tx_size = rect_tx_size;
1439 best_rd = rd;
1440 *distortion = d;
1441 *rate = r;
1442 *skip = s;
1443 *psse = sse;
1444 }
1445 }
1446#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1447
1448 last_rd = INT64_MAX;
1449 for (n = start_tx; n >= end_tx; --n) {
1450#if CONFIG_EXT_TX && CONFIG_RECT_TX
1451 if (is_rect_tx(n)) break;
1452#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1453 if (FIXED_TX_TYPE && tx_type != get_default_tx_type(0, xd, 0, n)) continue;
1454 if (!is_inter && x->use_default_intra_tx_type &&
1455 tx_type != get_default_tx_type(0, xd, 0, n))
1456 continue;
1457 if (is_inter && x->use_default_inter_tx_type &&
1458 tx_type != get_default_tx_type(0, xd, 0, n))
1459 continue;
1460 if (max_tx_size == TX_32X32 && n == TX_4X4) continue;
1461#if CONFIG_EXT_TX
1462 ext_tx_set = get_ext_tx_set(n, bs, is_inter);
1463 if (is_inter) {
1464 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
1465 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1466 if (!do_tx_type_search(tx_type, prune)) continue;
1467 }
1468 } else {
1469 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1470 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
1471 }
1472 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
1473 }
1474#else // CONFIG_EXT_TX
1475 if (n >= TX_32X32 && tx_type != DCT_DCT) continue;
1476 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
1477 !do_tx_type_search(tx_type, prune))
1478 continue;
1479#endif // CONFIG_EXT_TX
1480
1481 rd = txfm_yrd(cpi, x, &r, &d, &s, &sse, ref_best_rd, bs, tx_type, n);
1482
1483 // Early termination in transform size search.
1484 if (cpi->sf.tx_size_search_breakout &&
1485 (rd == INT64_MAX || (s == 1 && tx_type != DCT_DCT && n < start_tx) ||
1486 (n < (int)max_tx_size && rd > last_rd)))
1487 break;
1488
1489 last_rd = rd;
1490 if (rd < best_rd) {
1491 best_tx_size = n;
1492 best_rd = rd;
1493 *distortion = d;
1494 *rate = r;
1495 *skip = s;
1496 *psse = sse;
1497 }
1498 }
1499 mbmi->tx_size = best_tx_size;
1500
1501 return best_rd;
1502}
1503
1504#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07001505static int64_t estimate_yrd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bs,
1506 MACROBLOCK *x, int *r, int64_t *d, int *s,
1507 int64_t *sse, int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001508 return txfm_yrd(cpi, x, r, d, s, sse, ref_best_rd, bs, DCT_DCT,
1509 max_txsize_lookup[bs]);
1510}
1511#endif // CONFIG_EXT_INTER
1512
Urvang Joshi52648442016-10-13 17:27:51 -07001513static void choose_largest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
1514 int *rate, int64_t *distortion, int *skip,
1515 int64_t *sse, int64_t ref_best_rd,
1516 BLOCK_SIZE bs) {
1517 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001518 MACROBLOCKD *const xd = &x->e_mbd;
1519 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1520 TX_TYPE tx_type, best_tx_type = DCT_DCT;
1521 int r, s;
1522 int64_t d, psse, this_rd, best_rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001523 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
1524 int s0 = av1_cost_bit(skip_prob, 0);
1525 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001526 const int is_inter = is_inter_block(mbmi);
1527 int prune = 0;
1528#if CONFIG_EXT_TX
1529 int ext_tx_set;
1530#endif // CONFIG_EXT_TX
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001531 *distortion = INT64_MAX;
1532 *rate = INT_MAX;
1533 *skip = 0;
1534 *sse = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001535
1536 mbmi->tx_size = tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
1537
1538#if CONFIG_EXT_TX
1539 ext_tx_set = get_ext_tx_set(mbmi->tx_size, bs, is_inter);
1540#endif // CONFIG_EXT_TX
1541
1542 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
1543#if CONFIG_EXT_TX
1544 prune = prune_tx_types(cpi, bs, x, xd, ext_tx_set);
1545#else
1546 prune = prune_tx_types(cpi, bs, x, xd, 0);
1547#endif
1548#if CONFIG_EXT_TX
1549 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1 &&
1550 !xd->lossless[mbmi->segment_id]) {
1551 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
1552 if (is_inter) {
1553 if (x->use_default_inter_tx_type &&
1554 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1555 continue;
1556 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
1557 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1558 if (!do_tx_type_search(tx_type, prune)) continue;
1559 }
1560 } else {
1561 if (x->use_default_intra_tx_type &&
1562 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1563 continue;
1564 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1565 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
1566 }
1567 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
1568 }
1569
1570 mbmi->tx_type = tx_type;
1571
1572 txfm_rd_in_plane(x, cpi, &r, &d, &s, &psse, ref_best_rd, 0, bs,
1573 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
1574
1575 if (r == INT_MAX) continue;
1576 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1) {
1577 if (is_inter) {
1578 if (ext_tx_set > 0)
1579 r += cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size]
1580 [mbmi->tx_type];
1581 } else {
1582 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
1583 r += cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->mode]
1584 [mbmi->tx_type];
1585 }
1586 }
1587
1588 if (s)
1589 this_rd = RDCOST(x->rdmult, x->rddiv, s1, psse);
1590 else
1591 this_rd = RDCOST(x->rdmult, x->rddiv, r + s0, d);
1592 if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] && !s)
Yaowu Xuf883b422016-08-30 14:01:10 -07001593 this_rd = AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, psse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001594
1595 if (this_rd < best_rd) {
1596 best_rd = this_rd;
1597 best_tx_type = mbmi->tx_type;
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001598 *distortion = d;
1599 *rate = r;
1600 *skip = s;
1601 *sse = psse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001602 }
1603 }
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001604 } else {
1605 mbmi->tx_type = DCT_DCT;
1606 txfm_rd_in_plane(x, cpi, rate, distortion, skip, sse, ref_best_rd, 0, bs,
1607 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001608 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001609#else // CONFIG_EXT_TX
1610 if (mbmi->tx_size < TX_32X32 && !xd->lossless[mbmi->segment_id]) {
1611 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
1612 if (!is_inter && x->use_default_intra_tx_type &&
1613 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1614 continue;
1615 if (is_inter && x->use_default_inter_tx_type &&
1616 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1617 continue;
1618 mbmi->tx_type = tx_type;
1619 txfm_rd_in_plane(x, cpi, &r, &d, &s, &psse, ref_best_rd, 0, bs,
1620 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
1621 if (r == INT_MAX) continue;
1622 if (is_inter) {
1623 r += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
1624 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
1625 !do_tx_type_search(tx_type, prune))
1626 continue;
1627 } else {
1628 r += cpi->intra_tx_type_costs[mbmi->tx_size]
1629 [intra_mode_to_tx_type_context[mbmi->mode]]
1630 [mbmi->tx_type];
1631 }
1632 if (s)
1633 this_rd = RDCOST(x->rdmult, x->rddiv, s1, psse);
1634 else
1635 this_rd = RDCOST(x->rdmult, x->rddiv, r + s0, d);
1636 if (is_inter && !xd->lossless[mbmi->segment_id] && !s)
Yaowu Xuf883b422016-08-30 14:01:10 -07001637 this_rd = AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, psse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001638
1639 if (this_rd < best_rd) {
1640 best_rd = this_rd;
1641 best_tx_type = mbmi->tx_type;
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001642 *distortion = d;
1643 *rate = r;
1644 *skip = s;
1645 *sse = psse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001646 }
1647 }
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001648 } else {
1649 mbmi->tx_type = DCT_DCT;
1650 txfm_rd_in_plane(x, cpi, rate, distortion, skip, sse, ref_best_rd, 0, bs,
1651 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001652 }
1653#endif // CONFIG_EXT_TX
1654 mbmi->tx_type = best_tx_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001655}
1656
Urvang Joshi52648442016-10-13 17:27:51 -07001657static void choose_smallest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
1658 int *rate, int64_t *distortion, int *skip,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001659 int64_t *sse, int64_t ref_best_rd,
1660 BLOCK_SIZE bs) {
1661 MACROBLOCKD *const xd = &x->e_mbd;
1662 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1663
1664 mbmi->tx_size = TX_4X4;
1665 mbmi->tx_type = DCT_DCT;
1666
1667 txfm_rd_in_plane(x, cpi, rate, distortion, skip, sse, ref_best_rd, 0, bs,
1668 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
1669}
1670
Urvang Joshi52648442016-10-13 17:27:51 -07001671static void choose_tx_size_type_from_rd(const AV1_COMP *const cpi,
1672 MACROBLOCK *x, int *rate,
Yaowu Xuf883b422016-08-30 14:01:10 -07001673 int64_t *distortion, int *skip,
1674 int64_t *psse, int64_t ref_best_rd,
1675 BLOCK_SIZE bs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001676 MACROBLOCKD *const xd = &x->e_mbd;
1677 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1678 int r, s;
1679 int64_t d, sse;
1680 int64_t rd = INT64_MAX;
1681 int64_t best_rd = INT64_MAX;
1682 TX_SIZE best_tx = max_txsize_lookup[bs];
1683 const int is_inter = is_inter_block(mbmi);
1684 TX_TYPE tx_type, best_tx_type = DCT_DCT;
1685 int prune = 0;
1686
1687 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
1688 // passing -1 in for tx_type indicates that all 1D
1689 // transforms should be considered for pruning
1690 prune = prune_tx_types(cpi, bs, x, xd, -1);
1691
1692 *distortion = INT64_MAX;
1693 *rate = INT_MAX;
1694 *skip = 0;
1695 *psse = INT64_MAX;
1696
1697 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
1698#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07001699 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001700#endif
1701 rd = choose_tx_size_fix_type(cpi, bs, x, &r, &d, &s, &sse, ref_best_rd,
1702 tx_type, prune);
1703 if (rd < best_rd) {
1704 best_rd = rd;
1705 *distortion = d;
1706 *rate = r;
1707 *skip = s;
1708 *psse = sse;
1709 best_tx_type = tx_type;
1710 best_tx = mbmi->tx_size;
1711 }
1712 }
1713
1714 mbmi->tx_size = best_tx;
1715 mbmi->tx_type = best_tx_type;
1716
1717#if !CONFIG_EXT_TX
1718 if (mbmi->tx_size >= TX_32X32) assert(mbmi->tx_type == DCT_DCT);
1719#endif
1720}
1721
Urvang Joshi52648442016-10-13 17:27:51 -07001722static void super_block_yrd(const AV1_COMP *const cpi, MACROBLOCK *x, int *rate,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001723 int64_t *distortion, int *skip, int64_t *psse,
1724 BLOCK_SIZE bs, int64_t ref_best_rd) {
1725 MACROBLOCKD *xd = &x->e_mbd;
1726 int64_t sse;
1727 int64_t *ret_sse = psse ? psse : &sse;
1728
1729 assert(bs == xd->mi[0]->mbmi.sb_type);
1730
1731 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
1732 choose_smallest_tx_size(cpi, x, rate, distortion, skip, ret_sse,
1733 ref_best_rd, bs);
1734 } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
1735 choose_largest_tx_size(cpi, x, rate, distortion, skip, ret_sse, ref_best_rd,
1736 bs);
1737 } else {
1738 choose_tx_size_type_from_rd(cpi, x, rate, distortion, skip, ret_sse,
1739 ref_best_rd, bs);
1740 }
1741}
1742
1743static int conditional_skipintra(PREDICTION_MODE mode,
1744 PREDICTION_MODE best_intra_mode) {
1745 if (mode == D117_PRED && best_intra_mode != V_PRED &&
1746 best_intra_mode != D135_PRED)
1747 return 1;
1748 if (mode == D63_PRED && best_intra_mode != V_PRED &&
1749 best_intra_mode != D45_PRED)
1750 return 1;
1751 if (mode == D207_PRED && best_intra_mode != H_PRED &&
1752 best_intra_mode != D45_PRED)
1753 return 1;
1754 if (mode == D153_PRED && best_intra_mode != H_PRED &&
1755 best_intra_mode != D135_PRED)
1756 return 1;
1757 return 0;
1758}
1759
Urvang Joshib100db72016-10-12 16:28:56 -07001760#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001761static int rd_pick_palette_intra_sby(
Urvang Joshi52648442016-10-13 17:27:51 -07001762 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int palette_ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001763 int dc_mode_cost, PALETTE_MODE_INFO *palette_mode_info,
1764 uint8_t *best_palette_color_map, TX_SIZE *best_tx, TX_TYPE *best_tx_type,
1765 PREDICTION_MODE *mode_selected, int64_t *best_rd) {
1766 int rate_overhead = 0;
1767 MACROBLOCKD *const xd = &x->e_mbd;
1768 MODE_INFO *const mic = xd->mi[0];
1769 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
1770 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
1771 int this_rate, this_rate_tokenonly, s, colors, n;
1772 int64_t this_distortion, this_rd;
1773 const int src_stride = x->plane[0].src.stride;
1774 const uint8_t *const src = x->plane[0].src.buf;
1775
1776 assert(cpi->common.allow_screen_content_tools);
1777
Yaowu Xuf883b422016-08-30 14:01:10 -07001778#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001779 if (cpi->common.use_highbitdepth)
Yaowu Xuf883b422016-08-30 14:01:10 -07001780 colors = av1_count_colors_highbd(src, src_stride, rows, cols,
1781 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001782 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001783#endif // CONFIG_AOM_HIGHBITDEPTH
1784 colors = av1_count_colors(src, src_stride, rows, cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001785 palette_mode_info->palette_size[0] = 0;
hui su5db97432016-10-14 16:10:14 -07001786#if CONFIG_FILTER_INTRA
1787 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0;
1788#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07001789
1790 if (colors > 1 && colors <= 64) {
1791 int r, c, i, j, k;
1792 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07001793 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001794 float *const data = x->palette_buffer->kmeans_data_buf;
1795 float centroids[PALETTE_MAX_SIZE];
1796 uint8_t *const color_map = xd->plane[0].color_index_map;
1797 float lb, ub, val;
1798 MB_MODE_INFO *const mbmi = &mic->mbmi;
1799 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuf883b422016-08-30 14:01:10 -07001800#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001801 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
1802 if (cpi->common.use_highbitdepth)
1803 lb = ub = src16[0];
1804 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001805#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001806 lb = ub = src[0];
1807
Yaowu Xuf883b422016-08-30 14:01:10 -07001808#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001809 if (cpi->common.use_highbitdepth) {
1810 for (r = 0; r < rows; ++r) {
1811 for (c = 0; c < cols; ++c) {
1812 val = src16[r * src_stride + c];
1813 data[r * cols + c] = val;
1814 if (val < lb)
1815 lb = val;
1816 else if (val > ub)
1817 ub = val;
1818 }
1819 }
1820 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001821#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001822 for (r = 0; r < rows; ++r) {
1823 for (c = 0; c < cols; ++c) {
1824 val = src[r * src_stride + c];
1825 data[r * cols + c] = val;
1826 if (val < lb)
1827 lb = val;
1828 else if (val > ub)
1829 ub = val;
1830 }
1831 }
Yaowu Xuf883b422016-08-30 14:01:10 -07001832#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001833 }
Yaowu Xuf883b422016-08-30 14:01:10 -07001834#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001835
1836 mbmi->mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07001837#if CONFIG_FILTER_INTRA
1838 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
1839#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07001840
1841 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return 0;
1842
1843 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
1844 --n) {
1845 for (i = 0; i < n; ++i)
1846 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
Yaowu Xuf883b422016-08-30 14:01:10 -07001847 av1_k_means(data, centroids, color_map, rows * cols, n, 1, max_itr);
1848 k = av1_remove_duplicates(centroids, n);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001849
Yaowu Xuf883b422016-08-30 14:01:10 -07001850#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001851 if (cpi->common.use_highbitdepth)
1852 for (i = 0; i < k; ++i)
1853 pmi->palette_colors[i] =
1854 clip_pixel_highbd((int)centroids[i], cpi->common.bit_depth);
1855 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001856#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001857 for (i = 0; i < k; ++i)
1858 pmi->palette_colors[i] = clip_pixel((int)centroids[i]);
1859 pmi->palette_size[0] = k;
1860
Yaowu Xuf883b422016-08-30 14:01:10 -07001861 av1_calc_indices(data, centroids, color_map, rows * cols, k, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001862
1863 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s, NULL,
1864 bsize, *best_rd);
1865 if (this_rate_tokenonly == INT_MAX) continue;
1866
1867 this_rate =
1868 this_rate_tokenonly + dc_mode_cost +
Yaowu Xuf883b422016-08-30 14:01:10 -07001869 cpi->common.bit_depth * k * av1_cost_bit(128, 0) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07001870 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - 2] +
1871 write_uniform_cost(k, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07001872 av1_cost_bit(
1873 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07001874 1);
1875 for (i = 0; i < rows; ++i) {
1876 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07001877 int color_idx;
1878 const int color_ctx = av1_get_palette_color_context(
1879 color_map, cols, i, j, k, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001880 assert(color_idx >= 0 && color_idx < k);
1881 this_rate += cpi->palette_y_color_cost[k - 2][color_ctx][color_idx];
1882 }
1883 }
1884 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
1885
1886 if (this_rd < *best_rd) {
1887 *best_rd = this_rd;
1888 *palette_mode_info = *pmi;
1889 memcpy(best_palette_color_map, color_map,
1890 rows * cols * sizeof(color_map[0]));
1891 *mode_selected = DC_PRED;
1892 *best_tx = mbmi->tx_size;
1893 *best_tx_type = mbmi->tx_type;
1894 rate_overhead = this_rate - this_rate_tokenonly;
1895 }
1896 }
1897 }
1898 return rate_overhead;
1899}
Urvang Joshib100db72016-10-12 16:28:56 -07001900#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001901
Urvang Joshi52648442016-10-13 17:27:51 -07001902static int64_t rd_pick_intra4x4block(
1903 const AV1_COMP *const cpi, MACROBLOCK *x, int row, int col,
1904 PREDICTION_MODE *best_mode, const int *bmode_costs, ENTROPY_CONTEXT *a,
1905 ENTROPY_CONTEXT *l, int *bestrate, int *bestratey, int64_t *bestdistortion,
1906 BLOCK_SIZE bsize, int *y_skip, int64_t rd_thresh) {
Angie Chiang22ba7512016-10-20 17:10:33 -07001907 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001908 PREDICTION_MODE mode;
1909 MACROBLOCKD *const xd = &x->e_mbd;
1910 int64_t best_rd = rd_thresh;
1911 struct macroblock_plane *p = &x->plane[0];
1912 struct macroblockd_plane *pd = &xd->plane[0];
1913 const int src_stride = p->src.stride;
1914 const int dst_stride = pd->dst.stride;
1915 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
1916 uint8_t *dst_init = &pd->dst.buf[row * 4 * src_stride + col * 4];
1917 ENTROPY_CONTEXT ta[2], tempa[2];
1918 ENTROPY_CONTEXT tl[2], templ[2];
1919 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1920 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1921 int idx, idy;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001922 int best_can_skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001923 uint8_t best_dst[8 * 8];
Yaowu Xuf883b422016-08-30 14:01:10 -07001924#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001925 uint16_t best_dst16[8 * 8];
1926#endif
1927
1928 memcpy(ta, a, num_4x4_blocks_wide * sizeof(a[0]));
1929 memcpy(tl, l, num_4x4_blocks_high * sizeof(l[0]));
1930 xd->mi[0]->mbmi.tx_size = TX_4X4;
Urvang Joshib100db72016-10-12 16:28:56 -07001931#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001932 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07001933#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001934
Yaowu Xuf883b422016-08-30 14:01:10 -07001935#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001936 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1937 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
1938 int64_t this_rd;
1939 int ratey = 0;
1940 int64_t distortion = 0;
1941 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001942 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001943
1944 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode))) continue;
1945
1946 // Only do the oblique modes if the best so far is
1947 // one of the neighboring directional modes
1948 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
1949 if (conditional_skipintra(mode, *best_mode)) continue;
1950 }
1951
1952 memcpy(tempa, ta, num_4x4_blocks_wide * sizeof(ta[0]));
1953 memcpy(templ, tl, num_4x4_blocks_high * sizeof(tl[0]));
1954
1955 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
1956 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
1957 const int block = (row + idy) * 2 + (col + idx);
1958 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
1959 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
1960 int16_t *const src_diff =
Yaowu Xuf883b422016-08-30 14:01:10 -07001961 av1_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001962 xd->mi[0]->bmi[block].as_mode = mode;
Jingning Hanc4c99da2016-10-24 10:27:28 -07001963 av1_predict_intra_block(xd, pd->width, pd->height, TX_4X4, mode, dst,
1964 dst_stride, dst, dst_stride, col + idx,
1965 row + idy, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07001966 aom_highbd_subtract_block(4, 4, src_diff, 8, src, src_stride, dst,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001967 dst_stride, xd->bd);
1968 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
1969 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07001970 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001971 const int coeff_ctx =
1972 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001973#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07001974 av1_xform_quant_fp_nuq(cm, x, 0, block, row + idy, col + idx,
1975 BLOCK_8X8, TX_4X4, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001976#else
Angie Chiangff6d8902016-10-21 11:02:09 -07001977 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Yaowu Xuf883b422016-08-30 14:01:10 -07001978 TX_4X4, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001979#endif // CONFIG_NEW_QUANT
Angie Chiang22ba7512016-10-20 17:10:33 -07001980 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001981 scan_order->scan, scan_order->neighbors,
1982 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001983 *(tempa + idx) = !(p->eobs[block] == 0);
1984 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001985 can_skip &= (p->eobs[block] == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001986 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1987 goto next_highbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07001988 av1_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
1989 dst_stride, p->eobs[block], xd->bd,
1990 DCT_DCT, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001991 } else {
1992 int64_t dist;
1993 unsigned int tmp;
1994 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07001995 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001996 const int coeff_ctx =
1997 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
1998#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07001999 av1_xform_quant_fp_nuq(cm, x, 0, block, row + idy, col + idx,
2000 BLOCK_8X8, TX_4X4, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002001#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002002 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Yaowu Xuf883b422016-08-30 14:01:10 -07002003 TX_4X4, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002004#endif // CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002005 av1_optimize_b(cm, x, 0, block, TX_4X4, coeff_ctx);
Angie Chiang22ba7512016-10-20 17:10:33 -07002006 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002007 scan_order->scan, scan_order->neighbors,
2008 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002009 *(tempa + idx) = !(p->eobs[block] == 0);
2010 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002011 can_skip &= (p->eobs[block] == 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07002012 av1_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2013 dst_stride, p->eobs[block], xd->bd,
2014 tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002015 cpi->fn_ptr[BLOCK_4X4].vf(src, src_stride, dst, dst_stride, &tmp);
2016 dist = (int64_t)tmp << 4;
2017 distortion += dist;
2018 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2019 goto next_highbd;
2020 }
2021 }
2022 }
2023
2024 rate += ratey;
2025 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2026
2027 if (this_rd < best_rd) {
2028 *bestrate = rate;
2029 *bestratey = ratey;
2030 *bestdistortion = distortion;
2031 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002032 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002033 *best_mode = mode;
2034 memcpy(a, tempa, num_4x4_blocks_wide * sizeof(tempa[0]));
2035 memcpy(l, templ, num_4x4_blocks_high * sizeof(templ[0]));
2036 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
2037 memcpy(best_dst16 + idy * 8,
2038 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
2039 num_4x4_blocks_wide * 4 * sizeof(uint16_t));
2040 }
2041 }
2042 next_highbd : {}
2043 }
2044
2045 if (best_rd >= rd_thresh) return best_rd;
2046
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002047 if (y_skip) *y_skip &= best_can_skip;
2048
Yaowu Xuc27fc142016-08-22 16:08:15 -07002049 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
2050 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
2051 best_dst16 + idy * 8, num_4x4_blocks_wide * 4 * sizeof(uint16_t));
2052 }
2053
2054 return best_rd;
2055 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002056#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002057
2058 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2059 int64_t this_rd;
2060 int ratey = 0;
2061 int64_t distortion = 0;
2062 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002063 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002064
2065 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode))) continue;
2066
2067 // Only do the oblique modes if the best so far is
2068 // one of the neighboring directional modes
2069 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2070 if (conditional_skipintra(mode, *best_mode)) continue;
2071 }
2072
2073 memcpy(tempa, ta, num_4x4_blocks_wide * sizeof(ta[0]));
2074 memcpy(templ, tl, num_4x4_blocks_high * sizeof(tl[0]));
2075
2076 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
2077 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
2078 const int block = (row + idy) * 2 + (col + idx);
2079 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2080 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
2081 int16_t *const src_diff =
Yaowu Xuf883b422016-08-30 14:01:10 -07002082 av1_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002083 xd->mi[0]->bmi[block].as_mode = mode;
Jingning Hanc4c99da2016-10-24 10:27:28 -07002084 av1_predict_intra_block(xd, pd->width, pd->height, TX_4X4, mode, dst,
2085 dst_stride, dst, dst_stride, col + idx,
2086 row + idy, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07002087 aom_subtract_block(4, 4, src_diff, 8, src, src_stride, dst, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002088
2089 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
2090 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002091 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002092 const int coeff_ctx =
2093 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002094#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002095 av1_xform_quant_fp_nuq(cm, x, 0, block, row + idy, col + idx,
2096 BLOCK_8X8, TX_4X4, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002097#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002098 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2099 TX_4X4, AV1_XFORM_QUANT_B);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002100#endif // CONFIG_NEW_QUANT
Angie Chiang22ba7512016-10-20 17:10:33 -07002101 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002102 scan_order->scan, scan_order->neighbors,
2103 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002104 *(tempa + idx) = !(p->eobs[block] == 0);
2105 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002106 can_skip &= (p->eobs[block] == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002107 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2108 goto next;
Yaowu Xuf883b422016-08-30 14:01:10 -07002109 av1_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2110 dst_stride, p->eobs[block], DCT_DCT, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002111 } else {
2112 int64_t dist;
2113 unsigned int tmp;
2114 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002115 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002116 const int coeff_ctx =
2117 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
2118#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002119 av1_xform_quant_fp_nuq(cm, x, 0, block, row + idy, col + idx,
2120 BLOCK_8X8, TX_4X4, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002121#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002122 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2123 TX_4X4, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002124#endif // CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002125 av1_optimize_b(cm, x, 0, block, TX_4X4, coeff_ctx);
Angie Chiang22ba7512016-10-20 17:10:33 -07002126 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002127 scan_order->scan, scan_order->neighbors,
2128 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002129 *(tempa + idx) = !(p->eobs[block] == 0);
2130 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002131 can_skip &= (p->eobs[block] == 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07002132 av1_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2133 dst_stride, p->eobs[block], tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002134 cpi->fn_ptr[BLOCK_4X4].vf(src, src_stride, dst, dst_stride, &tmp);
2135 dist = (int64_t)tmp << 4;
2136 distortion += dist;
2137 // To use the pixel domain distortion, the step below needs to be
2138 // put behind the inv txfm. Compared to calculating the distortion
2139 // in the frequency domain, the overhead of encoding effort is low.
2140 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2141 goto next;
2142 }
2143 }
2144 }
2145
2146 rate += ratey;
2147 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2148
2149 if (this_rd < best_rd) {
2150 *bestrate = rate;
2151 *bestratey = ratey;
2152 *bestdistortion = distortion;
2153 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002154 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002155 *best_mode = mode;
2156 memcpy(a, tempa, num_4x4_blocks_wide * sizeof(tempa[0]));
2157 memcpy(l, templ, num_4x4_blocks_high * sizeof(templ[0]));
2158 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
2159 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
2160 num_4x4_blocks_wide * 4);
2161 }
2162 next : {}
2163 }
2164
2165 if (best_rd >= rd_thresh) return best_rd;
2166
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002167 if (y_skip) *y_skip &= best_can_skip;
2168
Yaowu Xuc27fc142016-08-22 16:08:15 -07002169 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
2170 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
2171 num_4x4_blocks_wide * 4);
2172
2173 return best_rd;
2174}
2175
Urvang Joshi52648442016-10-13 17:27:51 -07002176static int64_t rd_pick_intra_sub_8x8_y_mode(const AV1_COMP *const cpi,
2177 MACROBLOCK *mb, int *rate,
2178 int *rate_y, int64_t *distortion,
2179 int *y_skip, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002180 int i, j;
2181 const MACROBLOCKD *const xd = &mb->e_mbd;
2182 MODE_INFO *const mic = xd->mi[0];
2183 const MODE_INFO *above_mi = xd->above_mi;
2184 const MODE_INFO *left_mi = xd->left_mi;
2185 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
2186 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2187 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2188 int idx, idy;
2189 int cost = 0;
2190 int64_t total_distortion = 0;
2191 int tot_rate_y = 0;
2192 int64_t total_rd = 0;
2193 const int *bmode_costs = cpi->mbmode_cost[0];
2194
2195#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002196 mic->mbmi.intra_filter = INTRA_FILTER_LINEAR;
2197#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002198#if CONFIG_FILTER_INTRA
2199 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2200#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002201
2202 // TODO(any): Add search of the tx_type to improve rd performance at the
2203 // expense of speed.
2204 mic->mbmi.tx_type = DCT_DCT;
2205 mic->mbmi.tx_size = TX_4X4;
2206
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002207 if (y_skip) *y_skip = 1;
2208
Yaowu Xuc27fc142016-08-22 16:08:15 -07002209 // Pick modes for each sub-block (of size 4x4, 4x8, or 8x4) in an 8x8 block.
2210 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
2211 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
2212 PREDICTION_MODE best_mode = DC_PRED;
2213 int r = INT_MAX, ry = INT_MAX;
2214 int64_t d = INT64_MAX, this_rd = INT64_MAX;
2215 i = idy * 2 + idx;
2216 if (cpi->common.frame_type == KEY_FRAME) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002217 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, i);
2218 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, i);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002219
2220 bmode_costs = cpi->y_mode_costs[A][L];
2221 }
2222
2223 this_rd = rd_pick_intra4x4block(
2224 cpi, mb, idy, idx, &best_mode, bmode_costs,
2225 xd->plane[0].above_context + idx, xd->plane[0].left_context + idy, &r,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002226 &ry, &d, bsize, y_skip, best_rd - total_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002227 if (this_rd >= best_rd - total_rd) return INT64_MAX;
2228
2229 total_rd += this_rd;
2230 cost += r;
2231 total_distortion += d;
2232 tot_rate_y += ry;
2233
2234 mic->bmi[i].as_mode = best_mode;
2235 for (j = 1; j < num_4x4_blocks_high; ++j)
2236 mic->bmi[i + j * 2].as_mode = best_mode;
2237 for (j = 1; j < num_4x4_blocks_wide; ++j)
2238 mic->bmi[i + j].as_mode = best_mode;
2239
2240 if (total_rd >= best_rd) return INT64_MAX;
2241 }
2242 }
2243 mic->mbmi.mode = mic->bmi[3].as_mode;
2244
2245 // Add in the cost of the transform type
2246 if (!xd->lossless[mic->mbmi.segment_id]) {
2247 int rate_tx_type = 0;
2248#if CONFIG_EXT_TX
2249 if (get_ext_tx_types(TX_4X4, bsize, 0) > 1) {
2250 const int eset = get_ext_tx_set(TX_4X4, bsize, 0);
clang-format67948d32016-09-07 22:40:40 -07002251 rate_tx_type = cpi->intra_tx_type_costs[eset][TX_4X4][mic->mbmi.mode]
2252 [mic->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002253 }
2254#else
clang-format67948d32016-09-07 22:40:40 -07002255 rate_tx_type =
2256 cpi->intra_tx_type_costs[TX_4X4]
2257 [intra_mode_to_tx_type_context[mic->mbmi.mode]]
2258 [mic->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002259#endif
2260 assert(mic->mbmi.tx_size == TX_4X4);
2261 cost += rate_tx_type;
2262 tot_rate_y += rate_tx_type;
2263 }
2264
2265 *rate = cost;
2266 *rate_y = tot_rate_y;
2267 *distortion = total_distortion;
2268
2269 return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
2270}
2271
hui su5db97432016-10-14 16:10:14 -07002272#if CONFIG_FILTER_INTRA
2273// Return 1 if an filter intra mode is selected; return 0 otherwise.
2274static int rd_pick_filter_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2275 int *rate, int *rate_tokenonly,
2276 int64_t *distortion, int *skippable,
2277 BLOCK_SIZE bsize, int mode_cost,
2278 int64_t *best_rd, uint16_t skip_mask) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002279 MACROBLOCKD *const xd = &x->e_mbd;
2280 MODE_INFO *const mic = xd->mi[0];
2281 MB_MODE_INFO *mbmi = &mic->mbmi;
2282 int this_rate, this_rate_tokenonly, s;
hui su5db97432016-10-14 16:10:14 -07002283 int filter_intra_selected_flag = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002284 int64_t this_distortion, this_rd;
hui su5db97432016-10-14 16:10:14 -07002285 FILTER_INTRA_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002286 TX_SIZE best_tx_size = TX_4X4;
hui su5db97432016-10-14 16:10:14 -07002287 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002288 TX_TYPE best_tx_type;
2289
hui su5db97432016-10-14 16:10:14 -07002290 av1_zero(filter_intra_mode_info);
2291 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002292 mbmi->mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07002293#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002294 mbmi->palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002295#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002296
2297 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
2298 if (skip_mask & (1 << mode)) continue;
hui su5db97432016-10-14 16:10:14 -07002299 mbmi->filter_intra_mode_info.filter_intra_mode[0] = mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002300 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s, NULL,
2301 bsize, *best_rd);
2302 if (this_rate_tokenonly == INT_MAX) continue;
2303
2304 this_rate = this_rate_tokenonly +
hui su5db97432016-10-14 16:10:14 -07002305 av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07002306 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
2307 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
2308
2309 if (this_rd < *best_rd) {
2310 *best_rd = this_rd;
2311 best_tx_size = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07002312 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002313 best_tx_type = mic->mbmi.tx_type;
2314 *rate = this_rate;
2315 *rate_tokenonly = this_rate_tokenonly;
2316 *distortion = this_distortion;
2317 *skippable = s;
hui su5db97432016-10-14 16:10:14 -07002318 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002319 }
2320 }
2321
hui su5db97432016-10-14 16:10:14 -07002322 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002323 mbmi->mode = DC_PRED;
2324 mbmi->tx_size = best_tx_size;
hui su5db97432016-10-14 16:10:14 -07002325 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] =
2326 filter_intra_mode_info.use_filter_intra_mode[0];
2327 mbmi->filter_intra_mode_info.filter_intra_mode[0] =
2328 filter_intra_mode_info.filter_intra_mode[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002329 mbmi->tx_type = best_tx_type;
2330 return 1;
2331 } else {
2332 return 0;
2333 }
2334}
hui su5db97432016-10-14 16:10:14 -07002335#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002336
hui su5db97432016-10-14 16:10:14 -07002337#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002338static void pick_intra_angle_routine_sby(
Urvang Joshi52648442016-10-13 17:27:51 -07002339 const AV1_COMP *const cpi, MACROBLOCK *x, int *rate, int *rate_tokenonly,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002340 int64_t *distortion, int *skippable, int *best_angle_delta,
2341 TX_SIZE *best_tx_size, TX_TYPE *best_tx_type, INTRA_FILTER *best_filter,
2342 BLOCK_SIZE bsize, int rate_overhead, int64_t *best_rd) {
2343 int this_rate, this_rate_tokenonly, s;
2344 int64_t this_distortion, this_rd;
2345 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
2346 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s, NULL,
2347 bsize, *best_rd);
2348 if (this_rate_tokenonly == INT_MAX) return;
2349
2350 this_rate = this_rate_tokenonly + rate_overhead;
2351 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
2352
2353 if (this_rd < *best_rd) {
2354 *best_rd = this_rd;
2355 *best_angle_delta = mbmi->angle_delta[0];
2356 *best_tx_size = mbmi->tx_size;
2357 *best_filter = mbmi->intra_filter;
2358 *best_tx_type = mbmi->tx_type;
2359 *rate = this_rate;
2360 *rate_tokenonly = this_rate_tokenonly;
2361 *distortion = this_distortion;
2362 *skippable = s;
2363 }
2364}
2365
Urvang Joshi52648442016-10-13 17:27:51 -07002366static int64_t rd_pick_intra_angle_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2367 int *rate, int *rate_tokenonly,
2368 int64_t *distortion, int *skippable,
2369 BLOCK_SIZE bsize, int rate_overhead,
2370 int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002371 MACROBLOCKD *const xd = &x->e_mbd;
2372 MODE_INFO *const mic = xd->mi[0];
2373 MB_MODE_INFO *mbmi = &mic->mbmi;
2374 int this_rate, this_rate_tokenonly, s;
2375 int angle_delta, best_angle_delta = 0, p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07002376 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002377 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
2378 const double rd_adjust = 1.2;
2379 int64_t this_distortion, this_rd;
2380 TX_SIZE best_tx_size = mic->mbmi.tx_size;
2381 TX_TYPE best_tx_type = mbmi->tx_type;
2382
2383 if (ANGLE_FAST_SEARCH) {
2384 int deltas_level1[3] = { 0, -2, 2 };
2385 int deltas_level2[3][2] = {
2386 { -1, 1 }, { -3, -1 }, { 1, 3 },
2387 };
2388 const int level1 = 3, level2 = 2;
2389 int i, j, best_i = -1;
2390
2391 for (i = 0; i < level1; ++i) {
2392 mic->mbmi.angle_delta[0] = deltas_level1[i];
2393 p_angle =
2394 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
2395 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2396 int64_t tmp_best_rd;
Yaowu Xuf883b422016-08-30 14:01:10 -07002397 if ((FILTER_FAST_SEARCH || !av1_is_intra_filter_switchable(p_angle)) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002398 filter != INTRA_FILTER_LINEAR)
2399 continue;
2400 mic->mbmi.intra_filter = filter;
2401 tmp_best_rd =
2402 (i == 0 && filter == INTRA_FILTER_LINEAR && best_rd < INT64_MAX)
2403 ? (int64_t)(best_rd * rd_adjust)
2404 : best_rd;
2405 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s,
2406 NULL, bsize, tmp_best_rd);
2407 if (this_rate_tokenonly == INT_MAX) {
2408 if (i == 0 && filter == INTRA_FILTER_LINEAR)
2409 return best_rd;
2410 else
2411 continue;
2412 }
2413 this_rate = this_rate_tokenonly + rate_overhead +
2414 cpi->intra_filter_cost[intra_filter_ctx][filter];
2415 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
2416 if (i == 0 && filter == INTRA_FILTER_LINEAR && best_rd < INT64_MAX &&
2417 this_rd > best_rd * rd_adjust)
2418 return best_rd;
2419 if (this_rd < best_rd) {
2420 best_i = i;
2421 best_rd = this_rd;
2422 best_angle_delta = mbmi->angle_delta[0];
2423 best_tx_size = mbmi->tx_size;
2424 best_filter = mbmi->intra_filter;
2425 best_tx_type = mbmi->tx_type;
2426 *rate = this_rate;
2427 *rate_tokenonly = this_rate_tokenonly;
2428 *distortion = this_distortion;
2429 *skippable = s;
2430 }
2431 }
2432 }
2433
2434 if (best_i >= 0) {
2435 for (j = 0; j < level2; ++j) {
2436 mic->mbmi.angle_delta[0] = deltas_level2[best_i][j];
2437 p_angle =
2438 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
2439 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2440 mic->mbmi.intra_filter = filter;
2441 if ((FILTER_FAST_SEARCH ||
Yaowu Xuf883b422016-08-30 14:01:10 -07002442 !av1_is_intra_filter_switchable(p_angle)) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002443 filter != INTRA_FILTER_LINEAR)
2444 continue;
2445 pick_intra_angle_routine_sby(
2446 cpi, x, rate, rate_tokenonly, distortion, skippable,
2447 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
2448 bsize,
2449 rate_overhead + cpi->intra_filter_cost[intra_filter_ctx][filter],
2450 &best_rd);
2451 }
2452 }
2453 }
2454 } else {
2455 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
2456 ++angle_delta) {
2457 mbmi->angle_delta[0] = angle_delta;
2458 p_angle =
2459 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
2460 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2461 mic->mbmi.intra_filter = filter;
Yaowu Xuf883b422016-08-30 14:01:10 -07002462 if ((FILTER_FAST_SEARCH || !av1_is_intra_filter_switchable(p_angle)) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002463 filter != INTRA_FILTER_LINEAR)
2464 continue;
2465 pick_intra_angle_routine_sby(
2466 cpi, x, rate, rate_tokenonly, distortion, skippable,
2467 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
2468 bsize,
2469 rate_overhead + cpi->intra_filter_cost[intra_filter_ctx][filter],
2470 &best_rd);
2471 }
2472 }
2473 }
2474
2475 if (FILTER_FAST_SEARCH && *rate_tokenonly < INT_MAX) {
2476 mbmi->angle_delta[0] = best_angle_delta;
2477 p_angle = mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07002478 if (av1_is_intra_filter_switchable(p_angle)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002479 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
2480 mic->mbmi.intra_filter = filter;
2481 pick_intra_angle_routine_sby(
2482 cpi, x, rate, rate_tokenonly, distortion, skippable,
2483 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
2484 bsize,
2485 rate_overhead + cpi->intra_filter_cost[intra_filter_ctx][filter],
2486 &best_rd);
2487 }
2488 }
2489 }
2490
2491 mbmi->tx_size = best_tx_size;
2492 mbmi->angle_delta[0] = best_angle_delta;
2493 mic->mbmi.intra_filter = best_filter;
2494 mbmi->tx_type = best_tx_type;
2495 return best_rd;
2496}
2497
2498// Indices are sign, integer, and fractional part of the gradient value
2499static const uint8_t gradient_to_angle_bin[2][7][16] = {
2500 {
2501 { 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0 },
2502 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
2503 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
2504 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 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 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2507 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2508 },
2509 {
2510 { 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4 },
2511 { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3 },
2512 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2513 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 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, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2516 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2517 },
2518};
2519
2520static const uint8_t mode_to_angle_bin[INTRA_MODES] = {
2521 0, 2, 6, 0, 4, 3, 5, 7, 1, 0,
2522};
2523
2524static void angle_estimation(const uint8_t *src, int src_stride, int rows,
2525 int cols, uint8_t *directional_mode_skip_mask) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002526 int i, r, c, index, dx, dy, temp, sn, remd, quot;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002527 uint64_t hist[DIRECTIONAL_MODES];
2528 uint64_t hist_sum = 0;
2529
2530 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
2531 src += src_stride;
2532 for (r = 1; r < rows; ++r) {
2533 for (c = 1; c < cols; ++c) {
2534 dx = src[c] - src[c - 1];
2535 dy = src[c] - src[c - src_stride];
2536 temp = dx * dx + dy * dy;
2537 if (dy == 0) {
2538 index = 2;
2539 } else {
2540 sn = (dx > 0) ^ (dy > 0);
2541 dx = abs(dx);
2542 dy = abs(dy);
2543 remd = dx % dy;
2544 quot = dx / dy;
2545 remd = remd * 16 / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07002546 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002547 }
2548 hist[index] += temp;
2549 }
2550 src += src_stride;
2551 }
2552
2553 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
2554 for (i = 0; i < INTRA_MODES; ++i) {
2555 if (i != DC_PRED && i != TM_PRED) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002556 const uint8_t angle_bin = mode_to_angle_bin[i];
2557 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002558 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07002559 if (angle_bin > 0) {
2560 score += hist[angle_bin - 1];
2561 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002562 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07002563 if (angle_bin < DIRECTIONAL_MODES - 1) {
2564 score += hist[angle_bin + 1];
2565 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002566 }
2567 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
2568 directional_mode_skip_mask[i] = 1;
2569 }
2570 }
2571}
2572
Yaowu Xuf883b422016-08-30 14:01:10 -07002573#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002574static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
2575 int rows, int cols,
2576 uint8_t *directional_mode_skip_mask) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002577 int i, r, c, index, dx, dy, temp, sn, remd, quot;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002578 uint64_t hist[DIRECTIONAL_MODES];
2579 uint64_t hist_sum = 0;
2580 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
2581
2582 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
2583 src += src_stride;
2584 for (r = 1; r < rows; ++r) {
2585 for (c = 1; c < cols; ++c) {
2586 dx = src[c] - src[c - 1];
2587 dy = src[c] - src[c - src_stride];
2588 temp = dx * dx + dy * dy;
2589 if (dy == 0) {
2590 index = 2;
2591 } else {
2592 sn = (dx > 0) ^ (dy > 0);
2593 dx = abs(dx);
2594 dy = abs(dy);
2595 remd = dx % dy;
2596 quot = dx / dy;
2597 remd = remd * 16 / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07002598 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002599 }
2600 hist[index] += temp;
2601 }
2602 src += src_stride;
2603 }
2604
2605 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
2606 for (i = 0; i < INTRA_MODES; ++i) {
2607 if (i != DC_PRED && i != TM_PRED) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002608 const uint8_t angle_bin = mode_to_angle_bin[i];
2609 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002610 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07002611 if (angle_bin > 0) {
2612 score += hist[angle_bin - 1];
2613 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002614 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07002615 if (angle_bin < DIRECTIONAL_MODES - 1) {
2616 score += hist[angle_bin + 1];
2617 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002618 }
2619 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
2620 directional_mode_skip_mask[i] = 1;
2621 }
2622 }
2623}
Yaowu Xuf883b422016-08-30 14:01:10 -07002624#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002625#endif // CONFIG_EXT_INTRA
2626
2627// This function is used only for intra_only frames
Urvang Joshi52648442016-10-13 17:27:51 -07002628static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
2629 int *rate, int *rate_tokenonly,
2630 int64_t *distortion, int *skippable,
2631 BLOCK_SIZE bsize, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002632 uint8_t mode_idx;
2633 PREDICTION_MODE mode_selected = DC_PRED;
2634 MACROBLOCKD *const xd = &x->e_mbd;
2635 MODE_INFO *const mic = xd->mi[0];
2636 int this_rate, this_rate_tokenonly, s;
2637 int64_t this_distortion, this_rd;
2638 TX_SIZE best_tx = TX_4X4;
Urvang Joshib100db72016-10-12 16:28:56 -07002639#if CONFIG_EXT_INTRA || CONFIG_PALETTE
2640 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
2641 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
2642#endif // CONFIG_EXT_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002643#if CONFIG_EXT_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07002644 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002645 int is_directional_mode, rate_overhead, best_angle_delta = 0;
2646 INTRA_FILTER best_filter = INTRA_FILTER_LINEAR;
2647 uint8_t directional_mode_skip_mask[INTRA_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002648 const int src_stride = x->plane[0].src.stride;
2649 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002650#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002651#if CONFIG_FILTER_INTRA
2652 int beat_best_rd = 0;
2653 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
2654 uint16_t filter_intra_mode_skip_mask = (1 << FILTER_INTRA_MODES) - 1;
2655#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002656 TX_TYPE best_tx_type = DCT_DCT;
Urvang Joshi52648442016-10-13 17:27:51 -07002657 const int *bmode_costs;
Urvang Joshib100db72016-10-12 16:28:56 -07002658#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002659 PALETTE_MODE_INFO palette_mode_info;
2660 PALETTE_MODE_INFO *const pmi = &mic->mbmi.palette_mode_info;
2661 uint8_t *best_palette_color_map =
2662 cpi->common.allow_screen_content_tools
2663 ? x->palette_buffer->best_palette_color_map
2664 : NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002665 int palette_ctx = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002666#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002667 const MODE_INFO *above_mi = xd->above_mi;
2668 const MODE_INFO *left_mi = xd->left_mi;
Yaowu Xuf883b422016-08-30 14:01:10 -07002669 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, 0);
2670 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002671 const PREDICTION_MODE FINAL_MODE_SEARCH = TM_PRED + 1;
2672 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
2673 bmode_costs = cpi->y_mode_costs[A][L];
2674
2675#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002676 mic->mbmi.angle_delta[0] = 0;
2677 memset(directional_mode_skip_mask, 0,
2678 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
Yaowu Xuf883b422016-08-30 14:01:10 -07002679#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002680 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
2681 highbd_angle_estimation(src, src_stride, rows, cols,
2682 directional_mode_skip_mask);
2683 else
2684#endif
2685 angle_estimation(src, src_stride, rows, cols, directional_mode_skip_mask);
2686#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002687#if CONFIG_FILTER_INTRA
2688 filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2689 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2690#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07002691#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002692 palette_mode_info.palette_size[0] = 0;
2693 pmi->palette_size[0] = 0;
2694 if (above_mi)
2695 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
2696 if (left_mi)
2697 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Urvang Joshib100db72016-10-12 16:28:56 -07002698#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002699
2700 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
2701 x->use_default_intra_tx_type = 1;
2702 else
2703 x->use_default_intra_tx_type = 0;
2704
2705 /* Y Search for intra prediction mode */
2706 for (mode_idx = DC_PRED; mode_idx <= FINAL_MODE_SEARCH; ++mode_idx) {
2707 if (mode_idx == FINAL_MODE_SEARCH) {
2708 if (x->use_default_intra_tx_type == 0) break;
2709 mic->mbmi.mode = mode_selected;
2710 x->use_default_intra_tx_type = 0;
2711 } else {
2712 mic->mbmi.mode = mode_idx;
2713 }
2714#if CONFIG_EXT_INTRA
2715 is_directional_mode =
2716 (mic->mbmi.mode != DC_PRED && mic->mbmi.mode != TM_PRED);
2717 if (is_directional_mode && directional_mode_skip_mask[mic->mbmi.mode])
2718 continue;
2719 if (is_directional_mode) {
2720 rate_overhead = bmode_costs[mic->mbmi.mode] +
2721 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
2722 this_rate_tokenonly = INT_MAX;
2723 this_rd = rd_pick_intra_angle_sby(cpi, x, &this_rate,
2724 &this_rate_tokenonly, &this_distortion,
2725 &s, bsize, rate_overhead, best_rd);
2726 } else {
2727 mic->mbmi.angle_delta[0] = 0;
2728 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s, NULL,
2729 bsize, best_rd);
2730 }
2731#else
2732 super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s, NULL,
2733 bsize, best_rd);
2734#endif // CONFIG_EXT_INTRA
2735
2736 if (this_rate_tokenonly == INT_MAX) continue;
2737
2738 this_rate = this_rate_tokenonly + bmode_costs[mic->mbmi.mode];
2739
2740 if (!xd->lossless[xd->mi[0]->mbmi.segment_id]) {
2741 // super_block_yrd above includes the cost of the tx_size in the
2742 // tokenonly rate, but for intra blocks, tx_size is always coded
2743 // (prediction granularity), so we account for it in the full rate,
2744 // not the tokenonly rate.
2745 this_rate_tokenonly -=
clang-format67948d32016-09-07 22:40:40 -07002746 cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
2747 [mic->mbmi.tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002748 }
Urvang Joshib100db72016-10-12 16:28:56 -07002749#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002750 if (cpi->common.allow_screen_content_tools && mic->mbmi.mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07002751 this_rate += av1_cost_bit(
2752 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07002753#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07002754#if CONFIG_FILTER_INTRA
2755 if (mic->mbmi.mode == DC_PRED)
2756 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 0);
2757#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002758#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002759 if (is_directional_mode) {
2760 int p_angle;
2761 this_rate +=
2762 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
2763 MAX_ANGLE_DELTAS + mic->mbmi.angle_delta[0]);
2764 p_angle = mode_to_angle_map[mic->mbmi.mode] +
2765 mic->mbmi.angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07002766 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07002767 this_rate +=
2768 cpi->intra_filter_cost[intra_filter_ctx][mic->mbmi.intra_filter];
2769 }
2770#endif // CONFIG_EXT_INTRA
2771 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui su5db97432016-10-14 16:10:14 -07002772#if CONFIG_FILTER_INTRA
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07002773 if (best_rd == INT64_MAX || this_rd - best_rd < (best_rd >> 4)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002774 filter_intra_mode_skip_mask ^= (1 << mic->mbmi.mode);
2775 }
hui su5db97432016-10-14 16:10:14 -07002776#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002777
2778 if (this_rd < best_rd) {
2779 mode_selected = mic->mbmi.mode;
2780 best_rd = this_rd;
2781 best_tx = mic->mbmi.tx_size;
2782#if CONFIG_EXT_INTRA
2783 best_angle_delta = mic->mbmi.angle_delta[0];
2784 best_filter = mic->mbmi.intra_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002785#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002786#if CONFIG_FILTER_INTRA
2787 beat_best_rd = 1;
2788#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002789 best_tx_type = mic->mbmi.tx_type;
2790 *rate = this_rate;
2791 *rate_tokenonly = this_rate_tokenonly;
2792 *distortion = this_distortion;
2793 *skippable = s;
2794 }
2795 }
2796
Urvang Joshib100db72016-10-12 16:28:56 -07002797#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002798 if (cpi->common.allow_screen_content_tools)
2799 rd_pick_palette_intra_sby(cpi, x, bsize, palette_ctx, bmode_costs[DC_PRED],
2800 &palette_mode_info, best_palette_color_map,
2801 &best_tx, &best_tx_type, &mode_selected,
2802 &best_rd);
Urvang Joshib100db72016-10-12 16:28:56 -07002803#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002804
hui su5db97432016-10-14 16:10:14 -07002805#if CONFIG_FILTER_INTRA
2806 if (beat_best_rd) {
2807 if (rd_pick_filter_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
2808 skippable, bsize, bmode_costs[DC_PRED],
2809 &best_rd, filter_intra_mode_skip_mask)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002810 mode_selected = mic->mbmi.mode;
2811 best_tx = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07002812 filter_intra_mode_info = mic->mbmi.filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002813 best_tx_type = mic->mbmi.tx_type;
2814 }
2815 }
2816
hui su5db97432016-10-14 16:10:14 -07002817 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] =
2818 filter_intra_mode_info.use_filter_intra_mode[0];
2819 if (filter_intra_mode_info.use_filter_intra_mode[0]) {
2820 mic->mbmi.filter_intra_mode_info.filter_intra_mode[0] =
2821 filter_intra_mode_info.filter_intra_mode[0];
Urvang Joshib100db72016-10-12 16:28:56 -07002822#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002823 palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002824#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002825 }
hui su5db97432016-10-14 16:10:14 -07002826#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002827
2828 mic->mbmi.mode = mode_selected;
2829 mic->mbmi.tx_size = best_tx;
2830#if CONFIG_EXT_INTRA
2831 mic->mbmi.angle_delta[0] = best_angle_delta;
2832 mic->mbmi.intra_filter = best_filter;
2833#endif // CONFIG_EXT_INTRA
2834 mic->mbmi.tx_type = best_tx_type;
Urvang Joshib100db72016-10-12 16:28:56 -07002835#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002836 pmi->palette_size[0] = palette_mode_info.palette_size[0];
2837 if (palette_mode_info.palette_size[0] > 0) {
2838 memcpy(pmi->palette_colors, palette_mode_info.palette_colors,
2839 PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
2840 memcpy(xd->plane[0].color_index_map, best_palette_color_map,
2841 rows * cols * sizeof(best_palette_color_map[0]));
2842 }
Urvang Joshib100db72016-10-12 16:28:56 -07002843#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002844
2845 return best_rd;
2846}
2847
Yue Chena1e48dc2016-08-29 17:29:33 -07002848// Return value 0: early termination triggered, no valid rd cost available;
2849// 1: rd cost values are valid.
Urvang Joshi52648442016-10-13 17:27:51 -07002850static int super_block_uvrd(const AV1_COMP *const cpi, MACROBLOCK *x, int *rate,
Yue Chena1e48dc2016-08-29 17:29:33 -07002851 int64_t *distortion, int *skippable, int64_t *sse,
2852 BLOCK_SIZE bsize, int64_t ref_best_rd) {
2853 MACROBLOCKD *const xd = &x->e_mbd;
2854 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2855 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
2856 int plane;
2857 int pnrate = 0, pnskip = 1;
2858 int64_t pndist = 0, pnsse = 0;
2859 int is_cost_valid = 1;
2860
2861 if (ref_best_rd < 0) is_cost_valid = 0;
2862
2863 if (is_inter_block(mbmi) && is_cost_valid) {
Yue Chena1e48dc2016-08-29 17:29:33 -07002864 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
2865 av1_subtract_plane(x, bsize, plane);
2866 }
2867
2868 *rate = 0;
2869 *distortion = 0;
2870 *sse = 0;
2871 *skippable = 1;
2872
Yushin Cho09de28b2016-06-21 14:51:23 -07002873 if (is_cost_valid) {
2874 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
2875 txfm_rd_in_plane(x, cpi, &pnrate, &pndist, &pnskip, &pnsse, ref_best_rd,
2876 plane, bsize, uv_tx_size, cpi->sf.use_fast_coef_costing);
2877 if (pnrate == INT_MAX) {
2878 is_cost_valid = 0;
2879 break;
2880 }
2881 *rate += pnrate;
2882 *distortion += pndist;
2883 *sse += pnsse;
2884 *skippable &= pnskip;
2885 if (RDCOST(x->rdmult, x->rddiv, *rate, *distortion) > ref_best_rd &&
2886 RDCOST(x->rdmult, x->rddiv, 0, *sse) > ref_best_rd) {
2887 is_cost_valid = 0;
2888 break;
2889 }
Yue Chena1e48dc2016-08-29 17:29:33 -07002890 }
2891 }
2892
2893 if (!is_cost_valid) {
2894 // reset cost value
2895 *rate = INT_MAX;
2896 *distortion = INT64_MAX;
2897 *sse = INT64_MAX;
2898 *skippable = 0;
2899 }
2900
2901 return is_cost_valid;
2902}
2903
Yaowu Xuc27fc142016-08-22 16:08:15 -07002904#if CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07002905void av1_tx_block_rd_b(const AV1_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
2906 int blk_row, int blk_col, int plane, int block,
2907 int plane_bsize, int coeff_ctx, int *rate, int64_t *dist,
2908 int64_t *bsse, int *skip) {
Angie Chiang22ba7512016-10-20 17:10:33 -07002909 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002910 MACROBLOCKD *xd = &x->e_mbd;
2911 const struct macroblock_plane *const p = &x->plane[plane];
2912 struct macroblockd_plane *const pd = &xd->plane[plane];
2913 int64_t tmp;
2914 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
2915 PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
2916 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002917 const SCAN_ORDER *const scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07002918 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002919
2920 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
2921 int bh = 4 * num_4x4_blocks_wide_lookup[txm_bsize];
2922 int src_stride = p->src.stride;
2923 uint8_t *src = &p->src.buf[4 * blk_row * src_stride + 4 * blk_col];
2924 uint8_t *dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
Yaowu Xuf883b422016-08-30 14:01:10 -07002925#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002926 DECLARE_ALIGNED(16, uint16_t, rec_buffer16[MAX_TX_SQUARE]);
2927 uint8_t *rec_buffer;
2928#else
2929 DECLARE_ALIGNED(16, uint8_t, rec_buffer[MAX_TX_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07002930#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002931 const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
2932 const int16_t *diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
2933
2934 int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
2935 int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
2936
2937#if CONFIG_EXT_TX
2938 assert(tx_size < TX_SIZES);
2939#endif // CONFIG_EXT_TX
2940
2941 if (xd->mb_to_bottom_edge < 0)
2942 max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
2943 if (xd->mb_to_right_edge < 0)
2944 max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
2945
2946#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002947 av1_xform_quant_fp_nuq(cm, x, plane, block, blk_row, blk_col, plane_bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -07002948 tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002949#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002950 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Yaowu Xuf883b422016-08-30 14:01:10 -07002951 AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002952#endif // CONFIG_NEW_QUANT
2953
Angie Chiangff6d8902016-10-21 11:02:09 -07002954 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002955
2956// TODO(any): Use dist_block to compute distortion
Yaowu Xuf883b422016-08-30 14:01:10 -07002957#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002958 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2959 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer16);
Yaowu Xuf883b422016-08-30 14:01:10 -07002960 aom_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002961 0, NULL, 0, bh, bh, xd->bd);
2962 } else {
2963 rec_buffer = (uint8_t *)rec_buffer16;
Yaowu Xuf883b422016-08-30 14:01:10 -07002964 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002965 NULL, 0, bh, bh);
2966 }
2967#else
Yaowu Xuf883b422016-08-30 14:01:10 -07002968 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0, NULL,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002969 0, bh, bh);
Yaowu Xuf883b422016-08-30 14:01:10 -07002970#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002971
2972 if (blk_row + (bh >> 2) > max_blocks_high ||
2973 blk_col + (bh >> 2) > max_blocks_wide) {
2974 int idx, idy;
Yaowu Xuf883b422016-08-30 14:01:10 -07002975 int blocks_height = AOMMIN(bh >> 2, max_blocks_high - blk_row);
2976 int blocks_width = AOMMIN(bh >> 2, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002977 tmp = 0;
2978 for (idy = 0; idy < blocks_height; idy += 2) {
2979 for (idx = 0; idx < blocks_width; idx += 2) {
2980 const int16_t *d = diff + 4 * idy * diff_stride + 4 * idx;
Yaowu Xuf883b422016-08-30 14:01:10 -07002981 tmp += aom_sum_squares_2d_i16(d, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002982 }
2983 }
2984 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07002985 tmp = aom_sum_squares_2d_i16(diff, diff_stride, bh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002986 }
2987
Yaowu Xuf883b422016-08-30 14:01:10 -07002988#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002989 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
2990 tmp = ROUND_POWER_OF_TWO(tmp, (xd->bd - 8) * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07002991#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002992 *bsse += tmp * 16;
2993
2994 if (p->eobs[block] > 0) {
2995 INV_TXFM_PARAM inv_txfm_param;
2996 inv_txfm_param.tx_type = tx_type;
2997 inv_txfm_param.tx_size = tx_size;
2998 inv_txfm_param.eob = p->eobs[block];
2999 inv_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
Yaowu Xuf883b422016-08-30 14:01:10 -07003000#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003001 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3002 inv_txfm_param.bd = xd->bd;
3003 highbd_inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
3004 } else {
3005 inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
3006 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003007#else // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003008 inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
Yaowu Xuf883b422016-08-30 14:01:10 -07003009#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003010
3011 if ((bh >> 2) + blk_col > max_blocks_wide ||
3012 (bh >> 2) + blk_row > max_blocks_high) {
3013 int idx, idy;
3014 unsigned int this_dist;
Yaowu Xuf883b422016-08-30 14:01:10 -07003015 int blocks_height = AOMMIN(bh >> 2, max_blocks_high - blk_row);
3016 int blocks_width = AOMMIN(bh >> 2, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003017 tmp = 0;
3018 for (idy = 0; idy < blocks_height; idy += 2) {
3019 for (idx = 0; idx < blocks_width; idx += 2) {
3020 uint8_t *const s = src + 4 * idy * src_stride + 4 * idx;
3021 uint8_t *const r = rec_buffer + 4 * idy * MAX_TX_SIZE + 4 * idx;
3022 cpi->fn_ptr[BLOCK_8X8].vf(s, src_stride, r, MAX_TX_SIZE, &this_dist);
3023 tmp += this_dist;
3024 }
3025 }
3026 } else {
3027 uint32_t this_dist;
3028 cpi->fn_ptr[txm_bsize].vf(src, src_stride, rec_buffer, MAX_TX_SIZE,
3029 &this_dist);
3030 tmp = this_dist;
3031 }
3032 }
3033 *dist += tmp * 16;
Angie Chiang22ba7512016-10-20 17:10:33 -07003034 *rate += av1_cost_coeffs(cm, x, plane, block, coeff_ctx, tx_size,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003035 scan_order->scan, scan_order->neighbors, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003036 *skip &= (p->eobs[block] == 0);
3037}
3038
Yaowu Xuf883b422016-08-30 14:01:10 -07003039static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003040 int blk_col, int plane, int block, TX_SIZE tx_size,
Jingning Han94d5bfc2016-10-21 10:14:36 -07003041 int depth, BLOCK_SIZE plane_bsize,
3042 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
3043 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
3044 int *rate, int64_t *dist, int64_t *bsse, int *skip,
3045 int64_t ref_best_rd, int *is_cost_valid) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003046 MACROBLOCKD *const xd = &x->e_mbd;
3047 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3048 struct macroblock_plane *const p = &x->plane[plane];
3049 struct macroblockd_plane *const pd = &xd->plane[plane];
3050 const int tx_row = blk_row >> (1 - pd->subsampling_y);
3051 const int tx_col = blk_col >> (1 - pd->subsampling_x);
clang-format67948d32016-09-07 22:40:40 -07003052 TX_SIZE(*const inter_tx_size)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003053 [MAX_MIB_SIZE] =
3054 (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
3055 const int bw = num_4x4_blocks_wide_lookup[plane_bsize];
3056 int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
3057 int max_blocks_wide = bw;
3058 int64_t this_rd = INT64_MAX;
3059 ENTROPY_CONTEXT *pta = ta + blk_col;
3060 ENTROPY_CONTEXT *ptl = tl + blk_row;
3061 ENTROPY_CONTEXT stxa = 0, stxl = 0;
3062 int coeff_ctx, i;
3063 int ctx = txfm_partition_context(tx_above + (blk_col >> 1),
3064 tx_left + (blk_row >> 1), tx_size);
3065
3066 int64_t sum_dist = 0, sum_bsse = 0;
3067 int64_t sum_rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07003068 int sum_rate = av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003069 int all_skip = 1;
3070 int tmp_eob = 0;
3071 int zero_blk_rate;
3072
3073#if CONFIG_EXT_TX
3074 assert(tx_size < TX_SIZES);
3075#endif // CONFIG_EXT_TX
3076
3077 if (ref_best_rd < 0) {
3078 *is_cost_valid = 0;
3079 return;
3080 }
3081
3082 switch (tx_size) {
3083 case TX_4X4:
3084 stxa = pta[0];
3085 stxl = ptl[0];
3086 break;
3087 case TX_8X8:
3088 stxa = !!*(const uint16_t *)&pta[0];
3089 stxl = !!*(const uint16_t *)&ptl[0];
3090 break;
3091 case TX_16X16:
3092 stxa = !!*(const uint32_t *)&pta[0];
3093 stxl = !!*(const uint32_t *)&ptl[0];
3094 break;
3095 case TX_32X32:
3096 stxa = !!*(const uint64_t *)&pta[0];
3097 stxl = !!*(const uint64_t *)&ptl[0];
3098 break;
3099 default: assert(0 && "Invalid transform size."); break;
3100 }
3101 coeff_ctx = combine_entropy_contexts(stxa, stxl);
3102
3103 if (xd->mb_to_bottom_edge < 0)
3104 max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
3105 if (xd->mb_to_right_edge < 0)
3106 max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
3107
3108 *rate = 0;
3109 *dist = 0;
3110 *bsse = 0;
3111 *skip = 1;
3112
3113 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
3114
3115 zero_blk_rate =
3116 x->token_costs[tx_size][pd->plane_type][1][0][0][coeff_ctx][EOB_TOKEN];
3117
3118 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
3119 inter_tx_size[0][0] = tx_size;
Yaowu Xuf883b422016-08-30 14:01:10 -07003120 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
3121 plane_bsize, coeff_ctx, rate, dist, bsse, skip);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003122
3123 if ((RDCOST(x->rdmult, x->rddiv, *rate, *dist) >=
3124 RDCOST(x->rdmult, x->rddiv, zero_blk_rate, *bsse) ||
3125 *skip == 1) &&
3126 !xd->lossless[mbmi->segment_id]) {
3127 *rate = zero_blk_rate;
3128 *dist = *bsse;
3129 *skip = 1;
3130 x->blk_skip[plane][blk_row * bw + blk_col] = 1;
3131 p->eobs[block] = 0;
3132 } else {
3133 x->blk_skip[plane][blk_row * bw + blk_col] = 0;
3134 *skip = 0;
3135 }
3136
Jingning Han571189c2016-10-24 10:38:43 -07003137 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH)
Yaowu Xuf883b422016-08-30 14:01:10 -07003138 *rate += av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003139 this_rd = RDCOST(x->rdmult, x->rddiv, *rate, *dist);
3140 tmp_eob = p->eobs[block];
3141 }
3142
Jingning Han571189c2016-10-24 10:38:43 -07003143 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003144 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
3145 int bsl = b_height_log2_lookup[bsize];
3146 int sub_step = num_4x4_blocks_txsize_lookup[tx_size - 1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003147 int this_rate;
3148 int64_t this_dist;
3149 int64_t this_bsse;
3150 int this_skip;
3151 int this_cost_valid = 1;
3152 int64_t tmp_rd = 0;
3153
3154#if CONFIG_EXT_TX
3155 assert(tx_size < TX_SIZES);
3156#endif // CONFIG_EXT_TX
3157 --bsl;
3158 for (i = 0; i < 4 && this_cost_valid; ++i) {
3159 int offsetr = (i >> 1) << bsl;
3160 int offsetc = (i & 0x01) << bsl;
3161 select_tx_block(cpi, x, blk_row + offsetr, blk_col + offsetc, plane,
Jingning Han94d5bfc2016-10-21 10:14:36 -07003162 block + i * sub_step, tx_size - 1, depth + 1, plane_bsize,
3163 ta, tl, tx_above, tx_left, &this_rate, &this_dist,
3164 &this_bsse, &this_skip, ref_best_rd - tmp_rd,
3165 &this_cost_valid);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003166 sum_rate += this_rate;
3167 sum_dist += this_dist;
3168 sum_bsse += this_bsse;
3169 all_skip &= this_skip;
3170 tmp_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
3171 if (this_rd < tmp_rd) break;
3172 }
3173 if (this_cost_valid) sum_rd = tmp_rd;
3174 }
3175
3176 if (this_rd < sum_rd) {
3177 int idx, idy;
3178 for (i = 0; i < num_4x4_blocks_wide_txsize_lookup[tx_size]; ++i)
3179 pta[i] = !(tmp_eob == 0);
3180 for (i = 0; i < num_4x4_blocks_high_txsize_lookup[tx_size]; ++i)
3181 ptl[i] = !(tmp_eob == 0);
3182 txfm_partition_update(tx_above + (blk_col >> 1), tx_left + (blk_row >> 1),
3183 tx_size);
3184 inter_tx_size[0][0] = tx_size;
3185 for (idy = 0; idy < num_4x4_blocks_high_txsize_lookup[tx_size] / 2; ++idy)
3186 for (idx = 0; idx < num_4x4_blocks_wide_txsize_lookup[tx_size] / 2; ++idx)
3187 inter_tx_size[idy][idx] = tx_size;
3188 mbmi->tx_size = tx_size;
3189 if (this_rd == INT64_MAX) *is_cost_valid = 0;
3190 x->blk_skip[plane][blk_row * bw + blk_col] = *skip;
3191 } else {
3192 *rate = sum_rate;
3193 *dist = sum_dist;
3194 *bsse = sum_bsse;
3195 *skip = all_skip;
3196 if (sum_rd == INT64_MAX) *is_cost_valid = 0;
3197 }
3198}
3199
Yaowu Xuf883b422016-08-30 14:01:10 -07003200static void inter_block_yrd(const AV1_COMP *cpi, MACROBLOCK *x, int *rate,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003201 int64_t *distortion, int *skippable, int64_t *sse,
3202 BLOCK_SIZE bsize, int64_t ref_best_rd) {
3203 MACROBLOCKD *const xd = &x->e_mbd;
3204 int is_cost_valid = 1;
3205 int64_t this_rd = 0;
3206
3207 if (ref_best_rd < 0) is_cost_valid = 0;
3208
3209 *rate = 0;
3210 *distortion = 0;
3211 *sse = 0;
3212 *skippable = 1;
3213
3214 if (is_cost_valid) {
3215 const struct macroblockd_plane *const pd = &xd->plane[0];
3216 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
3217 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
3218 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
3219 BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[plane_bsize]];
3220 int bh = num_4x4_blocks_wide_lookup[txb_size];
3221 int idx, idy;
3222 int block = 0;
3223 int step = 1 << (max_txsize_lookup[plane_bsize] * 2);
3224 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
3225 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
3226 TXFM_CONTEXT tx_above[MAX_MIB_SIZE];
3227 TXFM_CONTEXT tx_left[MAX_MIB_SIZE];
3228
3229 int pnrate = 0, pnskip = 1;
3230 int64_t pndist = 0, pnsse = 0;
3231
Yaowu Xuf883b422016-08-30 14:01:10 -07003232 av1_get_entropy_contexts(bsize, TX_4X4, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003233 memcpy(tx_above, xd->above_txfm_context,
3234 sizeof(TXFM_CONTEXT) * (mi_width >> 1));
3235 memcpy(tx_left, xd->left_txfm_context,
3236 sizeof(TXFM_CONTEXT) * (mi_height >> 1));
3237
3238 for (idy = 0; idy < mi_height; idy += bh) {
3239 for (idx = 0; idx < mi_width; idx += bh) {
3240 select_tx_block(cpi, x, idy, idx, 0, block,
Jingning Han94d5bfc2016-10-21 10:14:36 -07003241 max_txsize_lookup[plane_bsize], mi_height != mi_width,
3242 plane_bsize, ctxa, ctxl, tx_above, tx_left, &pnrate,
3243 &pndist, &pnsse, &pnskip, ref_best_rd - this_rd,
3244 &is_cost_valid);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003245 *rate += pnrate;
3246 *distortion += pndist;
3247 *sse += pnsse;
3248 *skippable &= pnskip;
Yaowu Xuf883b422016-08-30 14:01:10 -07003249 this_rd += AOMMIN(RDCOST(x->rdmult, x->rddiv, pnrate, pndist),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003250 RDCOST(x->rdmult, x->rddiv, 0, pnsse));
3251 block += step;
3252 }
3253 }
3254 }
3255
Yaowu Xuf883b422016-08-30 14:01:10 -07003256 this_rd = AOMMIN(RDCOST(x->rdmult, x->rddiv, *rate, *distortion),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003257 RDCOST(x->rdmult, x->rddiv, 0, *sse));
3258 if (this_rd > ref_best_rd) is_cost_valid = 0;
3259
3260 if (!is_cost_valid) {
3261 // reset cost value
3262 *rate = INT_MAX;
3263 *distortion = INT64_MAX;
3264 *sse = INT64_MAX;
3265 *skippable = 0;
3266 }
3267}
3268
Yaowu Xuf883b422016-08-30 14:01:10 -07003269static int64_t select_tx_size_fix_type(const AV1_COMP *cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003270 int *rate, int64_t *dist, int *skippable,
3271 int64_t *sse, BLOCK_SIZE bsize,
3272 int64_t ref_best_rd, TX_TYPE tx_type) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003273 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003274 MACROBLOCKD *const xd = &x->e_mbd;
3275 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003276 const int is_inter = is_inter_block(mbmi);
Yaowu Xuf883b422016-08-30 14:01:10 -07003277 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
3278 int s0 = av1_cost_bit(skip_prob, 0);
3279 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003280 int64_t rd;
3281
3282 mbmi->tx_type = tx_type;
3283 inter_block_yrd(cpi, x, rate, dist, skippable, sse, bsize, ref_best_rd);
Yue Chena1e48dc2016-08-29 17:29:33 -07003284#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07003285 if (is_rect_tx_allowed(xd, mbmi)) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003286 int rate_rect_tx, skippable_rect_tx = 0;
Urvang Joshi368fbc92016-10-17 16:31:34 -07003287 int64_t dist_rect_tx, sse_rect_tx, rd_rect_tx;
Yue Chena1e48dc2016-08-29 17:29:33 -07003288 int tx_size_cat = inter_tx_size_cat_lookup[bsize];
3289 TX_SIZE tx_size = max_txsize_rect_lookup[bsize];
3290 TX_SIZE var_tx_size = mbmi->tx_size;
3291
3292 txfm_rd_in_plane(x, cpi, &rate_rect_tx, &dist_rect_tx, &skippable_rect_tx,
3293 &sse_rect_tx, ref_best_rd, 0, bsize, tx_size,
3294 cpi->sf.use_fast_coef_costing);
3295
3296 if (*rate != INT_MAX) {
3297 *rate += av1_cost_bit(cm->fc->rect_tx_prob[tx_size_cat], 0);
3298 if (*skippable) {
3299 rd = RDCOST(x->rdmult, x->rddiv, s1, *sse);
3300 } else {
3301 rd = RDCOST(x->rdmult, x->rddiv, *rate + s0, *dist);
3302 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
3303 !(*skippable))
3304 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, *sse));
3305 }
3306 } else {
3307 rd = INT64_MAX;
3308 }
3309
3310 if (rate_rect_tx != INT_MAX) {
3311 rate_rect_tx += av1_cost_bit(cm->fc->rect_tx_prob[tx_size_cat], 1);
3312 if (skippable_rect_tx) {
3313 rd_rect_tx = RDCOST(x->rdmult, x->rddiv, s1, sse_rect_tx);
3314 } else {
3315 rd_rect_tx =
3316 RDCOST(x->rdmult, x->rddiv, rate_rect_tx + s0, dist_rect_tx);
3317 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
3318 !(skippable_rect_tx))
3319 rd_rect_tx =
3320 AOMMIN(rd_rect_tx, RDCOST(x->rdmult, x->rddiv, s1, sse_rect_tx));
3321 }
3322 } else {
3323 rd_rect_tx = INT64_MAX;
3324 }
3325
3326 if (rd_rect_tx < rd) {
3327 *rate = rate_rect_tx;
3328 *dist = dist_rect_tx;
3329 *sse = sse_rect_tx;
3330 *skippable = skippable_rect_tx;
3331 if (!xd->lossless[mbmi->segment_id]) x->blk_skip[0][0] = *skippable;
3332 mbmi->tx_size = tx_size;
3333 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
3334 } else {
3335 mbmi->tx_size = var_tx_size;
3336 }
3337 }
3338#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003339
3340 if (*rate == INT_MAX) return INT64_MAX;
3341
3342#if CONFIG_EXT_TX
Peter de Rivazc0b4d7a2016-09-08 10:55:58 +01003343 if (get_ext_tx_types(mbmi->tx_size, bsize, is_inter) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003344 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Peter de Rivazc0b4d7a2016-09-08 10:55:58 +01003345 int ext_tx_set = get_ext_tx_set(mbmi->tx_size, bsize, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003346 if (is_inter) {
3347 if (ext_tx_set > 0)
Peter de Rivazb85a5a72016-10-18 11:47:56 +01003348 *rate +=
3349 cpi->inter_tx_type_costs[ext_tx_set][txsize_sqr_map[mbmi->tx_size]]
3350 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003351 } else {
3352 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Peter de Rivazc0b4d7a2016-09-08 10:55:58 +01003353 *rate += cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->mode]
Yaowu Xuc27fc142016-08-22 16:08:15 -07003354 [mbmi->tx_type];
3355 }
3356 }
3357#else // CONFIG_EXT_TX
Peter de Rivazc0b4d7a2016-09-08 10:55:58 +01003358 if (mbmi->tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003359 if (is_inter)
Peter de Rivazc0b4d7a2016-09-08 10:55:58 +01003360 *rate += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003361 else
clang-format67948d32016-09-07 22:40:40 -07003362 *rate +=
3363 cpi->intra_tx_type_costs[mbmi->tx_size]
3364 [intra_mode_to_tx_type_context[mbmi->mode]]
3365 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003366 }
3367#endif // CONFIG_EXT_TX
3368
3369 if (*skippable)
3370 rd = RDCOST(x->rdmult, x->rddiv, s1, *sse);
3371 else
3372 rd = RDCOST(x->rdmult, x->rddiv, *rate + s0, *dist);
3373
3374 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] && !(*skippable))
Yaowu Xuf883b422016-08-30 14:01:10 -07003375 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, *sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003376
3377 return rd;
3378}
3379
Yaowu Xuf883b422016-08-30 14:01:10 -07003380static void select_tx_type_yrd(const AV1_COMP *cpi, MACROBLOCK *x, int *rate,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003381 int64_t *distortion, int *skippable,
3382 int64_t *sse, BLOCK_SIZE bsize,
3383 int64_t ref_best_rd) {
3384 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
3385 MACROBLOCKD *const xd = &x->e_mbd;
3386 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3387 int64_t rd = INT64_MAX;
3388 int64_t best_rd = INT64_MAX;
3389 TX_TYPE tx_type, best_tx_type = DCT_DCT;
3390 const int is_inter = is_inter_block(mbmi);
3391 TX_SIZE best_tx_size[MAX_MIB_SIZE][MAX_MIB_SIZE];
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07003392 TX_SIZE best_tx = max_txsize_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003393 uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
3394 const int n4 = 1 << (num_pels_log2_lookup[bsize] - 4);
3395 int idx, idy;
3396 int prune = 0;
3397#if CONFIG_EXT_TX
3398 int ext_tx_set = get_ext_tx_set(max_tx_size, bsize, is_inter);
3399#endif // CONFIG_EXT_TX
3400
3401 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
3402#if CONFIG_EXT_TX
3403 prune = prune_tx_types(cpi, bsize, x, xd, ext_tx_set);
3404#else
3405 prune = prune_tx_types(cpi, bsize, x, xd, 0);
3406#endif
3407
3408 *distortion = INT64_MAX;
3409 *rate = INT_MAX;
3410 *skippable = 0;
3411 *sse = INT64_MAX;
3412
3413 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
3414 int this_rate = 0;
3415 int this_skip = 1;
3416 int64_t this_dist = 0;
3417 int64_t this_sse = 0;
3418#if CONFIG_EXT_TX
3419 if (is_inter) {
3420 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
3421 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
3422 if (!do_tx_type_search(tx_type, prune)) continue;
3423 }
3424 } else {
3425 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
3426 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
3427 }
3428 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
3429 }
3430#else // CONFIG_EXT_TX
3431 if (max_tx_size >= TX_32X32 && tx_type != DCT_DCT) continue;
3432 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
3433 !do_tx_type_search(tx_type, prune))
3434 continue;
3435#endif // CONFIG_EXT_TX
3436 if (is_inter && x->use_default_inter_tx_type &&
3437 tx_type != get_default_tx_type(0, xd, 0, max_tx_size))
3438 continue;
3439
3440 rd = select_tx_size_fix_type(cpi, x, &this_rate, &this_dist, &this_skip,
3441 &this_sse, bsize, ref_best_rd, tx_type);
3442
3443 if (rd < best_rd) {
3444 best_rd = rd;
3445 *distortion = this_dist;
3446 *rate = this_rate;
3447 *skippable = this_skip;
3448 *sse = this_sse;
3449 best_tx_type = mbmi->tx_type;
3450 best_tx = mbmi->tx_size;
3451 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
3452 for (idy = 0; idy < xd->n8_h; ++idy)
3453 for (idx = 0; idx < xd->n8_w; ++idx)
3454 best_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
3455 }
3456 }
3457
3458 mbmi->tx_type = best_tx_type;
3459 for (idy = 0; idy < xd->n8_h; ++idy)
3460 for (idx = 0; idx < xd->n8_w; ++idx)
3461 mbmi->inter_tx_size[idy][idx] = best_tx_size[idy][idx];
3462 mbmi->tx_size = best_tx;
3463 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
3464}
3465
Yaowu Xuf883b422016-08-30 14:01:10 -07003466static void tx_block_rd(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003467 int blk_col, int plane, int block, TX_SIZE tx_size,
3468 BLOCK_SIZE plane_bsize, ENTROPY_CONTEXT *above_ctx,
3469 ENTROPY_CONTEXT *left_ctx, int *rate, int64_t *dist,
3470 int64_t *bsse, int *skip) {
3471 MACROBLOCKD *const xd = &x->e_mbd;
3472 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3473 struct macroblock_plane *const p = &x->plane[plane];
3474 struct macroblockd_plane *const pd = &xd->plane[plane];
3475 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
3476 const int tx_row = blk_row >> (1 - pd->subsampling_y);
3477 const int tx_col = blk_col >> (1 - pd->subsampling_x);
3478 TX_SIZE plane_tx_size;
3479 int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
3480 int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
3481
3482#if CONFIG_EXT_TX
3483 assert(tx_size < TX_SIZES);
3484#endif // CONFIG_EXT_TX
3485
3486 if (xd->mb_to_bottom_edge < 0)
3487 max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
3488 if (xd->mb_to_right_edge < 0)
3489 max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
3490
3491 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
3492
Debargha Mukherjee2f123402016-08-30 17:43:38 -07003493 plane_tx_size =
3494 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
3495 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003496
3497 if (tx_size == plane_tx_size) {
3498 int coeff_ctx, i;
3499 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
3500 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
3501 switch (tx_size) {
3502 case TX_4X4: break;
3503 case TX_8X8:
3504 ta[0] = !!*(const uint16_t *)&ta[0];
3505 tl[0] = !!*(const uint16_t *)&tl[0];
3506 break;
3507 case TX_16X16:
3508 ta[0] = !!*(const uint32_t *)&ta[0];
3509 tl[0] = !!*(const uint32_t *)&tl[0];
3510 break;
3511 case TX_32X32:
3512 ta[0] = !!*(const uint64_t *)&ta[0];
3513 tl[0] = !!*(const uint64_t *)&tl[0];
3514 break;
3515 default: assert(0 && "Invalid transform size."); break;
3516 }
3517 coeff_ctx = combine_entropy_contexts(ta[0], tl[0]);
Yaowu Xuf883b422016-08-30 14:01:10 -07003518 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
3519 plane_bsize, coeff_ctx, rate, dist, bsse, skip);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003520 for (i = 0; i < num_4x4_blocks_wide_txsize_lookup[tx_size]; ++i)
3521 ta[i] = !(p->eobs[block] == 0);
3522 for (i = 0; i < num_4x4_blocks_high_txsize_lookup[tx_size]; ++i)
3523 tl[i] = !(p->eobs[block] == 0);
3524 } else {
3525 int bsl = b_width_log2_lookup[bsize];
3526 int step = num_4x4_blocks_txsize_lookup[tx_size - 1];
3527 int i;
3528
3529 assert(bsl > 0);
3530 --bsl;
3531
3532 for (i = 0; i < 4; ++i) {
3533 int offsetr = (i >> 1) << bsl;
3534 int offsetc = (i & 0x01) << bsl;
3535 tx_block_rd(cpi, x, blk_row + offsetr, blk_col + offsetc, plane,
3536 block + i * step, tx_size - 1, plane_bsize, above_ctx,
3537 left_ctx, rate, dist, bsse, skip);
3538 }
3539 }
3540}
3541
3542// Return value 0: early termination triggered, no valid rd cost available;
3543// 1: rd cost values are valid.
Yaowu Xuf883b422016-08-30 14:01:10 -07003544static int inter_block_uvrd(const AV1_COMP *cpi, MACROBLOCK *x, int *rate,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003545 int64_t *distortion, int *skippable, int64_t *sse,
3546 BLOCK_SIZE bsize, int64_t ref_best_rd) {
3547 MACROBLOCKD *const xd = &x->e_mbd;
3548 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3549 int plane;
3550 int is_cost_valid = 1;
3551 int64_t this_rd;
3552
3553 if (ref_best_rd < 0) is_cost_valid = 0;
3554
Yue Chena1e48dc2016-08-29 17:29:33 -07003555 *rate = 0;
3556 *distortion = 0;
3557 *sse = 0;
3558 *skippable = 1;
3559
3560#if CONFIG_EXT_TX && CONFIG_RECT_TX
3561 if (is_rect_tx(mbmi->tx_size)) {
3562 return super_block_uvrd(cpi, x, rate, distortion, skippable, sse, bsize,
3563 ref_best_rd);
3564 }
3565#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
3566
Yaowu Xuc27fc142016-08-22 16:08:15 -07003567 if (is_inter_block(mbmi) && is_cost_valid) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003568 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
Yaowu Xuf883b422016-08-30 14:01:10 -07003569 av1_subtract_plane(x, bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003570 }
3571
Yaowu Xuc27fc142016-08-22 16:08:15 -07003572 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
3573 const struct macroblockd_plane *const pd = &xd->plane[plane];
3574 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
3575 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
3576 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
3577 BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[plane_bsize]];
3578 int bh = num_4x4_blocks_wide_lookup[txb_size];
3579 int idx, idy;
3580 int block = 0;
3581 int step = 1 << (max_txsize_lookup[plane_bsize] * 2);
3582 int pnrate = 0, pnskip = 1;
3583 int64_t pndist = 0, pnsse = 0;
3584 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE];
3585 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE];
3586
Yaowu Xuf883b422016-08-30 14:01:10 -07003587 av1_get_entropy_contexts(bsize, TX_4X4, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003588
3589 for (idy = 0; idy < mi_height; idy += bh) {
3590 for (idx = 0; idx < mi_width; idx += bh) {
3591 tx_block_rd(cpi, x, idy, idx, plane, block,
3592 max_txsize_lookup[plane_bsize], plane_bsize, ta, tl,
3593 &pnrate, &pndist, &pnsse, &pnskip);
3594 block += step;
3595 }
3596 }
3597
3598 if (pnrate == INT_MAX) {
3599 is_cost_valid = 0;
3600 break;
3601 }
3602
3603 *rate += pnrate;
3604 *distortion += pndist;
3605 *sse += pnsse;
3606 *skippable &= pnskip;
3607
Yaowu Xuf883b422016-08-30 14:01:10 -07003608 this_rd = AOMMIN(RDCOST(x->rdmult, x->rddiv, *rate, *distortion),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003609 RDCOST(x->rdmult, x->rddiv, 0, *sse));
3610
3611 if (this_rd > ref_best_rd) {
3612 is_cost_valid = 0;
3613 break;
3614 }
3615 }
3616
3617 if (!is_cost_valid) {
3618 // reset cost value
3619 *rate = INT_MAX;
3620 *distortion = INT64_MAX;
3621 *sse = INT64_MAX;
3622 *skippable = 0;
3623 }
3624
3625 return is_cost_valid;
3626}
3627#endif // CONFIG_VAR_TX
3628
Urvang Joshib100db72016-10-12 16:28:56 -07003629#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003630static void rd_pick_palette_intra_sbuv(
Urvang Joshi52648442016-10-13 17:27:51 -07003631 const AV1_COMP *const cpi, MACROBLOCK *x, int dc_mode_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003632 PALETTE_MODE_INFO *palette_mode_info, uint8_t *best_palette_color_map,
3633 PREDICTION_MODE *mode_selected, int64_t *best_rd, int *rate,
3634 int *rate_tokenonly, int64_t *distortion, int *skippable) {
3635 MACROBLOCKD *const xd = &x->e_mbd;
3636 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3637 const BLOCK_SIZE bsize = mbmi->sb_type;
3638 const int rows =
3639 (4 * num_4x4_blocks_high_lookup[bsize]) >> (xd->plane[1].subsampling_y);
3640 const int cols =
3641 (4 * num_4x4_blocks_wide_lookup[bsize]) >> (xd->plane[1].subsampling_x);
3642 int this_rate, this_rate_tokenonly, s;
3643 int64_t this_distortion, this_rd;
3644 int colors_u, colors_v, colors;
3645 const int src_stride = x->plane[1].src.stride;
3646 const uint8_t *const src_u = x->plane[1].src.buf;
3647 const uint8_t *const src_v = x->plane[2].src.buf;
3648
3649 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return;
3650
hui su5db97432016-10-14 16:10:14 -07003651#if CONFIG_FILTER_INTRA
3652 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
3653#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003654
Yaowu Xuf883b422016-08-30 14:01:10 -07003655#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003656 if (cpi->common.use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003657 colors_u = av1_count_colors_highbd(src_u, src_stride, rows, cols,
3658 cpi->common.bit_depth);
3659 colors_v = av1_count_colors_highbd(src_v, src_stride, rows, cols,
3660 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003661 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003662#endif // CONFIG_AOM_HIGHBITDEPTH
3663 colors_u = av1_count_colors(src_u, src_stride, rows, cols);
3664 colors_v = av1_count_colors(src_v, src_stride, rows, cols);
3665#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003666 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003667#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003668
3669 colors = colors_u > colors_v ? colors_u : colors_v;
3670 if (colors > 1 && colors <= 64) {
3671 int r, c, n, i, j;
3672 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07003673 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003674 int64_t this_sse;
3675 float lb_u, ub_u, val_u;
3676 float lb_v, ub_v, val_v;
3677 float *const data = x->palette_buffer->kmeans_data_buf;
3678 float centroids[2 * PALETTE_MAX_SIZE];
3679 uint8_t *const color_map = xd->plane[1].color_index_map;
3680 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
3681
Yaowu Xuf883b422016-08-30 14:01:10 -07003682#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003683 uint16_t *src_u16 = CONVERT_TO_SHORTPTR(src_u);
3684 uint16_t *src_v16 = CONVERT_TO_SHORTPTR(src_v);
3685 if (cpi->common.use_highbitdepth) {
3686 lb_u = src_u16[0];
3687 ub_u = src_u16[0];
3688 lb_v = src_v16[0];
3689 ub_v = src_v16[0];
3690 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003691#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003692 lb_u = src_u[0];
3693 ub_u = src_u[0];
3694 lb_v = src_v[0];
3695 ub_v = src_v[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07003696#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003697 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003698#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003699
3700 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07003701#if CONFIG_FILTER_INTRA
3702 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
3703#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003704 for (r = 0; r < rows; ++r) {
3705 for (c = 0; c < cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003706#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003707 if (cpi->common.use_highbitdepth) {
3708 val_u = src_u16[r * src_stride + c];
3709 val_v = src_v16[r * src_stride + c];
3710 data[(r * cols + c) * 2] = val_u;
3711 data[(r * cols + c) * 2 + 1] = val_v;
3712 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003713#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003714 val_u = src_u[r * src_stride + c];
3715 val_v = src_v[r * src_stride + c];
3716 data[(r * cols + c) * 2] = val_u;
3717 data[(r * cols + c) * 2 + 1] = val_v;
Yaowu Xuf883b422016-08-30 14:01:10 -07003718#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003719 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003720#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003721 if (val_u < lb_u)
3722 lb_u = val_u;
3723 else if (val_u > ub_u)
3724 ub_u = val_u;
3725 if (val_v < lb_v)
3726 lb_v = val_v;
3727 else if (val_v > ub_v)
3728 ub_v = val_v;
3729 }
3730 }
3731
3732 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
3733 --n) {
3734 for (i = 0; i < n; ++i) {
3735 centroids[i * 2] = lb_u + (2 * i + 1) * (ub_u - lb_u) / n / 2;
3736 centroids[i * 2 + 1] = lb_v + (2 * i + 1) * (ub_v - lb_v) / n / 2;
3737 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003738 av1_k_means(data, centroids, color_map, rows * cols, n, 2, max_itr);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003739 pmi->palette_size[1] = n;
3740 for (i = 1; i < 3; ++i) {
3741 for (j = 0; j < n; ++j) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003742#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003743 if (cpi->common.use_highbitdepth)
3744 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] = clip_pixel_highbd(
3745 (int)centroids[j * 2 + i - 1], cpi->common.bit_depth);
3746 else
Yaowu Xuf883b422016-08-30 14:01:10 -07003747#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003748 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
3749 clip_pixel((int)centroids[j * 2 + i - 1]);
3750 }
3751 }
3752
3753 super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s,
3754 &this_sse, bsize, *best_rd);
3755 if (this_rate_tokenonly == INT_MAX) continue;
3756 this_rate =
3757 this_rate_tokenonly + dc_mode_cost +
Yaowu Xuf883b422016-08-30 14:01:10 -07003758 2 * cpi->common.bit_depth * n * av1_cost_bit(128, 0) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003759 cpi->palette_uv_size_cost[bsize - BLOCK_8X8][n - 2] +
3760 write_uniform_cost(n, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07003761 av1_cost_bit(
3762 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003763
3764 for (i = 0; i < rows; ++i) {
3765 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07003766 int color_idx;
3767 const int color_ctx = av1_get_palette_color_context(
3768 color_map, cols, i, j, n, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003769 assert(color_idx >= 0 && color_idx < n);
3770 this_rate += cpi->palette_uv_color_cost[n - 2][color_ctx][color_idx];
3771 }
3772 }
3773
3774 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3775 if (this_rd < *best_rd) {
3776 *best_rd = this_rd;
3777 *palette_mode_info = *pmi;
3778 memcpy(best_palette_color_map, color_map,
3779 rows * cols * sizeof(best_palette_color_map[0]));
3780 *mode_selected = DC_PRED;
3781 *rate = this_rate;
3782 *distortion = this_distortion;
3783 *rate_tokenonly = this_rate_tokenonly;
3784 *skippable = s;
3785 }
3786 }
3787 }
3788}
Urvang Joshib100db72016-10-12 16:28:56 -07003789#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003790
hui su5db97432016-10-14 16:10:14 -07003791#if CONFIG_FILTER_INTRA
3792// Return 1 if an filter intra mode is selected; return 0 otherwise.
3793static int rd_pick_filter_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
3794 int *rate, int *rate_tokenonly,
3795 int64_t *distortion, int *skippable,
3796 BLOCK_SIZE bsize, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003797 MACROBLOCKD *const xd = &x->e_mbd;
3798 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su5db97432016-10-14 16:10:14 -07003799 int filter_intra_selected_flag = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003800 int this_rate_tokenonly, this_rate, s;
3801 int64_t this_distortion, this_sse, this_rd;
hui su5db97432016-10-14 16:10:14 -07003802 FILTER_INTRA_MODE mode;
3803 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003804
hui su5db97432016-10-14 16:10:14 -07003805 av1_zero(filter_intra_mode_info);
3806 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003807 mbmi->uv_mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07003808#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003809 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003810#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003811
3812 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su5db97432016-10-14 16:10:14 -07003813 mbmi->filter_intra_mode_info.filter_intra_mode[1] = mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003814 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s,
3815 &this_sse, bsize, *best_rd))
3816 continue;
3817
3818 this_rate = this_rate_tokenonly +
hui su5db97432016-10-14 16:10:14 -07003819 av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003820 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
3821 write_uniform_cost(FILTER_INTRA_MODES, mode);
3822 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3823 if (this_rd < *best_rd) {
3824 *best_rd = this_rd;
3825 *rate = this_rate;
3826 *rate_tokenonly = this_rate_tokenonly;
3827 *distortion = this_distortion;
3828 *skippable = s;
hui su5db97432016-10-14 16:10:14 -07003829 filter_intra_mode_info = mbmi->filter_intra_mode_info;
3830 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003831 }
3832 }
3833
hui su5db97432016-10-14 16:10:14 -07003834 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003835 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07003836 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
3837 filter_intra_mode_info.use_filter_intra_mode[1];
3838 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
3839 filter_intra_mode_info.filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003840 return 1;
3841 } else {
3842 return 0;
3843 }
3844}
hui su5db97432016-10-14 16:10:14 -07003845#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003846
hui su5db97432016-10-14 16:10:14 -07003847#if CONFIG_EXT_INTRA
Urvang Joshi52648442016-10-13 17:27:51 -07003848static void pick_intra_angle_routine_sbuv(
3849 const AV1_COMP *const cpi, MACROBLOCK *x, int *rate, int *rate_tokenonly,
3850 int64_t *distortion, int *skippable, int *best_angle_delta,
3851 BLOCK_SIZE bsize, int rate_overhead, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003852 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
3853 int this_rate_tokenonly, this_rate, s;
3854 int64_t this_distortion, this_sse, this_rd;
3855
3856 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s,
3857 &this_sse, bsize, *best_rd))
3858 return;
3859
3860 this_rate = this_rate_tokenonly + rate_overhead;
3861 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3862 if (this_rd < *best_rd) {
3863 *best_rd = this_rd;
3864 *best_angle_delta = mbmi->angle_delta[1];
3865 *rate = this_rate;
3866 *rate_tokenonly = this_rate_tokenonly;
3867 *distortion = this_distortion;
3868 *skippable = s;
3869 }
3870}
3871
Urvang Joshi52648442016-10-13 17:27:51 -07003872static int rd_pick_intra_angle_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
3873 int *rate, int *rate_tokenonly,
3874 int64_t *distortion, int *skippable,
3875 BLOCK_SIZE bsize, int rate_overhead,
3876 int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003877 MACROBLOCKD *const xd = &x->e_mbd;
3878 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
3879 int this_rate_tokenonly, this_rate, s;
3880 int64_t this_distortion, this_sse, this_rd;
3881 int angle_delta, best_angle_delta = 0;
3882 const double rd_adjust = 1.2;
3883
3884 *rate_tokenonly = INT_MAX;
3885 if (ANGLE_FAST_SEARCH) {
3886 int deltas_level1[3] = { 0, -2, 2 };
3887 int deltas_level2[3][2] = {
3888 { -1, 1 }, { -3, -1 }, { 1, 3 },
3889 };
3890 const int level1 = 3, level2 = 2;
3891 int i, j, best_i = -1;
3892
3893 for (i = 0; i < level1; ++i) {
3894 int64_t tmp_best_rd;
3895 mbmi->angle_delta[1] = deltas_level1[i];
3896 tmp_best_rd = (i == 0 && best_rd < INT64_MAX)
3897 ? (int64_t)(best_rd * rd_adjust)
3898 : best_rd;
3899 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s,
3900 &this_sse, bsize, tmp_best_rd)) {
3901 if (i == 0)
3902 break;
3903 else
3904 continue;
3905 }
3906 this_rate = this_rate_tokenonly + rate_overhead;
3907 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
3908 if (i == 0 && best_rd < INT64_MAX && this_rd > best_rd * rd_adjust) break;
3909 if (this_rd < best_rd) {
3910 best_i = i;
3911 best_rd = this_rd;
3912 best_angle_delta = mbmi->angle_delta[1];
3913 *rate = this_rate;
3914 *rate_tokenonly = this_rate_tokenonly;
3915 *distortion = this_distortion;
3916 *skippable = s;
3917 }
3918 }
3919
3920 if (best_i >= 0) {
3921 for (j = 0; j < level2; ++j) {
3922 mbmi->angle_delta[1] = deltas_level2[best_i][j];
3923 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly, distortion,
3924 skippable, &best_angle_delta, bsize,
3925 rate_overhead, &best_rd);
3926 }
3927 }
3928 } else {
3929 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
3930 ++angle_delta) {
3931 mbmi->angle_delta[1] = angle_delta;
3932 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly, distortion,
3933 skippable, &best_angle_delta, bsize,
3934 rate_overhead, &best_rd);
3935 }
3936 }
3937
3938 mbmi->angle_delta[1] = best_angle_delta;
3939 return *rate_tokenonly != INT_MAX;
3940}
3941#endif // CONFIG_EXT_INTRA
3942
Urvang Joshi52648442016-10-13 17:27:51 -07003943static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
3944 int *rate, int *rate_tokenonly,
3945 int64_t *distortion, int *skippable,
3946 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003947 MACROBLOCKD *xd = &x->e_mbd;
3948 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
3949 PREDICTION_MODE mode;
3950 PREDICTION_MODE mode_selected = DC_PRED;
3951 int64_t best_rd = INT64_MAX, this_rd;
3952 int this_rate_tokenonly, this_rate, s;
3953 int64_t this_distortion, this_sse;
Urvang Joshib100db72016-10-12 16:28:56 -07003954#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003955 const int rows =
3956 (4 * num_4x4_blocks_high_lookup[bsize]) >> (xd->plane[1].subsampling_y);
3957 const int cols =
3958 (4 * num_4x4_blocks_wide_lookup[bsize]) >> (xd->plane[1].subsampling_x);
3959 PALETTE_MODE_INFO palette_mode_info;
3960 PALETTE_MODE_INFO *const pmi = &xd->mi[0]->mbmi.palette_mode_info;
3961 uint8_t *best_palette_color_map = NULL;
Urvang Joshib100db72016-10-12 16:28:56 -07003962#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003963#if CONFIG_EXT_INTRA
3964 int is_directional_mode, rate_overhead, best_angle_delta = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003965#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003966#if CONFIG_FILTER_INTRA
3967 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
3968
3969 filter_intra_mode_info.use_filter_intra_mode[1] = 0;
3970 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
3971#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07003972#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003973 palette_mode_info.palette_size[1] = 0;
3974 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003975#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003976 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
3977 if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode))) continue;
3978
3979 mbmi->uv_mode = mode;
3980#if CONFIG_EXT_INTRA
3981 is_directional_mode = (mode != DC_PRED && mode != TM_PRED);
3982 rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
3983 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
3984 mbmi->angle_delta[1] = 0;
3985 if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode) {
3986 if (!rd_pick_intra_angle_sbuv(cpi, x, &this_rate, &this_rate_tokenonly,
3987 &this_distortion, &s, bsize, rate_overhead,
3988 best_rd))
3989 continue;
3990 } else {
3991 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s,
3992 &this_sse, bsize, best_rd))
3993 continue;
3994 }
3995 this_rate = this_rate_tokenonly + cpi->intra_uv_mode_cost[mbmi->mode][mode];
3996 if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode)
3997 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
3998 MAX_ANGLE_DELTAS + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003999#else
4000 if (!super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s,
4001 &this_sse, bsize, best_rd))
4002 continue;
4003 this_rate = this_rate_tokenonly + cpi->intra_uv_mode_cost[mbmi->mode][mode];
4004#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07004005#if CONFIG_FILTER_INTRA
4006 if (mbmi->sb_type >= BLOCK_8X8 && mode == DC_PRED)
4007 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 0);
4008#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004009#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004010 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8 &&
4011 mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07004012 this_rate += av1_cost_bit(
4013 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07004014#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004015
4016 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
4017
4018 if (this_rd < best_rd) {
4019 mode_selected = mode;
4020#if CONFIG_EXT_INTRA
4021 best_angle_delta = mbmi->angle_delta[1];
4022#endif // CONFIG_EXT_INTRA
4023 best_rd = this_rd;
4024 *rate = this_rate;
4025 *rate_tokenonly = this_rate_tokenonly;
4026 *distortion = this_distortion;
4027 *skippable = s;
4028 }
4029 }
4030
Urvang Joshib100db72016-10-12 16:28:56 -07004031#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004032 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8) {
4033 best_palette_color_map = x->palette_buffer->best_palette_color_map;
4034 rd_pick_palette_intra_sbuv(
4035 cpi, x, cpi->intra_uv_mode_cost[mbmi->mode][DC_PRED],
4036 &palette_mode_info, best_palette_color_map, &mode_selected, &best_rd,
4037 rate, rate_tokenonly, distortion, skippable);
4038 }
Urvang Joshib100db72016-10-12 16:28:56 -07004039#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004040
hui su5db97432016-10-14 16:10:14 -07004041#if CONFIG_FILTER_INTRA
4042 if (mbmi->sb_type >= BLOCK_8X8) {
4043 if (rd_pick_filter_intra_sbuv(cpi, x, rate, rate_tokenonly, distortion,
4044 skippable, bsize, &best_rd)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004045 mode_selected = mbmi->uv_mode;
hui su5db97432016-10-14 16:10:14 -07004046 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004047 }
4048 }
4049
hui su5db97432016-10-14 16:10:14 -07004050 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
4051 filter_intra_mode_info.use_filter_intra_mode[1];
4052 if (filter_intra_mode_info.use_filter_intra_mode[1]) {
4053 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
4054 filter_intra_mode_info.filter_intra_mode[1];
Urvang Joshib100db72016-10-12 16:28:56 -07004055#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004056 palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004057#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004058 }
hui su5db97432016-10-14 16:10:14 -07004059#endif // CONFIG_FILTER_INTRA
4060
4061#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004062 mbmi->angle_delta[1] = best_angle_delta;
4063#endif // CONFIG_EXT_INTRA
4064 mbmi->uv_mode = mode_selected;
Urvang Joshib100db72016-10-12 16:28:56 -07004065#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004066 pmi->palette_size[1] = palette_mode_info.palette_size[1];
4067 if (palette_mode_info.palette_size[1] > 0) {
4068 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
4069 palette_mode_info.palette_colors + PALETTE_MAX_SIZE,
4070 2 * PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
4071 memcpy(xd->plane[1].color_index_map, best_palette_color_map,
4072 rows * cols * sizeof(best_palette_color_map[0]));
4073 }
Urvang Joshib100db72016-10-12 16:28:56 -07004074#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004075
4076 return best_rd;
4077}
4078
Urvang Joshi52648442016-10-13 17:27:51 -07004079static void choose_intra_uv_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004080 PICK_MODE_CONTEXT *ctx, BLOCK_SIZE bsize,
4081 TX_SIZE max_tx_size, int *rate_uv,
4082 int *rate_uv_tokenonly, int64_t *dist_uv,
4083 int *skip_uv, PREDICTION_MODE *mode_uv) {
4084 // Use an estimated rd for uv_intra based on DC_PRED if the
4085 // appropriate speed flag is set.
Jingning Han3f167252016-06-07 16:11:42 -07004086 (void)ctx;
4087 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4088 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004089 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
4090}
4091
Urvang Joshi52648442016-10-13 17:27:51 -07004092static int cost_mv_ref(const AV1_COMP *const cpi, PREDICTION_MODE mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004093#if CONFIG_REF_MV && CONFIG_EXT_INTER
4094 int is_compound,
4095#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4096 int16_t mode_context) {
4097#if CONFIG_REF_MV
4098 int mode_cost = 0;
4099#if CONFIG_EXT_INTER
4100 int16_t mode_ctx =
4101 is_compound ? mode_context : (mode_context & NEWMV_CTX_MASK);
4102#else
4103 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
4104#endif // CONFIG_EXT_INTER
4105 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
4106
4107 assert(is_inter_mode(mode));
4108
4109#if CONFIG_EXT_INTER
4110 if (is_compound) {
clang-format67948d32016-09-07 22:40:40 -07004111 return cpi->inter_compound_mode_cost[mode_context]
4112 [INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004113 } else {
4114 if (mode == NEWMV || mode == NEWFROMNEARMV) {
4115#else
4116 if (mode == NEWMV) {
4117#endif // CONFIG_EXT_INTER
4118 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
4119#if CONFIG_EXT_INTER
4120 if (!is_compound)
4121 mode_cost += cpi->new2mv_mode_cost[mode == NEWFROMNEARMV];
4122#endif // CONFIG_EXT_INTER
4123 return mode_cost;
4124 } else {
4125 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
4126 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
4127
4128 if (is_all_zero_mv) return mode_cost;
4129
4130 if (mode == ZEROMV) {
4131 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
4132 return mode_cost;
4133 } else {
4134 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
4135 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
4136
4137 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
4138 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
4139 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
4140
4141 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
4142 return mode_cost;
4143 }
4144 }
4145#if CONFIG_EXT_INTER
4146 }
4147#endif // CONFIG_EXT_INTER
4148#else
4149 assert(is_inter_mode(mode));
4150#if CONFIG_EXT_INTER
4151 if (is_inter_compound_mode(mode)) {
clang-format67948d32016-09-07 22:40:40 -07004152 return cpi->inter_compound_mode_cost[mode_context]
4153 [INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004154 } else {
4155#endif // CONFIG_EXT_INTER
4156 return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
4157#if CONFIG_EXT_INTER
4158 }
4159#endif // CONFIG_EXT_INTER
4160#endif
4161}
4162
Sarah Parkere5299862016-08-16 14:57:37 -07004163#if CONFIG_GLOBAL_MOTION
4164static int get_gmbitcost(const Global_Motion_Params *gm,
4165 const aom_prob *probs) {
4166 int gmtype_cost[GLOBAL_MOTION_TYPES];
4167 int bits;
4168 av1_cost_tokens(gmtype_cost, probs, av1_global_motion_types_tree);
4169 if (gm->motion_params.wmmat[2].as_int) {
4170 bits = (GM_ABS_TRANS_BITS + 1) * 2 + 4 * GM_ABS_ALPHA_BITS + 4;
4171 } else if (gm->motion_params.wmmat[1].as_int) {
4172 bits = (GM_ABS_TRANS_BITS + 1) * 2 + 2 * GM_ABS_ALPHA_BITS + 2;
4173 } else {
4174 bits =
4175 (gm->motion_params.wmmat[0].as_int ? ((GM_ABS_TRANS_BITS + 1) * 2) : 0);
4176 }
Sarah Parkerae51dd82016-10-18 16:18:23 -07004177 return bits ? (bits << AV1_PROB_COST_SHIFT) + gmtype_cost[gm->gmtype] : 0;
Sarah Parkere5299862016-08-16 14:57:37 -07004178}
4179
4180#define GLOBAL_MOTION_RATE(ref) \
4181 (cpi->global_motion_used[ref] >= 2 \
4182 ? 0 \
4183 : get_gmbitcost(&cm->global_motion[(ref)], \
4184 cm->fc->global_motion_types_prob) / \
4185 2);
4186#endif // CONFIG_GLOBAL_MOTION
4187
Urvang Joshi52648442016-10-13 17:27:51 -07004188static int set_and_cost_bmi_mvs(const AV1_COMP *const cpi, MACROBLOCK *x,
4189 MACROBLOCKD *xd, int i, PREDICTION_MODE mode,
4190 int_mv this_mv[2],
clang-format67948d32016-09-07 22:40:40 -07004191 int_mv frame_mv[MB_MODE_COUNT]
4192 [TOTAL_REFS_PER_FRAME],
4193 int_mv seg_mvs[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004194#if CONFIG_EXT_INTER
clang-format67948d32016-09-07 22:40:40 -07004195 int_mv compound_seg_newmvs[2],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004196#endif // CONFIG_EXT_INTER
clang-format67948d32016-09-07 22:40:40 -07004197 int_mv *best_ref_mv[2], const int *mvjcost,
4198 int *mvcost[2]) {
Sarah Parkere5299862016-08-16 14:57:37 -07004199#if CONFIG_GLOBAL_MOTION
4200 const AV1_COMMON *cm = &cpi->common;
4201#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004202 MODE_INFO *const mic = xd->mi[0];
4203 const MB_MODE_INFO *const mbmi = &mic->mbmi;
4204 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4205 int thismvcost = 0;
4206 int idx, idy;
4207 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
4208 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
4209 const int is_compound = has_second_ref(mbmi);
4210 int mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
4211
4212 switch (mode) {
4213 case NEWMV:
4214#if CONFIG_EXT_INTER
4215 case NEWFROMNEARMV:
4216#endif // CONFIG_EXT_INTER
4217 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
4218#if CONFIG_EXT_INTER
4219 if (!cpi->common.allow_high_precision_mv ||
Yaowu Xuf883b422016-08-30 14:01:10 -07004220 !av1_use_mv_hp(&best_ref_mv[0]->as_mv))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004221 lower_mv_precision(&this_mv[0].as_mv, 0);
4222#endif // CONFIG_EXT_INTER
4223
4224#if CONFIG_REF_MV
4225 for (idx = 0; idx < 1 + is_compound; ++idx) {
4226 this_mv[idx] = seg_mvs[mbmi->ref_frame[idx]];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07004227 av1_set_mvcost(x, mbmi->ref_frame[idx], idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004228 thismvcost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07004229 av1_mv_bit_cost(&this_mv[idx].as_mv, &best_ref_mv[idx]->as_mv,
4230 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004231 }
4232 (void)mvjcost;
4233 (void)mvcost;
4234#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004235 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4236 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004237#if !CONFIG_EXT_INTER
4238 if (is_compound) {
4239 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07004240 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4241 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004242 }
4243#endif // !CONFIG_EXT_INTER
4244#endif
4245 break;
4246 case NEARMV:
4247 case NEARESTMV:
4248 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4249 if (is_compound)
4250 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4251 break;
4252 case ZEROMV:
Sarah Parkere5299862016-08-16 14:57:37 -07004253#if CONFIG_GLOBAL_MOTION
4254 this_mv[0].as_int = cpi->common.global_motion[mbmi->ref_frame[0]]
4255 .motion_params.wmmat[0]
4256 .as_int;
4257 thismvcost += GLOBAL_MOTION_RATE(mbmi->ref_frame[0]);
4258 if (is_compound) {
4259 this_mv[1].as_int = cpi->common.global_motion[mbmi->ref_frame[1]]
4260 .motion_params.wmmat[0]
4261 .as_int;
4262 thismvcost += GLOBAL_MOTION_RATE(mbmi->ref_frame[1]);
4263 }
4264#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004265 this_mv[0].as_int = 0;
4266 if (is_compound) this_mv[1].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07004267#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004268 break;
4269#if CONFIG_EXT_INTER
4270 case NEW_NEWMV:
4271 if (compound_seg_newmvs[0].as_int == INVALID_MV ||
4272 compound_seg_newmvs[1].as_int == INVALID_MV) {
4273 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
4274 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
4275 } else {
4276 this_mv[0].as_int = compound_seg_newmvs[0].as_int;
4277 this_mv[1].as_int = compound_seg_newmvs[1].as_int;
4278 }
4279 if (!cpi->common.allow_high_precision_mv ||
Yaowu Xuf883b422016-08-30 14:01:10 -07004280 !av1_use_mv_hp(&best_ref_mv[0]->as_mv))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004281 lower_mv_precision(&this_mv[0].as_mv, 0);
4282 if (!cpi->common.allow_high_precision_mv ||
Yaowu Xuf883b422016-08-30 14:01:10 -07004283 !av1_use_mv_hp(&best_ref_mv[1]->as_mv))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004284 lower_mv_precision(&this_mv[1].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07004285 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4286 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
4287 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4288 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004289 break;
4290 case NEW_NEARMV:
4291 case NEW_NEARESTMV:
4292 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
4293 if (!cpi->common.allow_high_precision_mv ||
Yaowu Xuf883b422016-08-30 14:01:10 -07004294 !av1_use_mv_hp(&best_ref_mv[0]->as_mv))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004295 lower_mv_precision(&this_mv[0].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07004296 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4297 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004298 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4299 break;
4300 case NEAR_NEWMV:
4301 case NEAREST_NEWMV:
4302 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4303 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
4304 if (!cpi->common.allow_high_precision_mv ||
Yaowu Xuf883b422016-08-30 14:01:10 -07004305 !av1_use_mv_hp(&best_ref_mv[1]->as_mv))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004306 lower_mv_precision(&this_mv[1].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07004307 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4308 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004309 break;
4310 case NEAREST_NEARMV:
4311 case NEAR_NEARESTMV:
4312 case NEAREST_NEARESTMV:
4313 case NEAR_NEARMV:
4314 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4315 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4316 break;
4317 case ZERO_ZEROMV:
4318 this_mv[0].as_int = 0;
4319 this_mv[1].as_int = 0;
4320 break;
4321#endif // CONFIG_EXT_INTER
4322 default: break;
4323 }
4324
4325 mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
4326 if (is_compound) mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
4327
4328 mic->bmi[i].as_mode = mode;
4329
4330#if CONFIG_REF_MV
4331 if (mode == NEWMV) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07004332 mic->bmi[i].pred_mv[0].as_int =
4333 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_int;
4334 if (is_compound)
4335 mic->bmi[i].pred_mv[1].as_int =
4336 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004337 } else {
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07004338 mic->bmi[i].pred_mv[0].as_int = this_mv[0].as_int;
4339 if (is_compound) mic->bmi[i].pred_mv[1].as_int = this_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004340 }
4341#endif
4342
4343 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
4344 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
4345 memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
4346
4347#if CONFIG_REF_MV
4348#if CONFIG_EXT_INTER
4349 if (is_compound)
4350 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
4351 else
4352#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07004353 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
4354 mbmi->ref_frame, mbmi->sb_type, i);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004355#endif
4356#if CONFIG_REF_MV && CONFIG_EXT_INTER
4357 return cost_mv_ref(cpi, mode, is_compound, mode_ctx) + thismvcost;
4358#else
4359 return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
4360#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4361}
4362
Urvang Joshi52648442016-10-13 17:27:51 -07004363static int64_t encode_inter_mb_segment(const AV1_COMP *const cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004364 int64_t best_yrd, int i, int *labelyrate,
4365 int64_t *distortion, int64_t *sse,
4366 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
4367 int ir, int ic, int mi_row, int mi_col) {
Angie Chiang22ba7512016-10-20 17:10:33 -07004368 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004369 int k;
4370 MACROBLOCKD *xd = &x->e_mbd;
4371 struct macroblockd_plane *const pd = &xd->plane[0];
4372 struct macroblock_plane *const p = &x->plane[0];
4373 MODE_INFO *const mi = xd->mi[0];
4374 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
4375 const int width = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
4376 const int height = 4 * num_4x4_blocks_high_lookup[plane_bsize];
4377 int idx, idy;
4378 const uint8_t *const src =
Yaowu Xuf883b422016-08-30 14:01:10 -07004379 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004380 uint8_t *const dst =
Yaowu Xuf883b422016-08-30 14:01:10 -07004381 &pd->dst.buf[av1_raster_block_offset(BLOCK_8X8, i, pd->dst.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004382 int64_t thisdistortion = 0, thissse = 0;
4383 int thisrate = 0;
4384 TX_SIZE tx_size = mi->mbmi.tx_size;
4385
4386 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, i, tx_size);
Angie Chiangff6d8902016-10-21 11:02:09 -07004387 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004388 const int num_4x4_w = num_4x4_blocks_wide_txsize_lookup[tx_size];
4389 const int num_4x4_h = num_4x4_blocks_high_txsize_lookup[tx_size];
4390
4391#if CONFIG_EXT_TX && CONFIG_RECT_TX
4392 assert(IMPLIES(xd->lossless[mi->mbmi.segment_id], tx_size == TX_4X4));
4393 assert(IMPLIES(!xd->lossless[mi->mbmi.segment_id],
4394 tx_size == max_txsize_rect_lookup[mi->mbmi.sb_type]));
4395#else
4396 assert(tx_size == TX_4X4);
4397#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4398 assert(tx_type == DCT_DCT);
4399
Yaowu Xuf883b422016-08-30 14:01:10 -07004400 av1_build_inter_predictor_sub8x8(xd, 0, i, ir, ic, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004401
Yaowu Xuf883b422016-08-30 14:01:10 -07004402#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004403 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004404 aom_highbd_subtract_block(
4405 height, width, av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
4406 8, src, p->src.stride, dst, pd->dst.stride, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004407 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004408 aom_subtract_block(height, width,
4409 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07004410 8, src, p->src.stride, dst, pd->dst.stride);
4411 }
4412#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004413 aom_subtract_block(height, width,
4414 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07004415 8, src, p->src.stride, dst, pd->dst.stride);
Yaowu Xuf883b422016-08-30 14:01:10 -07004416#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004417
4418 k = i;
4419 for (idy = 0; idy < height / 4; idy += num_4x4_h) {
4420 for (idx = 0; idx < width / 4; idx += num_4x4_w) {
4421 int64_t dist, ssz, rd, rd1, rd2;
4422 int block;
4423 int coeff_ctx;
4424 k += (idy * 2 + idx);
4425 if (tx_size == TX_4X4)
4426 block = k;
4427 else
4428 block = (i ? 2 : 0);
Peter de Rivaz46fcb052016-10-18 15:38:01 +01004429#if CONFIG_VAR_TX
4430 coeff_ctx = get_entropy_context(tx_size, ta + (k & 1), tl + (k >> 1));
4431#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07004432 coeff_ctx = combine_entropy_contexts(*(ta + (k & 1)), *(tl + (k >> 1)));
Peter de Rivaz46fcb052016-10-18 15:38:01 +01004433#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004434#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07004435 av1_xform_quant_fp_nuq(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
Yaowu Xuf883b422016-08-30 14:01:10 -07004436 BLOCK_8X8, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004437#else
Angie Chiangff6d8902016-10-21 11:02:09 -07004438 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
4439 BLOCK_8X8, tx_size, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004440#endif // CONFIG_NEW_QUANT
4441 if (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0)
Angie Chiangff6d8902016-10-21 11:02:09 -07004442 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004443 dist_block(cpi, x, 0, block, idy + (i >> 1), idx + (i & 0x1), tx_size,
4444 &dist, &ssz);
4445 thisdistortion += dist;
4446 thissse += ssz;
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07004447 thisrate +=
Angie Chiang22ba7512016-10-20 17:10:33 -07004448 av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size, scan_order->scan,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07004449 scan_order->neighbors, cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004450 *(ta + (k & 1)) = !(p->eobs[block] == 0);
4451 *(tl + (k >> 1)) = !(p->eobs[block] == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004452#if CONFIG_EXT_TX
4453 if (tx_size == TX_8X4) {
4454 *(ta + (k & 1) + 1) = *(ta + (k & 1));
4455 }
4456 if (tx_size == TX_4X8) {
4457 *(tl + (k >> 1) + 1) = *(tl + (k >> 1));
4458 }
4459#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004460 rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion);
4461 rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse);
Yaowu Xuf883b422016-08-30 14:01:10 -07004462 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004463 if (rd >= best_yrd) return INT64_MAX;
4464 }
4465 }
4466
4467 *distortion = thisdistortion;
4468 *labelyrate = thisrate;
4469 *sse = thissse;
4470
4471 return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
4472}
4473
4474typedef struct {
4475 int eobs;
4476 int brate;
4477 int byrate;
4478 int64_t bdist;
4479 int64_t bsse;
4480 int64_t brdcost;
4481 int_mv mvs[2];
4482#if CONFIG_REF_MV
4483 int_mv pred_mv[2];
4484#endif
4485#if CONFIG_EXT_INTER
4486 int_mv ref_mv[2];
4487#endif // CONFIG_EXT_INTER
4488 ENTROPY_CONTEXT ta[2];
4489 ENTROPY_CONTEXT tl[2];
4490} SEG_RDSTAT;
4491
4492typedef struct {
4493 int_mv *ref_mv[2];
4494 int_mv mvp;
4495
4496 int64_t segment_rd;
4497 int r;
4498 int64_t d;
4499 int64_t sse;
4500 int segment_yrate;
4501 PREDICTION_MODE modes[4];
4502#if CONFIG_EXT_INTER
4503 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
4504#else
4505 SEG_RDSTAT rdstat[4][INTER_MODES];
4506#endif // CONFIG_EXT_INTER
4507 int mvthresh;
4508} BEST_SEG_INFO;
4509
4510static INLINE int mv_check_bounds(const MACROBLOCK *x, const MV *mv) {
4511 return (mv->row >> 3) < x->mv_row_min || (mv->row >> 3) > x->mv_row_max ||
4512 (mv->col >> 3) < x->mv_col_min || (mv->col >> 3) > x->mv_col_max;
4513}
4514
4515static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
4516 MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
4517 struct macroblock_plane *const p = &x->plane[0];
4518 struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
4519
4520 p->src.buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07004521 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004522 assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
4523 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07004524 &pd->pre[0].buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[0].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004525 if (has_second_ref(mbmi))
4526 pd->pre[1].buf =
4527 &pd->pre[1]
Yaowu Xuf883b422016-08-30 14:01:10 -07004528 .buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[1].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004529}
4530
4531static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
4532 struct buf_2d orig_pre[2]) {
4533 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
4534 x->plane[0].src = orig_src;
4535 x->e_mbd.plane[0].pre[0] = orig_pre[0];
4536 if (has_second_ref(mbmi)) x->e_mbd.plane[0].pre[1] = orig_pre[1];
4537}
4538
4539// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
4540// TODO(aconverse): Find out if this is still productive then clean up or remove
4541static int check_best_zero_mv(
Urvang Joshi52648442016-10-13 17:27:51 -07004542 const AV1_COMP *const cpi, const int16_t mode_context[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004543#if CONFIG_REF_MV && CONFIG_EXT_INTER
4544 const int16_t compound_mode_context[TOTAL_REFS_PER_FRAME],
4545#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4546 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME], int this_mode,
4547 const MV_REFERENCE_FRAME ref_frames[2], const BLOCK_SIZE bsize, int block) {
4548
4549#if !CONFIG_EXT_INTER
4550 assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
4551#endif
4552
4553 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
4554 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
4555 (ref_frames[1] <= INTRA_FRAME ||
4556 frame_mv[this_mode][ref_frames[1]].as_int == 0)) {
4557#if CONFIG_REF_MV
4558 int16_t rfc =
Yaowu Xuf883b422016-08-30 14:01:10 -07004559 av1_mode_context_analyzer(mode_context, ref_frames, bsize, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004560#else
4561 int16_t rfc = mode_context[ref_frames[0]];
4562#endif
4563#if CONFIG_REF_MV && CONFIG_EXT_INTER
4564 int c1 = cost_mv_ref(cpi, NEARMV, ref_frames[1] > INTRA_FRAME, rfc);
4565 int c2 = cost_mv_ref(cpi, NEARESTMV, ref_frames[1] > INTRA_FRAME, rfc);
4566 int c3 = cost_mv_ref(cpi, ZEROMV, ref_frames[1] > INTRA_FRAME, rfc);
4567#else
4568 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
4569 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
4570 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
4571#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4572
4573#if !CONFIG_REF_MV
4574 (void)bsize;
4575 (void)block;
4576#endif
4577
4578 if (this_mode == NEARMV) {
4579 if (c1 > c3) return 0;
4580 } else if (this_mode == NEARESTMV) {
4581 if (c2 > c3) return 0;
4582 } else {
4583 assert(this_mode == ZEROMV);
4584 if (ref_frames[1] <= INTRA_FRAME) {
4585 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
4586 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
4587 return 0;
4588 } else {
4589 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
4590 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
4591 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
4592 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
4593 return 0;
4594 }
4595 }
4596 }
4597#if CONFIG_EXT_INTER
4598 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
4599 this_mode == NEAR_NEARESTMV || this_mode == NEAR_NEARMV ||
4600 this_mode == ZERO_ZEROMV) &&
4601 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
4602 frame_mv[this_mode][ref_frames[1]].as_int == 0) {
4603#if CONFIG_REF_MV
4604 int16_t rfc = compound_mode_context[ref_frames[0]];
4605 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, 1, rfc);
4606 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, 1, rfc);
4607 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, 1, rfc);
4608 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, 1, rfc);
4609 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, 1, rfc);
4610#else
4611 int16_t rfc = mode_context[ref_frames[0]];
4612 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
4613 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
4614 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
4615 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
4616 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, rfc);
4617#endif
4618
4619 if (this_mode == NEAREST_NEARMV) {
4620 if (c1 > c3) return 0;
4621 } else if (this_mode == NEAREST_NEARESTMV) {
4622 if (c2 > c3) return 0;
4623 } else if (this_mode == NEAR_NEARESTMV) {
4624 if (c4 > c3) return 0;
4625 } else if (this_mode == NEAR_NEARMV) {
4626 if (c5 > c3) return 0;
4627 } else {
4628 assert(this_mode == ZERO_ZEROMV);
4629 if ((c3 >= c2 && frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
4630 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
4631 (c3 >= c1 && frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
4632 frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
4633 (c3 >= c5 && frame_mv[NEAR_NEARMV][ref_frames[0]].as_int == 0 &&
4634 frame_mv[NEAR_NEARMV][ref_frames[1]].as_int == 0) ||
4635 (c3 >= c4 && frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
4636 frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
4637 return 0;
4638 }
4639 }
4640#endif // CONFIG_EXT_INTER
4641 return 1;
4642}
4643
Urvang Joshi52648442016-10-13 17:27:51 -07004644static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
4645 BLOCK_SIZE bsize, int_mv *frame_mv, int mi_row,
4646 int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004647#if CONFIG_EXT_INTER
4648 int_mv *ref_mv_sub8x8[2],
4649#endif
4650 int_mv single_newmv[TOTAL_REFS_PER_FRAME],
4651 int *rate_mv, const int block) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004652 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004653 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
4654 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
4655 MACROBLOCKD *xd = &x->e_mbd;
4656 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4657 const int refs[2] = { mbmi->ref_frame[0],
4658 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
4659 int_mv ref_mv[2];
4660 int ite, ref;
4661#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07004662 InterpFilter interp_filter[4] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004663 mbmi->interp_filter[0], mbmi->interp_filter[1], mbmi->interp_filter[2],
4664 mbmi->interp_filter[3],
4665 };
4666#else
James Zern7b9407a2016-05-18 23:48:05 -07004667 const InterpFilter interp_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004668#endif
4669 struct scale_factors sf;
4670
4671 // Do joint motion search in compound mode to get more accurate mv.
4672 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
4673 int last_besterr[2] = { INT_MAX, INT_MAX };
4674 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
Yaowu Xuf883b422016-08-30 14:01:10 -07004675 av1_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
4676 av1_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
Yaowu Xuc27fc142016-08-22 16:08:15 -07004677 };
4678
4679// Prediction buffer from second frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07004680#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004681 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
4682 uint8_t *second_pred;
4683#else
4684 DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07004685#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004686
4687 for (ref = 0; ref < 2; ++ref) {
4688#if CONFIG_EXT_INTER
4689 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
4690 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
4691 else
4692#endif // CONFIG_EXT_INTER
4693 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
4694
4695 if (scaled_ref_frame[ref]) {
4696 int i;
4697 // Swap out the reference frame for a version that's been scaled to
4698 // match the resolution of the current frame, allowing the existing
4699 // motion search code to be used without additional modifications.
4700 for (i = 0; i < MAX_MB_PLANE; i++)
4701 backup_yv12[ref][i] = xd->plane[i].pre[ref];
Yaowu Xuf883b422016-08-30 14:01:10 -07004702 av1_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
4703 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004704 }
4705
4706 frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
4707 }
4708
4709// Since we have scaled the reference frames to match the size of the current
4710// frame we must use a unit scaling factor during mode selection.
Yaowu Xuf883b422016-08-30 14:01:10 -07004711#if CONFIG_AOM_HIGHBITDEPTH
4712 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
4713 cm->height, cm->use_highbitdepth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004714#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004715 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
4716 cm->height);
4717#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004718
4719 // Allow joint search multiple times iteratively for each reference frame
4720 // and break out of the search loop if it couldn't find a better mv.
4721 for (ite = 0; ite < 4; ite++) {
4722 struct buf_2d ref_yv12[2];
4723 int bestsme = INT_MAX;
4724 int sadpb = x->sadperbit16;
4725 MV *const best_mv = &x->best_mv.as_mv;
4726 int search_range = 3;
4727
4728 int tmp_col_min = x->mv_col_min;
4729 int tmp_col_max = x->mv_col_max;
4730 int tmp_row_min = x->mv_row_min;
4731 int tmp_row_max = x->mv_row_max;
4732 int id = ite % 2; // Even iterations search in the first reference frame,
4733 // odd iterations search in the second. The predictor
4734 // found for the 'other' reference frame is factored in.
4735
4736 // Initialized here because of compiler problem in Visual Studio.
4737 ref_yv12[0] = xd->plane[0].pre[0];
4738 ref_yv12[1] = xd->plane[0].pre[1];
4739
4740#if CONFIG_DUAL_FILTER
4741 // reload the filter types
4742 interp_filter[0] =
4743 (id == 0) ? mbmi->interp_filter[2] : mbmi->interp_filter[0];
4744 interp_filter[1] =
4745 (id == 0) ? mbmi->interp_filter[3] : mbmi->interp_filter[1];
4746#endif
4747
4748// Get the prediction block from the 'other' reference frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07004749#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004750 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
4751 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
Yaowu Xuf883b422016-08-30 14:01:10 -07004752 av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004753 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
4754 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, 0, interp_filter,
4755 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd->bd);
4756 } else {
4757 second_pred = (uint8_t *)second_pred_alloc_16;
Yaowu Xuf883b422016-08-30 14:01:10 -07004758 av1_build_inter_predictor(ref_yv12[!id].buf, ref_yv12[!id].stride,
4759 second_pred, pw, &frame_mv[refs[!id]].as_mv,
4760 &sf, pw, ph, 0, interp_filter, MV_PRECISION_Q3,
4761 mi_col * MI_SIZE, mi_row * MI_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004762 }
4763#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004764 av1_build_inter_predictor(ref_yv12[!id].buf, ref_yv12[!id].stride,
4765 second_pred, pw, &frame_mv[refs[!id]].as_mv, &sf,
4766 pw, ph, 0, interp_filter, MV_PRECISION_Q3,
4767 mi_col * MI_SIZE, mi_row * MI_SIZE);
4768#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004769
4770 // Do compound motion search on the current reference frame.
4771 if (id) xd->plane[0].pre[0] = ref_yv12[id];
Yaowu Xuf883b422016-08-30 14:01:10 -07004772 av1_set_mv_search_range(x, &ref_mv[id].as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004773
4774 // Use the mv result from the single mode as mv predictor.
4775 *best_mv = frame_mv[refs[id]].as_mv;
4776
4777 best_mv->col >>= 3;
4778 best_mv->row >>= 3;
4779
4780#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07004781 av1_set_mvcost(x, refs[id], id, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004782#endif
4783
4784 // Small-range full-pixel motion search.
4785 bestsme =
Yaowu Xuf883b422016-08-30 14:01:10 -07004786 av1_refining_search_8p_c(x, sadpb, search_range, &cpi->fn_ptr[bsize],
4787 &ref_mv[id].as_mv, second_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004788 if (bestsme < INT_MAX)
Yaowu Xuf883b422016-08-30 14:01:10 -07004789 bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv[id].as_mv,
4790 second_pred, &cpi->fn_ptr[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004791
4792 x->mv_col_min = tmp_col_min;
4793 x->mv_col_max = tmp_col_max;
4794 x->mv_row_min = tmp_row_min;
4795 x->mv_row_max = tmp_row_max;
4796
4797 if (bestsme < INT_MAX) {
4798 int dis; /* TODO: use dis in distortion calculation later. */
4799 unsigned int sse;
4800 if (cpi->sf.use_upsampled_references) {
4801 // Use up-sampled reference frames.
4802 struct macroblockd_plane *const pd = &xd->plane[0];
4803 struct buf_2d backup_pred = pd->pre[0];
4804 const YV12_BUFFER_CONFIG *upsampled_ref =
4805 get_upsampled_ref(cpi, refs[id]);
4806
4807 // Set pred for Y plane
4808 setup_pred_plane(&pd->pre[0], upsampled_ref->y_buffer,
4809 upsampled_ref->y_crop_width,
4810 upsampled_ref->y_crop_height, upsampled_ref->y_stride,
4811 (mi_row << 3), (mi_col << 3), NULL, pd->subsampling_x,
4812 pd->subsampling_y);
4813
4814 // If bsize < BLOCK_8X8, adjust pred pointer for this block
4815 if (bsize < BLOCK_8X8)
4816 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07004817 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, block,
4818 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004819 << 3];
4820
4821 bestsme = cpi->find_fractional_mv_step(
4822 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
4823 x->errorperbit, &cpi->fn_ptr[bsize], 0,
4824 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
4825 &dis, &sse, second_pred, pw, ph, 1);
4826
4827 // Restore the reference frames.
4828 pd->pre[0] = backup_pred;
4829 } else {
4830 (void)block;
4831 bestsme = cpi->find_fractional_mv_step(
4832 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
4833 x->errorperbit, &cpi->fn_ptr[bsize], 0,
4834 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
4835 &dis, &sse, second_pred, pw, ph, 0);
4836 }
4837 }
4838
4839 // Restore the pointer to the first (possibly scaled) prediction buffer.
4840 if (id) xd->plane[0].pre[0] = ref_yv12[0];
4841
4842 if (bestsme < last_besterr[id]) {
4843 frame_mv[refs[id]].as_mv = *best_mv;
4844 last_besterr[id] = bestsme;
4845 } else {
4846 break;
4847 }
4848 }
4849
4850 *rate_mv = 0;
4851
4852 for (ref = 0; ref < 2; ++ref) {
4853 if (scaled_ref_frame[ref]) {
4854 // Restore the prediction frame pointers to their unscaled versions.
4855 int i;
4856 for (i = 0; i < MAX_MB_PLANE; i++)
4857 xd->plane[i].pre[ref] = backup_yv12[ref][i];
4858 }
4859#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07004860 av1_set_mvcost(x, refs[ref], ref, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004861#endif
4862#if CONFIG_EXT_INTER
4863 if (bsize >= BLOCK_8X8)
4864#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07004865 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
4866 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
4867 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004868#if CONFIG_EXT_INTER
4869 else
Yaowu Xuf883b422016-08-30 14:01:10 -07004870 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
4871 &ref_mv_sub8x8[ref]->as_mv, x->nmvjointcost,
4872 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004873#endif // CONFIG_EXT_INTER
4874 }
4875}
4876
4877static int64_t rd_pick_best_sub8x8_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07004878 const AV1_COMP *const cpi, MACROBLOCK *x, int_mv *best_ref_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004879 int_mv *second_best_ref_mv, int64_t best_rd, int *returntotrate,
4880 int *returnyrate, int64_t *returndistortion, int *skippable, int64_t *psse,
4881 int mvthresh,
4882#if CONFIG_EXT_INTER
4883 int_mv seg_mvs[4][2][TOTAL_REFS_PER_FRAME],
4884 int_mv compound_seg_newmvs[4][2],
4885#else
4886 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME],
4887#endif // CONFIG_EXT_INTER
4888 BEST_SEG_INFO *bsi_buf, int filter_idx, int mi_row, int mi_col) {
4889 BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
4890#if CONFIG_REF_MV
4891 int_mv tmp_ref_mv[2];
4892#endif
4893 MACROBLOCKD *xd = &x->e_mbd;
4894 MODE_INFO *mi = xd->mi[0];
4895 MB_MODE_INFO *mbmi = &mi->mbmi;
4896 int mode_idx;
4897 int k, br = 0, idx, idy;
4898 int64_t bd = 0, block_sse = 0;
4899 PREDICTION_MODE this_mode;
Urvang Joshi52648442016-10-13 17:27:51 -07004900 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004901 struct macroblock_plane *const p = &x->plane[0];
4902 struct macroblockd_plane *const pd = &xd->plane[0];
4903 const int label_count = 4;
4904 int64_t this_segment_rd = 0;
4905 int label_mv_thresh;
4906 int segmentyrate = 0;
4907 const BLOCK_SIZE bsize = mbmi->sb_type;
4908 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
4909 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
4910 ENTROPY_CONTEXT t_above[2], t_left[2];
4911 int subpelmv = 1, have_ref = 0;
4912 const int has_second_rf = has_second_ref(mbmi);
4913 const int inter_mode_mask = cpi->sf.inter_mode_mask[bsize];
4914 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4915#if CONFIG_EXT_TX && CONFIG_RECT_TX
4916 mbmi->tx_size =
4917 xd->lossless[mbmi->segment_id] ? TX_4X4 : max_txsize_rect_lookup[bsize];
4918#else
4919 mbmi->tx_size = TX_4X4;
4920#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4921
Yaowu Xuf883b422016-08-30 14:01:10 -07004922 av1_zero(*bsi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004923
4924 bsi->segment_rd = best_rd;
4925 bsi->ref_mv[0] = best_ref_mv;
4926 bsi->ref_mv[1] = second_best_ref_mv;
4927 bsi->mvp.as_int = best_ref_mv->as_int;
4928 bsi->mvthresh = mvthresh;
4929
4930 for (idx = 0; idx < 4; ++idx) bsi->modes[idx] = ZEROMV;
4931
4932#if CONFIG_REFMV
4933 for (idx = 0; idx < 4; ++idx) {
4934 for (k = NEARESTMV; k <= NEWMV; ++k) {
4935 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[0].as_int = INVALID_MV;
4936 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[1].as_int = INVALID_MV;
4937
4938 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[0].as_int = INVALID_MV;
4939 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[1].as_int = INVALID_MV;
4940 }
4941 }
4942#endif
4943
4944 memcpy(t_above, pd->above_context, sizeof(t_above));
4945 memcpy(t_left, pd->left_context, sizeof(t_left));
4946
4947 // 64 makes this threshold really big effectively
4948 // making it so that we very rarely check mvs on
4949 // segments. setting this to 1 would make mv thresh
4950 // roughly equal to what it is for macroblocks
4951 label_mv_thresh = 1 * bsi->mvthresh / label_count;
4952
4953 // Segmentation method overheads
4954 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
4955 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
4956 // TODO(jingning,rbultje): rewrite the rate-distortion optimization
4957 // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
4958 int_mv mode_mv[MB_MODE_COUNT][2];
4959 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
4960 PREDICTION_MODE mode_selected = ZEROMV;
Urvang Joshi454280d2016-10-14 16:51:44 -07004961 int64_t new_best_rd = INT64_MAX;
4962 const int index = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004963 int ref;
4964#if CONFIG_REF_MV
4965 CANDIDATE_MV ref_mv_stack[2][MAX_REF_MV_STACK_SIZE];
4966 uint8_t ref_mv_count[2];
4967#endif
4968#if CONFIG_EXT_INTER
4969 int mv_idx;
4970 int_mv ref_mvs_sub8x8[2][2];
4971#endif // CONFIG_EXT_INTER
4972
4973 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
4974 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
4975#if CONFIG_EXT_INTER
4976 int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
Urvang Joshi454280d2016-10-14 16:51:44 -07004977 av1_update_mv_context(xd, mi, frame, mv_ref_list, index, mi_row, mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -07004978 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004979#endif // CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07004980#if CONFIG_GLOBAL_MOTION
4981 frame_mv[ZEROMV][frame].as_int =
4982 cm->global_motion[frame].motion_params.wmmat[0].as_int;
4983#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004984 frame_mv[ZEROMV][frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07004985#endif // CONFIG_GLOBAL_MOTION
Urvang Joshi454280d2016-10-14 16:51:44 -07004986 av1_append_sub8x8_mvs_for_idx(cm, xd, index, ref, mi_row, mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004987#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07004988 ref_mv_stack[ref], &ref_mv_count[ref],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004989#endif
4990#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07004991 mv_ref_list,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004992#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07004993 &frame_mv[NEARESTMV][frame],
4994 &frame_mv[NEARMV][frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004995
4996#if CONFIG_REF_MV
4997 tmp_ref_mv[ref] = frame_mv[NEARESTMV][mbmi->ref_frame[ref]];
4998 lower_mv_precision(&tmp_ref_mv[ref].as_mv, cm->allow_high_precision_mv);
4999 bsi->ref_mv[ref] = &tmp_ref_mv[ref];
5000 mbmi_ext->ref_mvs[frame][0] = tmp_ref_mv[ref];
5001#endif
5002
5003#if CONFIG_EXT_INTER
5004 mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
5005 mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07005006 av1_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
5007 &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005008
5009 if (has_second_rf) {
5010 frame_mv[ZERO_ZEROMV][frame].as_int = 0;
5011 frame_mv[NEAREST_NEARESTMV][frame].as_int =
5012 frame_mv[NEARESTMV][frame].as_int;
5013
5014 if (ref == 0) {
5015 frame_mv[NEAREST_NEARMV][frame].as_int =
5016 frame_mv[NEARESTMV][frame].as_int;
5017 frame_mv[NEAR_NEARESTMV][frame].as_int =
5018 frame_mv[NEARMV][frame].as_int;
5019 frame_mv[NEAREST_NEWMV][frame].as_int =
5020 frame_mv[NEARESTMV][frame].as_int;
5021 frame_mv[NEAR_NEWMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5022 frame_mv[NEAR_NEARMV][frame].as_int =
5023 frame_mv[NEARMV][frame].as_int;
5024 } else if (ref == 1) {
5025 frame_mv[NEAREST_NEARMV][frame].as_int =
5026 frame_mv[NEARMV][frame].as_int;
5027 frame_mv[NEAR_NEARESTMV][frame].as_int =
5028 frame_mv[NEARESTMV][frame].as_int;
5029 frame_mv[NEW_NEARESTMV][frame].as_int =
5030 frame_mv[NEARESTMV][frame].as_int;
5031 frame_mv[NEW_NEARMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5032 frame_mv[NEAR_NEARMV][frame].as_int =
5033 frame_mv[NEARMV][frame].as_int;
5034 }
5035 }
5036#endif // CONFIG_EXT_INTER
5037 }
5038
5039// search for the best motion vector on this segment
5040#if CONFIG_EXT_INTER
5041 for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
5042 this_mode <= (has_second_rf ? NEW_NEWMV : NEWFROMNEARMV);
5043 ++this_mode)
5044#else
5045 for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode)
5046#endif // CONFIG_EXT_INTER
5047 {
5048 const struct buf_2d orig_src = x->plane[0].src;
5049 struct buf_2d orig_pre[2];
5050 // This flag controls if the motion estimation will kick off. When it
5051 // is set to a non-zero value, the encoder will force motion estimation.
5052 int run_mv_search = 0;
5053
5054 mode_idx = INTER_OFFSET(this_mode);
5055#if CONFIG_EXT_INTER
5056 mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
5057
5058 for (ref = 0; ref < 1 + has_second_rf; ++ref)
5059 bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[mv_idx][ref].as_int;
5060#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005061 bsi->rdstat[index][mode_idx].brdcost = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005062 if (!(inter_mode_mask & (1 << this_mode))) continue;
5063
5064#if CONFIG_REF_MV
5065 run_mv_search = 2;
5066#if !CONFIG_EXT_INTER
5067 if (filter_idx > 0 && this_mode == NEWMV) {
5068 BEST_SEG_INFO *ref_bsi = bsi_buf;
Urvang Joshi454280d2016-10-14 16:51:44 -07005069 SEG_RDSTAT *ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005070
5071 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005072 if (seg_mvs[index][mbmi->ref_frame[0]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005073 ref_rdstat->mvs[0].as_int &&
5074 ref_rdstat->mvs[0].as_int != INVALID_MV)
5075 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
5076 --run_mv_search;
5077
Urvang Joshi454280d2016-10-14 16:51:44 -07005078 if (seg_mvs[index][mbmi->ref_frame[1]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005079 ref_rdstat->mvs[1].as_int &&
5080 ref_rdstat->mvs[1].as_int != INVALID_MV)
5081 if (bsi->ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
5082 --run_mv_search;
5083 } else {
5084 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
5085 ref_rdstat->mvs[0].as_int != INVALID_MV) {
5086 run_mv_search = 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005087 seg_mvs[index][mbmi->ref_frame[0]].as_int =
5088 ref_rdstat->mvs[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005089 }
5090 }
5091
5092 if (run_mv_search != 0 && filter_idx > 1) {
5093 ref_bsi = bsi_buf + 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07005094 ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005095 run_mv_search = 2;
5096
5097 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005098 if (seg_mvs[index][mbmi->ref_frame[0]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005099 ref_rdstat->mvs[0].as_int &&
5100 ref_rdstat->mvs[0].as_int != INVALID_MV)
5101 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
5102 --run_mv_search;
5103
Urvang Joshi454280d2016-10-14 16:51:44 -07005104 if (seg_mvs[index][mbmi->ref_frame[1]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005105 ref_rdstat->mvs[1].as_int &&
5106 ref_rdstat->mvs[1].as_int != INVALID_MV)
5107 if (bsi->ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
5108 --run_mv_search;
5109 } else {
5110 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
5111 ref_rdstat->mvs[0].as_int != INVALID_MV) {
5112 run_mv_search = 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005113 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005114 ref_rdstat->mvs[0].as_int;
5115 }
5116 }
5117 }
5118 }
5119#endif // CONFIG_EXT_INTER
5120#endif // CONFIG_REF_MV
5121
Sarah Parkere5299862016-08-16 14:57:37 -07005122#if CONFIG_GLOBAL_MOTION
5123 if (get_gmtype(&cm->global_motion[mbmi->ref_frame[0]]) == GLOBAL_ZERO &&
5124 (!has_second_rf ||
5125 get_gmtype(&cm->global_motion[mbmi->ref_frame[1]]) == GLOBAL_ZERO))
5126#endif // CONFIG_GLOBAL_MOTION
5127
5128 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005129#if CONFIG_REF_MV && CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005130 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005131#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005132 frame_mv, this_mode, mbmi->ref_frame, bsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07005133 index))
Sarah Parkere5299862016-08-16 14:57:37 -07005134 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005135
5136 memcpy(orig_pre, pd->pre, sizeof(orig_pre));
Urvang Joshi454280d2016-10-14 16:51:44 -07005137 memcpy(bsi->rdstat[index][mode_idx].ta, t_above,
5138 sizeof(bsi->rdstat[index][mode_idx].ta));
5139 memcpy(bsi->rdstat[index][mode_idx].tl, t_left,
5140 sizeof(bsi->rdstat[index][mode_idx].tl));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005141
5142 // motion search for newmv (single predictor case only)
5143 if (!has_second_rf &&
5144#if CONFIG_EXT_INTER
5145 have_newmv_in_inter_mode(this_mode) &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005146 (seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV ||
Yaowu Xuf883b422016-08-30 14:01:10 -07005147 av1_use_mv_hp(&bsi->ref_mv[0]->as_mv) == 0)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005148#else
5149 this_mode == NEWMV &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005150 (seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07005151 run_mv_search)
5152#endif // CONFIG_EXT_INTER
5153 ) {
5154 int step_param = 0;
5155 int bestsme = INT_MAX;
5156 int sadpb = x->sadperbit4;
5157 MV mvp_full;
5158 int max_mv;
5159 int cost_list[5];
5160 int tmp_col_min = x->mv_col_min;
5161 int tmp_col_max = x->mv_col_max;
5162 int tmp_row_min = x->mv_row_min;
5163 int tmp_row_max = x->mv_row_max;
5164
5165 /* Is the best so far sufficiently good that we cant justify doing
5166 * and new motion search. */
Urvang Joshi454280d2016-10-14 16:51:44 -07005167 if (new_best_rd < label_mv_thresh) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005168
5169 if (cpi->oxcf.mode != BEST) {
5170#if CONFIG_EXT_INTER
5171 bsi->mvp.as_int = bsi->ref_mv[0]->as_int;
5172#else
5173// use previous block's result as next block's MV predictor.
5174#if !CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07005175 if (index > 0) {
5176 bsi->mvp.as_int = mi->bmi[index - 1].as_mv[0].as_int;
5177 if (index == 2)
5178 bsi->mvp.as_int = mi->bmi[index - 2].as_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005179 }
5180#endif
5181#endif // CONFIG_EXT_INTER
5182 }
Urvang Joshi454280d2016-10-14 16:51:44 -07005183 max_mv = (index == 0) ? (int)x->max_mv_context[mbmi->ref_frame[0]]
5184 : AOMMAX(abs(bsi->mvp.as_mv.row),
5185 abs(bsi->mvp.as_mv.col)) >>
5186 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005187
5188 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
5189 // Take wtd average of the step_params based on the last frame's
5190 // max mv magnitude and the best ref mvs of the current block for
5191 // the given reference.
5192 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07005193 (av1_init_search_range(max_mv) + cpi->mv_step_param) / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005194 } else {
5195 step_param = cpi->mv_step_param;
5196 }
5197
5198#if CONFIG_REF_MV
5199 mvp_full.row = bsi->ref_mv[0]->as_mv.row >> 3;
5200 mvp_full.col = bsi->ref_mv[0]->as_mv.col >> 3;
5201#else
5202 mvp_full.row = bsi->mvp.as_mv.row >> 3;
5203 mvp_full.col = bsi->mvp.as_mv.col >> 3;
5204#endif
5205
5206 if (cpi->sf.adaptive_motion_search) {
5207 mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
5208 mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
Yaowu Xuf883b422016-08-30 14:01:10 -07005209 step_param = AOMMAX(step_param, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005210 }
5211
5212 // adjust src pointer for this block
Urvang Joshi454280d2016-10-14 16:51:44 -07005213 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005214
Yaowu Xuf883b422016-08-30 14:01:10 -07005215 av1_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005216
5217 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
5218
5219#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005220 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005221#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07005222 bestsme = av1_full_pixel_search(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005223 cpi, x, bsize, &mvp_full, step_param, sadpb,
5224 cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
5225 &bsi->ref_mv[0]->as_mv, INT_MAX, 1);
5226
5227 x->mv_col_min = tmp_col_min;
5228 x->mv_col_max = tmp_col_max;
5229 x->mv_row_min = tmp_row_min;
5230 x->mv_row_max = tmp_row_max;
5231
5232 if (bestsme < INT_MAX) {
5233 int distortion;
5234 if (cpi->sf.use_upsampled_references) {
5235 int best_mv_var;
5236 const int try_second =
5237 x->second_best_mv.as_int != INVALID_MV &&
5238 x->second_best_mv.as_int != x->best_mv.as_int;
5239 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
5240 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
5241 // Use up-sampled reference frames.
Yaowu Xuc27fc142016-08-22 16:08:15 -07005242 struct buf_2d backup_pred = pd->pre[0];
5243 const YV12_BUFFER_CONFIG *upsampled_ref =
5244 get_upsampled_ref(cpi, mbmi->ref_frame[0]);
5245
5246 // Set pred for Y plane
5247 setup_pred_plane(
5248 &pd->pre[0], upsampled_ref->y_buffer,
5249 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
5250 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
5251 pd->subsampling_x, pd->subsampling_y);
5252
5253 // adjust pred pointer for this block
5254 pd->pre[0].buf =
Urvang Joshi454280d2016-10-14 16:51:44 -07005255 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, index,
Yaowu Xuf883b422016-08-30 14:01:10 -07005256 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005257 << 3];
5258
5259 best_mv_var = cpi->find_fractional_mv_step(
5260 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
5261 x->errorperbit, &cpi->fn_ptr[bsize],
5262 cpi->sf.mv.subpel_force_stop,
5263 cpi->sf.mv.subpel_iters_per_step,
5264 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
5265 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, pw, ph,
5266 1);
5267
5268 if (try_second) {
5269 int this_var;
5270 MV best_mv = x->best_mv.as_mv;
5271 const MV ref_mv = bsi->ref_mv[0]->as_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07005272 const int minc = AOMMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
5273 const int maxc = AOMMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
5274 const int minr = AOMMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
5275 const int maxr = AOMMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005276
5277 x->best_mv = x->second_best_mv;
5278 if (x->best_mv.as_mv.row * 8 <= maxr &&
5279 x->best_mv.as_mv.row * 8 >= minr &&
5280 x->best_mv.as_mv.col * 8 <= maxc &&
5281 x->best_mv.as_mv.col * 8 >= minc) {
5282 this_var = cpi->find_fractional_mv_step(
5283 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
5284 x->errorperbit, &cpi->fn_ptr[bsize],
5285 cpi->sf.mv.subpel_force_stop,
5286 cpi->sf.mv.subpel_iters_per_step,
5287 cond_cost_list(cpi, cost_list), x->nmvjointcost,
5288 x->mvcost, &distortion, &x->pred_sse[mbmi->ref_frame[0]],
5289 NULL, pw, ph, 1);
5290 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
5291 x->best_mv.as_mv = best_mv;
5292 }
5293 }
5294
5295 // Restore the reference frames.
5296 pd->pre[0] = backup_pred;
5297 } else {
5298 cpi->find_fractional_mv_step(
5299 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
5300 x->errorperbit, &cpi->fn_ptr[bsize],
5301 cpi->sf.mv.subpel_force_stop,
5302 cpi->sf.mv.subpel_iters_per_step,
5303 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
5304 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, 0, 0, 0);
5305 }
5306
5307// save motion search result for use in compound prediction
5308#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005309 seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005310#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005311 seg_mvs[index][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005312#endif // CONFIG_EXT_INTER
5313 }
5314
5315 if (cpi->sf.adaptive_motion_search)
5316 x->pred_mv[mbmi->ref_frame[0]] = x->best_mv.as_mv;
5317
5318#if CONFIG_EXT_INTER
5319 mode_mv[this_mode][0] = x->best_mv;
5320#else
5321 mode_mv[NEWMV][0] = x->best_mv;
5322#endif // CONFIG_EXT_INTER
5323
5324 // restore src pointers
5325 mi_buf_restore(x, orig_src, orig_pre);
5326 }
5327
5328 if (has_second_rf) {
5329#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005330 if (seg_mvs[index][mv_idx][mbmi->ref_frame[1]].as_int == INVALID_MV ||
5331 seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005332#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005333 if (seg_mvs[index][mbmi->ref_frame[1]].as_int == INVALID_MV ||
5334 seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005335#endif // CONFIG_EXT_INTER
5336 continue;
5337 }
5338
5339#if CONFIG_DUAL_FILTER
5340 (void)run_mv_search;
5341#endif
5342
5343 if (has_second_rf &&
5344#if CONFIG_EXT_INTER
5345 this_mode == NEW_NEWMV &&
5346#else
5347 this_mode == NEWMV &&
5348#endif // CONFIG_EXT_INTER
5349#if CONFIG_DUAL_FILTER
5350 (mbmi->interp_filter[0] == EIGHTTAP_REGULAR || run_mv_search))
5351#else
5352 (mbmi->interp_filter == EIGHTTAP_REGULAR || run_mv_search))
5353#endif
5354 {
5355 // adjust src pointers
Urvang Joshi454280d2016-10-14 16:51:44 -07005356 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005357 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
5358 int rate_mv;
5359 joint_motion_search(cpi, x, bsize, frame_mv[this_mode], mi_row,
5360 mi_col,
5361#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005362 bsi->ref_mv, seg_mvs[index][mv_idx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005363#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005364 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005365#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005366 &rate_mv, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005367#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005368 compound_seg_newmvs[index][0].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005369 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07005370 compound_seg_newmvs[index][1].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005371 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
5372#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005373 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005374 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07005375 seg_mvs[index][mbmi->ref_frame[1]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005376 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
5377#endif // CONFIG_EXT_INTER
5378 }
5379 // restore src pointers
5380 mi_buf_restore(x, orig_src, orig_pre);
5381 }
5382
Urvang Joshi454280d2016-10-14 16:51:44 -07005383 bsi->rdstat[index][mode_idx].brate = set_and_cost_bmi_mvs(
5384 cpi, x, xd, index, this_mode, mode_mv[this_mode], frame_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005385#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005386 seg_mvs[index][mv_idx], compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005387#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005388 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005389#endif // CONFIG_EXT_INTER
5390 bsi->ref_mv, x->nmvjointcost, x->mvcost);
5391
5392 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005393 bsi->rdstat[index][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005394 mode_mv[this_mode][ref].as_int;
5395 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005396 bsi->rdstat[index + 1][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005397 mode_mv[this_mode][ref].as_int;
5398 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005399 bsi->rdstat[index + 2][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005400 mode_mv[this_mode][ref].as_int;
5401#if CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07005402 bsi->rdstat[index][mode_idx].pred_mv[ref].as_int =
5403 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005404 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005405 bsi->rdstat[index + 1][mode_idx].pred_mv[ref].as_int =
5406 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005407 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005408 bsi->rdstat[index + 2][mode_idx].pred_mv[ref].as_int =
5409 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005410#endif
5411#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005412 bsi->rdstat[index][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005413 bsi->ref_mv[ref]->as_int;
5414 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005415 bsi->rdstat[index + 1][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005416 bsi->ref_mv[ref]->as_int;
5417 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005418 bsi->rdstat[index + 2][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005419 bsi->ref_mv[ref]->as_int;
5420#endif // CONFIG_EXT_INTER
5421 }
5422
5423 // Trap vectors that reach beyond the UMV borders
5424 if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
5425 (has_second_rf && mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
5426 continue;
5427
5428 if (filter_idx > 0) {
5429 BEST_SEG_INFO *ref_bsi = bsi_buf;
5430 subpelmv = 0;
5431 have_ref = 1;
5432
5433 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5434 subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
5435#if CONFIG_EXT_INTER
5436 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07005437 have_ref &=
5438 ((mode_mv[this_mode][ref].as_int ==
5439 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
5440 (bsi->ref_mv[ref]->as_int ==
5441 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005442 else
5443#endif // CONFIG_EXT_INTER
5444 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07005445 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005446 }
5447
Urvang Joshi454280d2016-10-14 16:51:44 -07005448 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005449
5450 if (filter_idx > 1 && !subpelmv && !have_ref) {
5451 ref_bsi = bsi_buf + 1;
5452 have_ref = 1;
5453 for (ref = 0; ref < 1 + has_second_rf; ++ref)
5454#if CONFIG_EXT_INTER
5455 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07005456 have_ref &=
5457 ((mode_mv[this_mode][ref].as_int ==
5458 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
5459 (bsi->ref_mv[ref]->as_int ==
5460 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005461 else
5462#endif // CONFIG_EXT_INTER
5463 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07005464 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005465
Urvang Joshi454280d2016-10-14 16:51:44 -07005466 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005467 }
5468
5469 if (!subpelmv && have_ref &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005470 ref_bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005471#if CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07005472 bsi->rdstat[index][mode_idx].byrate =
5473 ref_bsi->rdstat[index][mode_idx].byrate;
5474 bsi->rdstat[index][mode_idx].bdist =
5475 ref_bsi->rdstat[index][mode_idx].bdist;
5476 bsi->rdstat[index][mode_idx].bsse =
5477 ref_bsi->rdstat[index][mode_idx].bsse;
5478 bsi->rdstat[index][mode_idx].brate +=
5479 ref_bsi->rdstat[index][mode_idx].byrate;
5480 bsi->rdstat[index][mode_idx].eobs =
5481 ref_bsi->rdstat[index][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005482
Urvang Joshi454280d2016-10-14 16:51:44 -07005483 bsi->rdstat[index][mode_idx].brdcost =
5484 RDCOST(x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate,
5485 bsi->rdstat[index][mode_idx].bdist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005486
Urvang Joshi454280d2016-10-14 16:51:44 -07005487 memcpy(bsi->rdstat[index][mode_idx].ta,
5488 ref_bsi->rdstat[index][mode_idx].ta,
5489 sizeof(bsi->rdstat[index][mode_idx].ta));
5490 memcpy(bsi->rdstat[index][mode_idx].tl,
5491 ref_bsi->rdstat[index][mode_idx].tl,
5492 sizeof(bsi->rdstat[index][mode_idx].tl));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005493#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005494 memcpy(&bsi->rdstat[index][mode_idx],
5495 &ref_bsi->rdstat[index][mode_idx], sizeof(SEG_RDSTAT));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005496#endif
5497 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005498 bsi->rdstat[index + 1][mode_idx].eobs =
5499 ref_bsi->rdstat[index + 1][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005500 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005501 bsi->rdstat[index + 2][mode_idx].eobs =
5502 ref_bsi->rdstat[index + 2][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005503
Urvang Joshi454280d2016-10-14 16:51:44 -07005504 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005505#if CONFIG_REF_MV
5506 // If the NEWMV mode is using the same motion vector as the
5507 // NEARESTMV mode, skip the rest rate-distortion calculations
5508 // and use the inferred motion vector modes.
5509 if (this_mode == NEWMV) {
5510 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005511 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005512 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005513 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005514 bsi->ref_mv[1]->as_int)
5515 continue;
5516 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07005517 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005518 bsi->ref_mv[0]->as_int)
5519 continue;
5520 }
5521 }
5522#endif
5523 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07005524 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005525 }
5526 continue;
5527 }
5528 }
5529
Urvang Joshi454280d2016-10-14 16:51:44 -07005530 bsi->rdstat[index][mode_idx].brdcost = encode_inter_mb_segment(
5531 cpi, x, bsi->segment_rd - this_segment_rd, index,
5532 &bsi->rdstat[index][mode_idx].byrate,
5533 &bsi->rdstat[index][mode_idx].bdist,
5534 &bsi->rdstat[index][mode_idx].bsse, bsi->rdstat[index][mode_idx].ta,
5535 bsi->rdstat[index][mode_idx].tl, idy, idx, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005536
Urvang Joshi454280d2016-10-14 16:51:44 -07005537 if (bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
5538 bsi->rdstat[index][mode_idx].brdcost += RDCOST(
5539 x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate, 0);
5540 bsi->rdstat[index][mode_idx].brate +=
5541 bsi->rdstat[index][mode_idx].byrate;
5542 bsi->rdstat[index][mode_idx].eobs = p->eobs[index];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005543 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005544 bsi->rdstat[index + 1][mode_idx].eobs = p->eobs[index + 1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005545 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005546 bsi->rdstat[index + 2][mode_idx].eobs = p->eobs[index + 2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005547 }
5548
Urvang Joshi454280d2016-10-14 16:51:44 -07005549 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005550#if CONFIG_REF_MV
5551 // If the NEWMV mode is using the same motion vector as the
5552 // NEARESTMV mode, skip the rest rate-distortion calculations
5553 // and use the inferred motion vector modes.
5554 if (this_mode == NEWMV) {
5555 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005556 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005557 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005558 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005559 bsi->ref_mv[1]->as_int)
5560 continue;
5561 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07005562 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005563 bsi->ref_mv[0]->as_int)
5564 continue;
5565 }
5566 }
5567#endif
5568 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07005569 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005570 }
5571 } /*for each 4x4 mode*/
5572
Urvang Joshi454280d2016-10-14 16:51:44 -07005573 if (new_best_rd == INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005574 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07005575 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005576#if CONFIG_EXT_INTER
5577 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
5578#else
5579 for (midx = 0; midx < INTER_MODES; ++midx)
5580#endif // CONFIG_EXT_INTER
5581 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
5582 bsi->segment_rd = INT64_MAX;
5583 return INT64_MAX;
5584 }
5585
5586 mode_idx = INTER_OFFSET(mode_selected);
Urvang Joshi454280d2016-10-14 16:51:44 -07005587 memcpy(t_above, bsi->rdstat[index][mode_idx].ta, sizeof(t_above));
5588 memcpy(t_left, bsi->rdstat[index][mode_idx].tl, sizeof(t_left));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005589
5590#if CONFIG_EXT_INTER
5591 mv_idx = (mode_selected == NEWFROMNEARMV) ? 1 : 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005592 bsi->ref_mv[0]->as_int = bsi->rdstat[index][mode_idx].ref_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005593 if (has_second_rf)
Urvang Joshi454280d2016-10-14 16:51:44 -07005594 bsi->ref_mv[1]->as_int = bsi->rdstat[index][mode_idx].ref_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005595#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005596 set_and_cost_bmi_mvs(cpi, x, xd, index, mode_selected,
5597 mode_mv[mode_selected], frame_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005598#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005599 seg_mvs[index][mv_idx], compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005600#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005601 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005602#endif // CONFIG_EXT_INTER
5603 bsi->ref_mv, x->nmvjointcost, x->mvcost);
5604
Urvang Joshi454280d2016-10-14 16:51:44 -07005605 br += bsi->rdstat[index][mode_idx].brate;
5606 bd += bsi->rdstat[index][mode_idx].bdist;
5607 block_sse += bsi->rdstat[index][mode_idx].bsse;
5608 segmentyrate += bsi->rdstat[index][mode_idx].byrate;
5609 this_segment_rd += bsi->rdstat[index][mode_idx].brdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005610
5611 if (this_segment_rd > bsi->segment_rd) {
5612 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07005613 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005614#if CONFIG_EXT_INTER
5615 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
5616#else
5617 for (midx = 0; midx < INTER_MODES; ++midx)
5618#endif // CONFIG_EXT_INTER
5619 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
5620 bsi->segment_rd = INT64_MAX;
5621 return INT64_MAX;
5622 }
5623 }
5624 } /* for each label */
5625
5626 bsi->r = br;
5627 bsi->d = bd;
5628 bsi->segment_yrate = segmentyrate;
5629 bsi->segment_rd = this_segment_rd;
5630 bsi->sse = block_sse;
5631
5632 // update the coding decisions
5633 for (k = 0; k < 4; ++k) bsi->modes[k] = mi->bmi[k].as_mode;
5634
5635 if (bsi->segment_rd > best_rd) return INT64_MAX;
5636 /* set it to the best */
5637 for (idx = 0; idx < 4; idx++) {
5638 mode_idx = INTER_OFFSET(bsi->modes[idx]);
5639 mi->bmi[idx].as_mv[0].as_int = bsi->rdstat[idx][mode_idx].mvs[0].as_int;
5640 if (has_second_ref(mbmi))
5641 mi->bmi[idx].as_mv[1].as_int = bsi->rdstat[idx][mode_idx].mvs[1].as_int;
5642#if CONFIG_REF_MV
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07005643 mi->bmi[idx].pred_mv[0] = bsi->rdstat[idx][mode_idx].pred_mv[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005644 if (has_second_ref(mbmi))
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07005645 mi->bmi[idx].pred_mv[1] = bsi->rdstat[idx][mode_idx].pred_mv[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005646#endif
5647#if CONFIG_EXT_INTER
5648 mi->bmi[idx].ref_mv[0].as_int = bsi->rdstat[idx][mode_idx].ref_mv[0].as_int;
5649 if (has_second_rf)
5650 mi->bmi[idx].ref_mv[1].as_int =
5651 bsi->rdstat[idx][mode_idx].ref_mv[1].as_int;
5652#endif // CONFIG_EXT_INTER
5653 x->plane[0].eobs[idx] = bsi->rdstat[idx][mode_idx].eobs;
5654 mi->bmi[idx].as_mode = bsi->modes[idx];
5655 }
5656
5657 /*
5658 * used to set mbmi->mv.as_int
5659 */
5660 *returntotrate = bsi->r;
5661 *returndistortion = bsi->d;
5662 *returnyrate = bsi->segment_yrate;
Yaowu Xuf883b422016-08-30 14:01:10 -07005663 *skippable = av1_is_skippable_in_plane(x, BLOCK_8X8, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005664 *psse = bsi->sse;
5665 mbmi->mode = bsi->modes[3];
5666
5667 return bsi->segment_rd;
5668}
5669
Yaowu Xuf883b422016-08-30 14:01:10 -07005670static void estimate_ref_frame_costs(const AV1_COMMON *cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005671 const MACROBLOCKD *xd, int segment_id,
5672 unsigned int *ref_costs_single,
5673 unsigned int *ref_costs_comp,
Yaowu Xuf883b422016-08-30 14:01:10 -07005674 aom_prob *comp_mode_p) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005675 int seg_ref_active =
5676 segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
5677 if (seg_ref_active) {
5678 memset(ref_costs_single, 0,
5679 TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_single));
5680 memset(ref_costs_comp, 0, TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_comp));
5681 *comp_mode_p = 128;
5682 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005683 aom_prob intra_inter_p = av1_get_intra_inter_prob(cm, xd);
5684 aom_prob comp_inter_p = 128;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005685
5686 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005687 comp_inter_p = av1_get_reference_mode_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005688 *comp_mode_p = comp_inter_p;
5689 } else {
5690 *comp_mode_p = 128;
5691 }
5692
Yaowu Xuf883b422016-08-30 14:01:10 -07005693 ref_costs_single[INTRA_FRAME] = av1_cost_bit(intra_inter_p, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005694
5695 if (cm->reference_mode != COMPOUND_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005696 aom_prob ref_single_p1 = av1_get_pred_prob_single_ref_p1(cm, xd);
5697 aom_prob ref_single_p2 = av1_get_pred_prob_single_ref_p2(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005698#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005699 aom_prob ref_single_p3 = av1_get_pred_prob_single_ref_p3(cm, xd);
5700 aom_prob ref_single_p4 = av1_get_pred_prob_single_ref_p4(cm, xd);
5701 aom_prob ref_single_p5 = av1_get_pred_prob_single_ref_p5(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005702#endif // CONFIG_EXT_REFS
5703
Yaowu Xuf883b422016-08-30 14:01:10 -07005704 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005705
5706 ref_costs_single[LAST_FRAME] =
5707#if CONFIG_EXT_REFS
5708 ref_costs_single[LAST2_FRAME] = ref_costs_single[LAST3_FRAME] =
5709 ref_costs_single[BWDREF_FRAME] =
5710#endif // CONFIG_EXT_REFS
5711 ref_costs_single[GOLDEN_FRAME] =
5712 ref_costs_single[ALTREF_FRAME] = base_cost;
5713
5714#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005715 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
5716 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p1, 0);
5717 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p1, 0);
5718 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 0);
5719 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
5720 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005721
Yaowu Xuf883b422016-08-30 14:01:10 -07005722 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p3, 0);
5723 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p3, 0);
5724 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p3, 1);
5725 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p3, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005726
Yaowu Xuf883b422016-08-30 14:01:10 -07005727 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p2, 0);
5728 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005729
Yaowu Xuf883b422016-08-30 14:01:10 -07005730 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p4, 0);
5731 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p4, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005732
Yaowu Xuf883b422016-08-30 14:01:10 -07005733 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p5, 0);
5734 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p5, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005735#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005736 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
5737 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 1);
5738 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005739
Yaowu Xuf883b422016-08-30 14:01:10 -07005740 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p2, 0);
5741 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005742#endif // CONFIG_EXT_REFS
5743 } else {
5744 ref_costs_single[LAST_FRAME] = 512;
5745#if CONFIG_EXT_REFS
5746 ref_costs_single[LAST2_FRAME] = 512;
5747 ref_costs_single[LAST3_FRAME] = 512;
5748 ref_costs_single[BWDREF_FRAME] = 512;
5749#endif // CONFIG_EXT_REFS
5750 ref_costs_single[GOLDEN_FRAME] = 512;
5751 ref_costs_single[ALTREF_FRAME] = 512;
5752 }
5753
5754 if (cm->reference_mode != SINGLE_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005755 aom_prob ref_comp_p = av1_get_pred_prob_comp_ref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005756#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005757 aom_prob ref_comp_p1 = av1_get_pred_prob_comp_ref_p1(cm, xd);
5758 aom_prob ref_comp_p2 = av1_get_pred_prob_comp_ref_p2(cm, xd);
5759 aom_prob bwdref_comp_p = av1_get_pred_prob_comp_bwdref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005760#endif // CONFIG_EXT_REFS
5761
Yaowu Xuf883b422016-08-30 14:01:10 -07005762 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005763
5764 ref_costs_comp[LAST_FRAME] =
5765#if CONFIG_EXT_REFS
5766 ref_costs_comp[LAST2_FRAME] = ref_costs_comp[LAST3_FRAME] =
5767#endif // CONFIG_EXT_REFS
5768 ref_costs_comp[GOLDEN_FRAME] = base_cost;
5769
5770#if CONFIG_EXT_REFS
5771 ref_costs_comp[BWDREF_FRAME] = ref_costs_comp[ALTREF_FRAME] = 0;
5772#endif // CONFIG_EXT_REFS
5773
5774#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005775 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
5776 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p, 0);
5777 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p, 1);
5778 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005779
Yaowu Xuf883b422016-08-30 14:01:10 -07005780 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p1, 1);
5781 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005782
Yaowu Xuf883b422016-08-30 14:01:10 -07005783 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p2, 0);
5784 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005785
5786 // NOTE(zoeliu): BWDREF and ALTREF each add an extra cost by coding 1
5787 // more bit.
Yaowu Xuf883b422016-08-30 14:01:10 -07005788 ref_costs_comp[BWDREF_FRAME] += av1_cost_bit(bwdref_comp_p, 0);
5789 ref_costs_comp[ALTREF_FRAME] += av1_cost_bit(bwdref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005790#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005791 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
5792 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005793#endif // CONFIG_EXT_REFS
5794 } else {
5795 ref_costs_comp[LAST_FRAME] = 512;
5796#if CONFIG_EXT_REFS
5797 ref_costs_comp[LAST2_FRAME] = 512;
5798 ref_costs_comp[LAST3_FRAME] = 512;
5799 ref_costs_comp[BWDREF_FRAME] = 512;
5800 ref_costs_comp[ALTREF_FRAME] = 512;
5801#endif // CONFIG_EXT_REFS
5802 ref_costs_comp[GOLDEN_FRAME] = 512;
5803 }
5804 }
5805}
5806
5807static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
5808 int mode_index,
5809 int64_t comp_pred_diff[REFERENCE_MODES],
5810 int skippable) {
5811 MACROBLOCKD *const xd = &x->e_mbd;
5812
5813 // Take a snapshot of the coding context so it can be
5814 // restored if we decide to encode this way
5815 ctx->skip = x->skip;
5816 ctx->skippable = skippable;
5817 ctx->best_mode_index = mode_index;
5818 ctx->mic = *xd->mi[0];
5819 ctx->mbmi_ext = *x->mbmi_ext;
5820 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
5821 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
5822 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
5823}
5824
Urvang Joshi52648442016-10-13 17:27:51 -07005825static void setup_buffer_inter(const AV1_COMP *const cpi, MACROBLOCK *x,
clang-format67948d32016-09-07 22:40:40 -07005826 MV_REFERENCE_FRAME ref_frame,
5827 BLOCK_SIZE block_size, int mi_row, int mi_col,
5828 int_mv frame_nearest_mv[TOTAL_REFS_PER_FRAME],
5829 int_mv frame_near_mv[TOTAL_REFS_PER_FRAME],
5830 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME]
5831 [MAX_MB_PLANE]) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005832 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005833 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
5834 MACROBLOCKD *const xd = &x->e_mbd;
5835 MODE_INFO *const mi = xd->mi[0];
5836 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
5837 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
5838 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
5839
5840 assert(yv12 != NULL);
5841
5842 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
5843 // use the UV scaling factors.
Yaowu Xuf883b422016-08-30 14:01:10 -07005844 av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005845
5846 // Gets an initial list of candidate vectors from neighbours and orders them
Yaowu Xuf883b422016-08-30 14:01:10 -07005847 av1_find_mv_refs(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005848 cm, xd, mi, ref_frame,
5849#if CONFIG_REF_MV
5850 &mbmi_ext->ref_mv_count[ref_frame], mbmi_ext->ref_mv_stack[ref_frame],
5851#if CONFIG_EXT_INTER
5852 mbmi_ext->compound_mode_context,
5853#endif // CONFIG_EXT_INTER
5854#endif
5855 candidates, mi_row, mi_col, NULL, NULL, mbmi_ext->mode_context);
5856
5857 // Candidate refinement carried out at encoder and decoder
Yaowu Xuf883b422016-08-30 14:01:10 -07005858 av1_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
5859 &frame_nearest_mv[ref_frame],
5860 &frame_near_mv[ref_frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005861
5862 // Further refinement that is encode side only to test the top few candidates
5863 // in full and choose the best as the centre point for subsequent searches.
5864 // The current implementation doesn't support scaling.
Yaowu Xuf883b422016-08-30 14:01:10 -07005865 if (!av1_is_scaled(sf) && block_size >= BLOCK_8X8)
5866 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
5867 block_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005868}
5869
Urvang Joshi52648442016-10-13 17:27:51 -07005870static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
5871 BLOCK_SIZE bsize, int mi_row, int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005872#if CONFIG_EXT_INTER
5873 int ref_idx, int mv_idx,
5874#endif // CONFIG_EXT_INTER
5875 int *rate_mv) {
5876 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07005877 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005878 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5879 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
5880 int bestsme = INT_MAX;
5881 int step_param;
5882 int sadpb = x->sadperbit16;
5883 MV mvp_full;
5884#if CONFIG_EXT_INTER
5885 int ref = mbmi->ref_frame[ref_idx];
5886 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
5887#else
5888 int ref = mbmi->ref_frame[0];
5889 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
5890 int ref_idx = 0;
5891#endif // CONFIG_EXT_INTER
5892
5893 int tmp_col_min = x->mv_col_min;
5894 int tmp_col_max = x->mv_col_max;
5895 int tmp_row_min = x->mv_row_min;
5896 int tmp_row_max = x->mv_row_max;
5897 int cost_list[5];
5898
5899 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07005900 av1_get_scaled_ref_frame(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005901
5902 MV pred_mv[3];
5903 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
5904 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
5905 pred_mv[2] = x->pred_mv[ref];
5906
Yaowu Xuc27fc142016-08-22 16:08:15 -07005907 if (scaled_ref_frame) {
5908 int i;
5909 // Swap out the reference frame for a version that's been scaled to
5910 // match the resolution of the current frame, allowing the existing
5911 // motion search code to be used without additional modifications.
5912 for (i = 0; i < MAX_MB_PLANE; i++)
5913 backup_yv12[i] = xd->plane[i].pre[ref_idx];
5914
Yaowu Xuf883b422016-08-30 14:01:10 -07005915 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005916 }
5917
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005918 av1_set_mv_search_range(x, &ref_mv);
5919
5920#if CONFIG_REF_MV
5921 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
5922#endif
5923
Yaowu Xuc27fc142016-08-22 16:08:15 -07005924 // Work out the size of the first step in the mv step search.
Yaowu Xuf883b422016-08-30 14:01:10 -07005925 // 0 here is maximum length first step. 1 is AOMMAX >> 1 etc.
Yaowu Xuc27fc142016-08-22 16:08:15 -07005926 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
5927 // Take wtd average of the step_params based on the last frame's
5928 // max mv magnitude and that based on the best ref mvs of the current
5929 // block for the given reference.
5930 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07005931 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07005932 2;
5933 } else {
5934 step_param = cpi->mv_step_param;
5935 }
5936
5937 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size) {
5938 int boffset =
5939 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07005940 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
5941 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005942 }
5943
5944 if (cpi->sf.adaptive_motion_search) {
5945 int bwl = b_width_log2_lookup[bsize];
5946 int bhl = b_height_log2_lookup[bsize];
5947 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
5948
5949 if (tlevel < 5) step_param += 2;
5950
5951 // prev_mv_sad is not setup for dynamically scaled frames.
5952 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
5953 int i;
5954 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
5955 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
5956 x->pred_mv[ref].row = 0;
5957 x->pred_mv[ref].col = 0;
5958 x->best_mv.as_int = INVALID_MV;
5959
5960 if (scaled_ref_frame) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005961 int j;
5962 for (j = 0; j < MAX_MB_PLANE; ++j)
5963 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005964 }
5965 return;
5966 }
5967 }
5968 }
5969 }
5970
Yaowu Xuf883b422016-08-30 14:01:10 -07005971 av1_set_mv_search_range(x, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005972
Yue Chene9638cc2016-10-10 12:37:54 -07005973#if CONFIG_MOTION_VAR
5974 if (mbmi->motion_mode != SIMPLE_TRANSLATION)
5975 mvp_full = mbmi->mv[0].as_mv;
5976 else
5977#endif // CONFIG_MOTION_VAR
5978 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005979
5980 mvp_full.col >>= 3;
5981 mvp_full.row >>= 3;
5982
5983 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
5984
Yue Chene9638cc2016-10-10 12:37:54 -07005985#if CONFIG_MOTION_VAR
5986 switch (mbmi->motion_mode) {
5987 case SIMPLE_TRANSLATION:
5988#endif // CONFIG_MOTION_VAR
5989 bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
5990 sadpb, cond_cost_list(cpi, cost_list),
5991 &ref_mv, INT_MAX, 1);
5992#if CONFIG_MOTION_VAR
5993 break;
5994 case OBMC_CAUSAL:
5995 bestsme = av1_obmc_full_pixel_diamond(
5996 cpi, x, &mvp_full, step_param, sadpb,
5997 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
5998 &(x->best_mv.as_mv), 0);
5999 break;
6000 default: assert("Invalid motion mode!\n");
6001 }
6002#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006003
6004 x->mv_col_min = tmp_col_min;
6005 x->mv_col_max = tmp_col_max;
6006 x->mv_row_min = tmp_row_min;
6007 x->mv_row_max = tmp_row_max;
6008
6009 if (bestsme < INT_MAX) {
6010 int dis; /* TODO: use dis in distortion calculation later. */
Yue Chene9638cc2016-10-10 12:37:54 -07006011#if CONFIG_MOTION_VAR
6012 switch (mbmi->motion_mode) {
6013 case SIMPLE_TRANSLATION:
6014#endif // CONFIG_MOTION_VAR
6015 if (cpi->sf.use_upsampled_references) {
6016 int best_mv_var;
6017 const int try_second = x->second_best_mv.as_int != INVALID_MV &&
6018 x->second_best_mv.as_int != x->best_mv.as_int;
6019 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
6020 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
6021 // Use up-sampled reference frames.
6022 struct macroblockd_plane *const pd = &xd->plane[0];
6023 struct buf_2d backup_pred = pd->pre[ref_idx];
6024 const YV12_BUFFER_CONFIG *upsampled_ref = get_upsampled_ref(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006025
Yue Chene9638cc2016-10-10 12:37:54 -07006026 // Set pred for Y plane
6027 setup_pred_plane(
6028 &pd->pre[ref_idx], upsampled_ref->y_buffer,
6029 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
6030 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
6031 pd->subsampling_x, pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006032
Yue Chene9638cc2016-10-10 12:37:54 -07006033 best_mv_var = cpi->find_fractional_mv_step(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006034 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6035 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6036 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
6037 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, pw, ph,
6038 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006039
Yue Chene9638cc2016-10-10 12:37:54 -07006040 if (try_second) {
6041 const int minc = AOMMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
6042 const int maxc = AOMMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
6043 const int minr = AOMMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
6044 const int maxr = AOMMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
6045 int this_var;
6046 MV best_mv = x->best_mv.as_mv;
6047
6048 x->best_mv = x->second_best_mv;
6049 if (x->best_mv.as_mv.row * 8 <= maxr &&
6050 x->best_mv.as_mv.row * 8 >= minr &&
6051 x->best_mv.as_mv.col * 8 <= maxc &&
6052 x->best_mv.as_mv.col * 8 >= minc) {
6053 this_var = cpi->find_fractional_mv_step(
6054 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6055 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6056 cpi->sf.mv.subpel_iters_per_step,
6057 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
6058 &dis, &x->pred_sse[ref], NULL, pw, ph, 1);
6059 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
6060 x->best_mv.as_mv = best_mv;
6061 }
6062 }
6063
6064 // Restore the reference frames.
6065 pd->pre[ref_idx] = backup_pred;
6066 } else {
6067 cpi->find_fractional_mv_step(
6068 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6069 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6070 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
6071 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, 0, 0,
6072 0);
6073 }
6074#if CONFIG_MOTION_VAR
6075 break;
6076 case OBMC_CAUSAL:
6077 av1_find_best_obmc_sub_pixel_tree_up(
6078 cpi, x, mi_row, mi_col, &x->best_mv.as_mv, &ref_mv,
6079 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
6080 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
6081 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], 0,
6082 cpi->sf.use_upsampled_references);
6083 break;
6084 default: assert("Invalid motion mode!\n");
Yaowu Xuc27fc142016-08-22 16:08:15 -07006085 }
Yue Chene9638cc2016-10-10 12:37:54 -07006086#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006087 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006088 *rate_mv = av1_mv_bit_cost(&x->best_mv.as_mv, &ref_mv, x->nmvjointcost,
6089 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006090
Yue Chene9638cc2016-10-10 12:37:54 -07006091#if CONFIG_MOTION_VAR
6092 if (cpi->sf.adaptive_motion_search && mbmi->motion_mode == SIMPLE_TRANSLATION)
6093#else
6094 if (cpi->sf.adaptive_motion_search)
6095#endif // CONFIG_MOTION_VAR
6096 x->pred_mv[ref] = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006097
6098 if (scaled_ref_frame) {
6099 int i;
6100 for (i = 0; i < MAX_MB_PLANE; i++)
6101 xd->plane[i].pre[ref_idx] = backup_yv12[i];
6102 }
6103}
6104
6105static INLINE void restore_dst_buf(MACROBLOCKD *xd,
6106 uint8_t *orig_dst[MAX_MB_PLANE],
6107 int orig_dst_stride[MAX_MB_PLANE]) {
6108 int i;
6109 for (i = 0; i < MAX_MB_PLANE; i++) {
6110 xd->plane[i].dst.buf = orig_dst[i];
6111 xd->plane[i].dst.stride = orig_dst_stride[i];
6112 }
6113}
6114
Yaowu Xuc27fc142016-08-22 16:08:15 -07006115#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07006116static void do_masked_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006117 const uint8_t *mask, int mask_stride,
6118 BLOCK_SIZE bsize, int mi_row, int mi_col,
6119 int_mv *tmp_mv, int *rate_mv, int ref_idx,
6120 int mv_idx) {
6121 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07006122 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006123 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6124 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
6125 int bestsme = INT_MAX;
6126 int step_param;
6127 int sadpb = x->sadperbit16;
6128 MV mvp_full;
6129 int ref = mbmi->ref_frame[ref_idx];
6130 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
6131
6132 int tmp_col_min = x->mv_col_min;
6133 int tmp_col_max = x->mv_col_max;
6134 int tmp_row_min = x->mv_row_min;
6135 int tmp_row_max = x->mv_row_max;
6136
6137 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07006138 av1_get_scaled_ref_frame(cpi, ref);
Urvang Joshi368fbc92016-10-17 16:31:34 -07006139 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006140
6141 MV pred_mv[3];
6142 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6143 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
6144 pred_mv[2] = x->pred_mv[ref];
6145
6146#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006147 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006148#endif
6149
6150 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006151 // Swap out the reference frame for a version that's been scaled to
6152 // match the resolution of the current frame, allowing the existing
6153 // motion search code to be used without additional modifications.
6154 for (i = 0; i < MAX_MB_PLANE; i++)
6155 backup_yv12[i] = xd->plane[i].pre[ref_idx];
6156
Yaowu Xuf883b422016-08-30 14:01:10 -07006157 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006158 }
6159
Yaowu Xuf883b422016-08-30 14:01:10 -07006160 av1_set_mv_search_range(x, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006161
6162 // Work out the size of the first step in the mv step search.
6163 // 0 here is maximum length first step. 1 is MAX >> 1 etc.
6164 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6165 // Take wtd average of the step_params based on the last frame's
6166 // max mv magnitude and that based on the best ref mvs of the current
6167 // block for the given reference.
6168 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006169 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07006170 2;
6171 } else {
6172 step_param = cpi->mv_step_param;
6173 }
6174
6175 // TODO(debargha): is show_frame needed here?
6176 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size && cm->show_frame) {
6177 int boffset =
6178 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07006179 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
6180 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006181 }
6182
6183 if (cpi->sf.adaptive_motion_search) {
6184 int bwl = b_width_log2_lookup[bsize];
6185 int bhl = b_height_log2_lookup[bsize];
6186 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
6187
6188 if (tlevel < 5) step_param += 2;
6189
6190 // prev_mv_sad is not setup for dynamically scaled frames.
6191 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006192 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
6193 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
6194 x->pred_mv[ref].row = 0;
6195 x->pred_mv[ref].col = 0;
6196 tmp_mv->as_int = INVALID_MV;
6197
6198 if (scaled_ref_frame) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07006199 int j;
6200 for (j = 0; j < MAX_MB_PLANE; ++j)
6201 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006202 }
6203 return;
6204 }
6205 }
6206 }
6207 }
6208
6209 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
6210
6211 mvp_full.col >>= 3;
6212 mvp_full.row >>= 3;
6213
Yaowu Xuf883b422016-08-30 14:01:10 -07006214 bestsme = av1_masked_full_pixel_diamond(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006215 cpi, x, mask, mask_stride, &mvp_full, step_param, sadpb,
6216 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
6217 &tmp_mv->as_mv, ref_idx);
6218
6219 x->mv_col_min = tmp_col_min;
6220 x->mv_col_max = tmp_col_max;
6221 x->mv_row_min = tmp_row_min;
6222 x->mv_row_max = tmp_row_max;
6223
6224 if (bestsme < INT_MAX) {
6225 int dis; /* TODO: use dis in distortion calculation later. */
Yaowu Xuf883b422016-08-30 14:01:10 -07006226 av1_find_best_masked_sub_pixel_tree_up(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006227 cpi, x, mask, mask_stride, mi_row, mi_col, &tmp_mv->as_mv, &ref_mv,
6228 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
6229 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
6230 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], ref_idx,
6231 cpi->sf.use_upsampled_references);
6232 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006233 *rate_mv = av1_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmvjointcost,
6234 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006235
6236 if (cpi->sf.adaptive_motion_search && cm->show_frame)
6237 x->pred_mv[ref] = tmp_mv->as_mv;
6238
6239 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006240 for (i = 0; i < MAX_MB_PLANE; i++)
6241 xd->plane[i].pre[ref_idx] = backup_yv12[i];
6242 }
6243}
6244
Urvang Joshi52648442016-10-13 17:27:51 -07006245static void do_masked_motion_search_indexed(const AV1_COMP *const cpi,
6246 MACROBLOCK *x, int wedge_index,
6247 int wedge_sign, BLOCK_SIZE bsize,
6248 int mi_row, int mi_col,
6249 int_mv *tmp_mv, int *rate_mv,
6250 int mv_idx[2], int which) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006251 // NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both
6252 MACROBLOCKD *xd = &x->e_mbd;
6253 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6254 BLOCK_SIZE sb_type = mbmi->sb_type;
6255 const uint8_t *mask;
6256 const int mask_stride = 4 * num_4x4_blocks_wide_lookup[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07006257 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006258
6259 if (which == 0 || which == 2)
6260 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
6261 &tmp_mv[0], &rate_mv[0], 0, mv_idx[0]);
6262
6263 if (which == 1 || which == 2) {
6264 // get the negative mask
Yaowu Xuf883b422016-08-30 14:01:10 -07006265 mask = av1_get_contiguous_soft_mask(wedge_index, !wedge_sign, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006266 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
6267 &tmp_mv[1], &rate_mv[1], 1, mv_idx[1]);
6268 }
6269}
6270#endif // CONFIG_EXT_INTER
6271
6272// In some situations we want to discount tha pparent cost of a new motion
6273// vector. Where there is a subtle motion field and especially where there is
6274// low spatial complexity then it can be hard to cover the cost of a new motion
6275// vector in a single block, even if that motion vector reduces distortion.
6276// However, once established that vector may be usable through the nearest and
6277// near mv modes to reduce distortion in subsequent blocks and also improve
6278// visual quality.
Urvang Joshi52648442016-10-13 17:27:51 -07006279static int discount_newmv_test(const AV1_COMP *const cpi, int this_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006280 int_mv this_mv,
6281 int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME],
6282 int ref_frame) {
6283 return (!cpi->rc.is_src_frame_alt_ref && (this_mode == NEWMV) &&
6284 (this_mv.as_int != 0) &&
6285 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
6286 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
6287 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
6288 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
6289}
6290
Yaowu Xu671f2bd2016-09-30 15:07:57 -07006291#define LEFT_TOP_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
6292#define RIGHT_BOTTOM_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006293
6294// TODO(jingning): this mv clamping function should be block size dependent.
6295static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
6296 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
6297 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
6298 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
6299 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
6300}
6301
6302#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006303static int estimate_wedge_sign(const AV1_COMP *cpi, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006304 const BLOCK_SIZE bsize, const uint8_t *pred0,
6305 int stride0, const uint8_t *pred1, int stride1) {
6306 const struct macroblock_plane *const p = &x->plane[0];
6307 const uint8_t *src = p->src.buf;
6308 int src_stride = p->src.stride;
6309 const int f_index = bsize - BLOCK_8X8;
6310 const int bw = 4 << (b_width_log2_lookup[bsize]);
6311 const int bh = 4 << (b_height_log2_lookup[bsize]);
6312 uint32_t esq[2][4], var;
6313 int64_t tl, br;
6314
Yaowu Xuf883b422016-08-30 14:01:10 -07006315#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006316 if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6317 pred0 = CONVERT_TO_BYTEPTR(pred0);
6318 pred1 = CONVERT_TO_BYTEPTR(pred1);
6319 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006320#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006321
6322 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred0, stride0, &esq[0][0]);
6323 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred0 + bw / 2,
6324 stride0, &esq[0][1]);
6325 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
6326 pred0 + bh / 2 * stride0, stride0, &esq[0][2]);
6327 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
6328 pred0 + bh / 2 * stride0 + bw / 2, stride0,
6329 &esq[0][3]);
6330 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred1, stride1, &esq[1][0]);
6331 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred1 + bw / 2,
6332 stride1, &esq[1][1]);
6333 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
6334 pred1 + bh / 2 * stride1, stride0, &esq[1][2]);
6335 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
6336 pred1 + bh / 2 * stride1 + bw / 2, stride0,
6337 &esq[1][3]);
6338 (void)var;
6339
6340 tl = (int64_t)(esq[0][0] + esq[0][1] + esq[0][2]) -
6341 (int64_t)(esq[1][0] + esq[1][1] + esq[1][2]);
6342 br = (int64_t)(esq[1][3] + esq[1][1] + esq[1][2]) -
6343 (int64_t)(esq[0][3] + esq[0][1] + esq[0][2]);
6344 return (tl + br > 0);
6345}
6346#endif // CONFIG_EXT_INTER
6347
6348#if !CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07006349static InterpFilter predict_interp_filter(
Yaowu Xuf883b422016-08-30 14:01:10 -07006350 const AV1_COMP *cpi, const MACROBLOCK *x, const BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006351 const int mi_row, const int mi_col,
James Zern7b9407a2016-05-18 23:48:05 -07006352 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME]) {
6353 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuf883b422016-08-30 14:01:10 -07006354 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006355 const MACROBLOCKD *xd = &x->e_mbd;
6356 int bsl = mi_width_log2_lookup[bsize];
6357 int pred_filter_search =
6358 cpi->sf.cb_pred_filter_search
6359 ? (((mi_row + mi_col) >> bsl) +
6360 get_chessboard_index(cm->current_video_frame)) &
6361 0x1
6362 : 0;
6363 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6364 const int is_comp_pred = has_second_ref(mbmi);
6365 const int this_mode = mbmi->mode;
6366 int refs[2] = { mbmi->ref_frame[0],
6367 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Yaowu Xuc27fc142016-08-22 16:08:15 -07006368 if (pred_filter_search) {
James Zern7b9407a2016-05-18 23:48:05 -07006369 InterpFilter af = SWITCHABLE, lf = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006370 if (xd->up_available) af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
6371 if (xd->left_available) lf = xd->mi[-1]->mbmi.interp_filter;
6372
6373#if CONFIG_EXT_INTER
6374 if ((this_mode != NEWMV && this_mode != NEWFROMNEARMV &&
6375 this_mode != NEW_NEWMV) ||
6376 (af == lf))
6377#else
6378 if ((this_mode != NEWMV) || (af == lf))
6379#endif // CONFIG_EXT_INTER
6380 best_filter = af;
6381 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006382 if (is_comp_pred) {
6383 if (cpi->sf.adaptive_mode_search) {
6384#if CONFIG_EXT_INTER
6385 switch (this_mode) {
6386 case NEAREST_NEARESTMV:
6387 if (single_filter[NEARESTMV][refs[0]] ==
6388 single_filter[NEARESTMV][refs[1]])
6389 best_filter = single_filter[NEARESTMV][refs[0]];
6390 break;
6391 case NEAREST_NEARMV:
6392 if (single_filter[NEARESTMV][refs[0]] ==
6393 single_filter[NEARMV][refs[1]])
6394 best_filter = single_filter[NEARESTMV][refs[0]];
6395 break;
6396 case NEAR_NEARESTMV:
6397 if (single_filter[NEARMV][refs[0]] ==
6398 single_filter[NEARESTMV][refs[1]])
6399 best_filter = single_filter[NEARMV][refs[0]];
6400 break;
6401 case NEAR_NEARMV:
6402 if (single_filter[NEARMV][refs[0]] == single_filter[NEARMV][refs[1]])
6403 best_filter = single_filter[NEARMV][refs[0]];
6404 break;
6405 case ZERO_ZEROMV:
6406 if (single_filter[ZEROMV][refs[0]] == single_filter[ZEROMV][refs[1]])
6407 best_filter = single_filter[ZEROMV][refs[0]];
6408 break;
6409 case NEW_NEWMV:
6410 if (single_filter[NEWMV][refs[0]] == single_filter[NEWMV][refs[1]])
6411 best_filter = single_filter[NEWMV][refs[0]];
6412 break;
6413 case NEAREST_NEWMV:
6414 if (single_filter[NEARESTMV][refs[0]] ==
6415 single_filter[NEWMV][refs[1]])
6416 best_filter = single_filter[NEARESTMV][refs[0]];
6417 break;
6418 case NEAR_NEWMV:
6419 if (single_filter[NEARMV][refs[0]] == single_filter[NEWMV][refs[1]])
6420 best_filter = single_filter[NEARMV][refs[0]];
6421 break;
6422 case NEW_NEARESTMV:
6423 if (single_filter[NEWMV][refs[0]] ==
6424 single_filter[NEARESTMV][refs[1]])
6425 best_filter = single_filter[NEWMV][refs[0]];
6426 break;
6427 case NEW_NEARMV:
6428 if (single_filter[NEWMV][refs[0]] == single_filter[NEARMV][refs[1]])
6429 best_filter = single_filter[NEWMV][refs[0]];
6430 break;
6431 default:
6432 if (single_filter[this_mode][refs[0]] ==
6433 single_filter[this_mode][refs[1]])
6434 best_filter = single_filter[this_mode][refs[0]];
6435 break;
6436 }
6437#else
6438 if (single_filter[this_mode][refs[0]] ==
6439 single_filter[this_mode][refs[1]])
6440 best_filter = single_filter[this_mode][refs[0]];
6441#endif // CONFIG_EXT_INTER
6442 }
6443 }
Angie Chiang75c22092016-10-25 12:19:16 -07006444 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
6445 best_filter = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006446 }
6447 return best_filter;
6448}
6449#endif
6450
6451#if CONFIG_EXT_INTER
6452// Choose the best wedge index and sign
Yaowu Xuf883b422016-08-30 14:01:10 -07006453static int64_t pick_wedge(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006454 const BLOCK_SIZE bsize, const uint8_t *const p0,
6455 const uint8_t *const p1, int *const best_wedge_sign,
6456 int *const best_wedge_index) {
6457 const MACROBLOCKD *const xd = &x->e_mbd;
6458 const struct buf_2d *const src = &x->plane[0].src;
6459 const int bw = 4 * num_4x4_blocks_wide_lookup[bsize];
6460 const int bh = 4 * num_4x4_blocks_high_lookup[bsize];
6461 const int N = bw * bh;
6462 int rate;
6463 int64_t dist;
6464 int64_t rd, best_rd = INT64_MAX;
6465 int wedge_index;
6466 int wedge_sign;
6467 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
6468 const uint8_t *mask;
6469 uint64_t sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006470#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006471 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
6472 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
6473#else
6474 const int bd_round = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07006475#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006476
6477 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
6478 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
6479 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
6480 DECLARE_ALIGNED(32, int16_t, ds[MAX_SB_SQUARE]);
6481
6482 int64_t sign_limit;
6483
Yaowu Xuf883b422016-08-30 14:01:10 -07006484#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006485 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006486 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006487 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006488 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006489 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006490 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006491 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
6492 } else // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07006493#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006494 {
Yaowu Xuf883b422016-08-30 14:01:10 -07006495 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
6496 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
6497 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006498 }
6499
Yaowu Xuf883b422016-08-30 14:01:10 -07006500 sign_limit = ((int64_t)aom_sum_squares_i16(r0, N) -
6501 (int64_t)aom_sum_squares_i16(r1, N)) *
Yaowu Xuc27fc142016-08-22 16:08:15 -07006502 (1 << WEDGE_WEIGHT_BITS) / 2;
6503
Yaowu Xuf883b422016-08-30 14:01:10 -07006504 av1_wedge_compute_delta_squares(ds, r0, r1, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006505
6506 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006507 mask = av1_get_contiguous_soft_mask(wedge_index, 0, bsize);
6508 wedge_sign = av1_wedge_sign_from_residuals(ds, mask, N, sign_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006509
Yaowu Xuf883b422016-08-30 14:01:10 -07006510 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
6511 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006512 sse = ROUND_POWER_OF_TWO(sse, bd_round);
6513
6514 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
6515 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
6516
6517 if (rd < best_rd) {
6518 *best_wedge_index = wedge_index;
6519 *best_wedge_sign = wedge_sign;
6520 best_rd = rd;
6521 }
6522 }
6523
6524 return best_rd;
6525}
6526
6527// Choose the best wedge index the specified sign
6528static int64_t pick_wedge_fixed_sign(
Yaowu Xuf883b422016-08-30 14:01:10 -07006529 const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006530 const BLOCK_SIZE bsize, const uint8_t *const p0, const uint8_t *const p1,
6531 const int wedge_sign, int *const best_wedge_index) {
6532 const MACROBLOCKD *const xd = &x->e_mbd;
6533 const struct buf_2d *const src = &x->plane[0].src;
6534 const int bw = 4 * num_4x4_blocks_wide_lookup[bsize];
6535 const int bh = 4 * num_4x4_blocks_high_lookup[bsize];
6536 const int N = bw * bh;
6537 int rate;
6538 int64_t dist;
6539 int64_t rd, best_rd = INT64_MAX;
6540 int wedge_index;
6541 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
6542 const uint8_t *mask;
6543 uint64_t sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006544#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006545 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
6546 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
6547#else
6548 const int bd_round = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07006549#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006550
6551 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
6552 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
6553
Yaowu Xuf883b422016-08-30 14:01:10 -07006554#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006555 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006556 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006557 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006558 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006559 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
6560 } else // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07006561#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006562 {
Yaowu Xuf883b422016-08-30 14:01:10 -07006563 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
6564 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006565 }
6566
6567 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006568 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
6569 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006570 sse = ROUND_POWER_OF_TWO(sse, bd_round);
6571
6572 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
6573 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
6574
6575 if (rd < best_rd) {
6576 *best_wedge_index = wedge_index;
6577 best_rd = rd;
6578 }
6579 }
6580
6581 return best_rd;
6582}
6583
Yaowu Xuf883b422016-08-30 14:01:10 -07006584static int64_t pick_interinter_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006585 const MACROBLOCK *const x,
6586 const BLOCK_SIZE bsize,
6587 const uint8_t *const p0,
6588 const uint8_t *const p1) {
6589 const MACROBLOCKD *const xd = &x->e_mbd;
6590 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6591 const int bw = 4 * num_4x4_blocks_wide_lookup[bsize];
6592
6593 int64_t rd;
6594 int wedge_index = -1;
6595 int wedge_sign = 0;
6596
6597 assert(is_interinter_wedge_used(bsize));
6598
6599 if (cpi->sf.fast_wedge_sign_estimate) {
6600 wedge_sign = estimate_wedge_sign(cpi, x, bsize, p0, bw, p1, bw);
6601 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, wedge_sign, &wedge_index);
6602 } else {
6603 rd = pick_wedge(cpi, x, bsize, p0, p1, &wedge_sign, &wedge_index);
6604 }
6605
6606 mbmi->interinter_wedge_sign = wedge_sign;
6607 mbmi->interinter_wedge_index = wedge_index;
6608 return rd;
6609}
6610
Yaowu Xuf883b422016-08-30 14:01:10 -07006611static int64_t pick_interintra_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006612 const MACROBLOCK *const x,
6613 const BLOCK_SIZE bsize,
6614 const uint8_t *const p0,
6615 const uint8_t *const p1) {
6616 const MACROBLOCKD *const xd = &x->e_mbd;
6617 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6618
6619 int64_t rd;
6620 int wedge_index = -1;
6621
6622 assert(is_interintra_wedge_used(bsize));
6623
6624 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, 0, &wedge_index);
6625
6626 mbmi->interintra_wedge_sign = 0;
6627 mbmi->interintra_wedge_index = wedge_index;
6628 return rd;
6629}
6630#endif // CONFIG_EXT_INTER
6631
6632static int64_t handle_inter_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07006633 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int *rate2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006634 int64_t *distortion, int *skippable, int *rate_y, int *rate_uv,
6635 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
6636 int mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07006637#if CONFIG_MOTION_VAR
Yue Chene9638cc2016-10-10 12:37:54 -07006638 uint8_t *above_pred_buf[3], int above_pred_stride[3],
6639 uint8_t *left_pred_buf[3], int left_pred_stride[3],
Yue Chencb60b182016-10-13 15:18:22 -07006640#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006641#if CONFIG_EXT_INTER
6642 int_mv single_newmvs[2][TOTAL_REFS_PER_FRAME],
6643 int single_newmvs_rate[2][TOTAL_REFS_PER_FRAME],
6644 int *compmode_interintra_cost, int *compmode_wedge_cost,
6645 int64_t (*const modelled_rd)[TOTAL_REFS_PER_FRAME],
6646#else
6647 int_mv single_newmv[TOTAL_REFS_PER_FRAME],
6648#endif // CONFIG_EXT_INTER
James Zern7b9407a2016-05-18 23:48:05 -07006649 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006650 int (*single_skippable)[TOTAL_REFS_PER_FRAME], int64_t *psse,
6651 const int64_t ref_best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07006652 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006653 MACROBLOCKD *xd = &x->e_mbd;
6654 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6655 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6656 const int is_comp_pred = has_second_ref(mbmi);
6657 const int this_mode = mbmi->mode;
6658 int_mv *frame_mv = mode_mv[this_mode];
6659 int i;
6660 int refs[2] = { mbmi->ref_frame[0],
6661 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
6662 int_mv cur_mv[2];
6663 int rate_mv = 0;
6664#if CONFIG_EXT_INTER
Angie Chiang75c22092016-10-25 12:19:16 -07006665 int pred_exists = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006666 const int bw = 4 * num_4x4_blocks_wide_lookup[bsize];
6667 int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
6668 int_mv single_newmv[TOTAL_REFS_PER_FRAME];
6669 const unsigned int *const interintra_mode_cost =
6670 cpi->interintra_mode_cost[size_group_lookup[bsize]];
6671 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
6672#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07006673 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006674#endif
6675#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006676#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006677 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
6678#else
6679 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07006680#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006681 uint8_t *tmp_buf;
6682
Yue Chencb60b182016-10-13 15:18:22 -07006683#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07006684 int allow_motvar =
6685#if CONFIG_EXT_INTER
6686 !is_comp_interintra_pred &&
6687#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07006688 is_motion_variation_allowed(mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006689 int rate2_nocoeff = 0, best_rate2 = INT_MAX, best_skippable, best_xskip,
6690 best_disable_skip = 0;
6691 int best_rate_y, best_rate_uv;
6692#if CONFIG_VAR_TX
6693 uint8_t best_blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
6694#endif // CONFIG_VAR_TX
6695 int64_t best_distortion = INT64_MAX;
Angie Chiang75c22092016-10-25 12:19:16 -07006696 int64_t best_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006697 MB_MODE_INFO best_mbmi;
6698#if CONFIG_EXT_INTER
6699 int rate2_bmc_nocoeff;
6700 int rate_mv_bmc;
6701 MB_MODE_INFO best_bmc_mbmi;
6702#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07006703#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang75c22092016-10-25 12:19:16 -07006704 int64_t rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006705 uint8_t *orig_dst[MAX_MB_PLANE];
6706 int orig_dst_stride[MAX_MB_PLANE];
Angie Chiang75c22092016-10-25 12:19:16 -07006707 uint8_t *tmp_dst[MAX_MB_PLANE];
6708 int tmp_dst_stride[MAX_MB_PLANE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006709 int rs = 0;
Angie Chiang75c22092016-10-25 12:19:16 -07006710 InterpFilter assign_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006711
6712 int skip_txfm_sb = 0;
6713 int64_t skip_sse_sb = INT64_MAX;
6714 int64_t distortion_y = 0, distortion_uv = 0;
6715 int16_t mode_ctx = mbmi_ext->mode_context[refs[0]];
6716
6717#if CONFIG_EXT_INTER
6718 *compmode_interintra_cost = 0;
6719 mbmi->use_wedge_interintra = 0;
6720 *compmode_wedge_cost = 0;
6721 mbmi->use_wedge_interinter = 0;
6722
6723 // is_comp_interintra_pred implies !is_comp_pred
6724 assert(!is_comp_interintra_pred || (!is_comp_pred));
6725 // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
6726 assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
6727#endif // CONFIG_EXT_INTER
6728
6729#if CONFIG_REF_MV
6730#if CONFIG_EXT_INTER
6731 if (is_comp_pred)
6732 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
6733 else
6734#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006735 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
6736 mbmi->ref_frame, bsize, -1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006737#endif
6738
Yaowu Xuf883b422016-08-30 14:01:10 -07006739#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006740 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
6741 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf_);
6742 else
Yaowu Xuf883b422016-08-30 14:01:10 -07006743#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006744 tmp_buf = tmp_buf_;
6745
6746 if (is_comp_pred) {
6747 if (frame_mv[refs[0]].as_int == INVALID_MV ||
6748 frame_mv[refs[1]].as_int == INVALID_MV)
6749 return INT64_MAX;
6750 }
6751
Yue Chene9638cc2016-10-10 12:37:54 -07006752 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006753 if (have_newmv_in_inter_mode(this_mode)) {
6754 if (is_comp_pred) {
6755#if CONFIG_EXT_INTER
6756 for (i = 0; i < 2; ++i) {
6757 single_newmv[refs[i]].as_int = single_newmvs[mv_idx][refs[i]].as_int;
6758 }
6759
6760 if (this_mode == NEW_NEWMV) {
6761 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
6762 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
6763
6764 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
6765 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, NULL,
6766 single_newmv, &rate_mv, 0);
6767 } else {
6768#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006769 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006770#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07006771 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
6772 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
6773 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006774#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006775 av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006776#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07006777 rate_mv += av1_mv_bit_cost(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006778 &frame_mv[refs[1]].as_mv, &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
6779 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
6780 }
6781 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
6782 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07006783 rate_mv = av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
6784 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
6785 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006786 } else {
6787 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07006788 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
6789 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
6790 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006791 }
6792#else
6793 // Initialize mv using single prediction mode result.
6794 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
6795 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
6796
6797 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
6798 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col,
6799 single_newmv, &rate_mv, 0);
6800 } else {
6801#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006802 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006803#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07006804 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
6805 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
6806 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006807#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006808 av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006809#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07006810 rate_mv += av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
6811 &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
6812 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006813 }
6814#endif // CONFIG_EXT_INTER
6815 } else {
6816#if CONFIG_EXT_INTER
6817 if (is_comp_interintra_pred) {
6818 x->best_mv = single_newmvs[mv_idx][refs[0]];
6819 rate_mv = single_newmvs_rate[mv_idx][refs[0]];
6820 } else {
6821 single_motion_search(cpi, x, bsize, mi_row, mi_col, 0, mv_idx,
6822 &rate_mv);
6823 single_newmvs[mv_idx][refs[0]] = x->best_mv;
6824 single_newmvs_rate[mv_idx][refs[0]] = rate_mv;
6825 }
6826#else
6827 single_motion_search(cpi, x, bsize, mi_row, mi_col, &rate_mv);
6828 single_newmv[refs[0]] = x->best_mv;
6829#endif // CONFIG_EXT_INTER
6830
6831 if (x->best_mv.as_int == INVALID_MV) return INT64_MAX;
6832
6833 frame_mv[refs[0]] = x->best_mv;
6834 xd->mi[0]->bmi[0].as_mv[0] = x->best_mv;
6835
6836 // Estimate the rate implications of a new mv but discount this
6837 // under certain circumstances where we want to help initiate a weak
6838 // motion field, where the distortion gain for a single block may not
6839 // be enough to overcome the cost of a new mv.
6840 if (discount_newmv_test(cpi, this_mode, x->best_mv, mode_mv, refs[0])) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006841 rate_mv = AOMMAX((rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006842 }
6843 }
6844 *rate2 += rate_mv;
6845 }
6846
6847 for (i = 0; i < is_comp_pred + 1; ++i) {
6848 cur_mv[i] = frame_mv[refs[i]];
6849// Clip "next_nearest" so that it does not extend to far out of image
6850#if CONFIG_EXT_INTER
6851 if (this_mode != NEWMV && this_mode != NEWFROMNEARMV)
6852#else
6853 if (this_mode != NEWMV)
6854#endif // CONFIG_EXT_INTER
6855 clamp_mv2(&cur_mv[i].as_mv, xd);
6856
6857 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
6858 mbmi->mv[i].as_int = cur_mv[i].as_int;
6859 }
6860
6861#if CONFIG_REF_MV
6862#if CONFIG_EXT_INTER
6863 if (this_mode == NEAREST_NEARESTMV) {
6864#else
6865 if (this_mode == NEARESTMV && is_comp_pred) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006866 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006867#endif // CONFIG_EXT_INTER
6868 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
6869 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
6870 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
6871
6872 for (i = 0; i < 2; ++i) {
6873 clamp_mv2(&cur_mv[i].as_mv, xd);
6874 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
6875 mbmi->mv[i].as_int = cur_mv[i].as_int;
6876 }
6877 }
6878 }
6879
6880#if CONFIG_EXT_INTER
6881 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
6882 if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
6883 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
6884
6885 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
6886 clamp_mv2(&cur_mv[0].as_mv, xd);
6887 if (mv_check_bounds(x, &cur_mv[0].as_mv)) return INT64_MAX;
6888 mbmi->mv[0].as_int = cur_mv[0].as_int;
6889 }
6890
6891 if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
6892 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
6893
6894 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
6895 clamp_mv2(&cur_mv[1].as_mv, xd);
6896 if (mv_check_bounds(x, &cur_mv[1].as_mv)) return INT64_MAX;
6897 mbmi->mv[1].as_int = cur_mv[1].as_int;
6898 }
6899 }
6900
6901 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
6902 if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV ||
6903 this_mode == NEAR_NEARMV) {
6904 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][1].this_mv;
6905
6906 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
6907 clamp_mv2(&cur_mv[0].as_mv, xd);
6908 if (mv_check_bounds(x, &cur_mv[0].as_mv)) return INT64_MAX;
6909 mbmi->mv[0].as_int = cur_mv[0].as_int;
6910 }
6911
6912 if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV ||
6913 this_mode == NEAR_NEARMV) {
6914 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][1].comp_mv;
6915
6916 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
6917 clamp_mv2(&cur_mv[1].as_mv, xd);
6918 if (mv_check_bounds(x, &cur_mv[1].as_mv)) return INT64_MAX;
6919 mbmi->mv[1].as_int = cur_mv[1].as_int;
6920 }
6921 }
6922#else
6923 if (this_mode == NEARMV && is_comp_pred) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006924 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006925 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
6926 int ref_mv_idx = mbmi->ref_mv_idx + 1;
6927 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
6928 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
6929
6930 for (i = 0; i < 2; ++i) {
6931 clamp_mv2(&cur_mv[i].as_mv, xd);
6932 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
6933 mbmi->mv[i].as_int = cur_mv[i].as_int;
6934 }
6935 }
6936 }
6937#endif // CONFIG_EXT_INTER
6938#endif // CONFIG_REF_MV
6939
6940 // do first prediction into the destination buffer. Do the next
6941 // prediction into a temporary buffer. Then keep track of which one
6942 // of these currently holds the best predictor, and use the other
6943 // one for future predictions. In the end, copy from tmp_buf to
6944 // dst if necessary.
6945 for (i = 0; i < MAX_MB_PLANE; i++) {
Angie Chiang75c22092016-10-25 12:19:16 -07006946 tmp_dst[i] = tmp_buf + i * MAX_SB_SQUARE;
6947 tmp_dst_stride[i] = MAX_SB_SIZE;
6948 }
6949 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006950 orig_dst[i] = xd->plane[i].dst.buf;
6951 orig_dst_stride[i] = xd->plane[i].dst.stride;
6952 }
6953
6954 // We don't include the cost of the second reference here, because there
6955 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
6956 // words if you present them in that order, the second one is always known
6957 // if the first is known.
6958 //
6959 // Under some circumstances we discount the cost of new mv mode to encourage
6960 // initiation of a motion field.
6961 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]], mode_mv,
6962 refs[0])) {
6963#if CONFIG_REF_MV && CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006964 *rate2 += AOMMIN(cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx),
Yaowu Xuc27fc142016-08-22 16:08:15 -07006965 cost_mv_ref(cpi, NEARESTMV, is_comp_pred, mode_ctx));
6966#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006967 *rate2 += AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
Yaowu Xuc27fc142016-08-22 16:08:15 -07006968 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
6969#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
6970 } else {
6971#if CONFIG_REF_MV && CONFIG_EXT_INTER
6972 *rate2 += cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx);
6973#else
6974 *rate2 += cost_mv_ref(cpi, this_mode, mode_ctx);
6975#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
6976 }
6977
6978 if (RDCOST(x->rdmult, x->rddiv, *rate2, 0) > ref_best_rd &&
6979#if CONFIG_EXT_INTER
6980 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV
6981#else
6982 mbmi->mode != NEARESTMV
6983#endif // CONFIG_EXT_INTER
6984 )
6985 return INT64_MAX;
6986
Angie Chiang75c22092016-10-25 12:19:16 -07006987 if (cm->interp_filter == SWITCHABLE) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006988#if !CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07006989 assign_filter =
6990 predict_interp_filter(cpi, x, bsize, mi_row, mi_col, single_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006991#endif
Angie Chiang75c22092016-10-25 12:19:16 -07006992#if CONFIG_EXT_INTERP || CONFIG_DUAL_FILTER
6993 if (!av1_is_interp_needed(xd)) assign_filter = EIGHTTAP_REGULAR;
6994#endif
6995 } else {
6996 assign_filter = cm->interp_filter;
6997 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006998
Angie Chiang75c22092016-10-25 12:19:16 -07006999 { // Do interpolation filter search in the parentheses
7000 int tmp_rate;
7001 int64_t tmp_dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007002#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007003 mbmi->interp_filter[0] =
7004 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
7005 mbmi->interp_filter[1] =
7006 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
7007 mbmi->interp_filter[2] =
7008 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
7009 mbmi->interp_filter[3] =
7010 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007011#else
Angie Chiang75c22092016-10-25 12:19:16 -07007012 mbmi->interp_filter =
7013 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007014#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007015 rs = av1_get_switchable_rate(cpi, xd);
7016 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
7017 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7018 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7019 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007020
Angie Chiang75c22092016-10-25 12:19:16 -07007021 if (assign_filter == SWITCHABLE) {
7022 // do interp_filter search
7023 if (av1_is_interp_needed(xd)) {
7024 int best_in_temp = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007025#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007026 InterpFilter best_filter[4];
7027 av1_copy(best_filter, mbmi->interp_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007028#else
Angie Chiang75c22092016-10-25 12:19:16 -07007029 InterpFilter best_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007030#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007031 restore_dst_buf(xd, tmp_dst, tmp_dst_stride);
7032#if CONFIG_DUAL_FILTER
7033 // EIGHTTAP_REGULAR mode is calculated beforehand
7034 for (i = 1; i < SWITCHABLE_FILTERS * SWITCHABLE_FILTERS; ++i)
7035#else
7036 // EIGHTTAP_REGULAR mode is calculated beforehand
7037 for (i = 1; i < SWITCHABLE_FILTERS; ++i)
7038#endif
7039 {
7040 int tmp_skip_sb = 0;
7041 int64_t tmp_skip_sse = INT64_MAX;
7042 int tmp_rs;
Angie Chianga2b56d32016-10-25 17:34:59 -07007043 int tmp_rd;
Angie Chiang75c22092016-10-25 12:19:16 -07007044#if CONFIG_DUAL_FILTER
7045 mbmi->interp_filter[0] = filter_sets[i][0];
7046 mbmi->interp_filter[1] = filter_sets[i][1];
7047 mbmi->interp_filter[2] = filter_sets[i][0];
7048 mbmi->interp_filter[3] = filter_sets[i][1];
7049#else
7050 mbmi->interp_filter = i;
7051#endif
7052 tmp_rs = av1_get_switchable_rate(cpi, xd);
7053 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
7054 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7055 &tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
7056 tmp_rd = RDCOST(x->rdmult, x->rddiv, tmp_rs + tmp_rate, tmp_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007057
Angie Chiang75c22092016-10-25 12:19:16 -07007058 if (tmp_rd < rd) {
7059 rd = tmp_rd;
7060 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007061#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007062 av1_copy(best_filter, mbmi->interp_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007063#else
Angie Chiang75c22092016-10-25 12:19:16 -07007064 best_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007065#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007066 skip_txfm_sb = tmp_skip_sb;
7067 skip_sse_sb = tmp_skip_sse;
7068 best_in_temp = !best_in_temp;
7069 if (best_in_temp) {
7070 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7071 } else {
7072 restore_dst_buf(xd, tmp_dst, tmp_dst_stride);
7073 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007074 }
7075 }
Angie Chiang75c22092016-10-25 12:19:16 -07007076 if (best_in_temp) {
7077 restore_dst_buf(xd, tmp_dst, tmp_dst_stride);
7078 } else {
7079 restore_dst_buf(xd, orig_dst, orig_dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007080 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007081#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007082 av1_copy(mbmi->interp_filter, best_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007083#else
Angie Chiang75c22092016-10-25 12:19:16 -07007084 mbmi->interp_filter = best_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007085#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007086 } else {
Angie Chiang75c22092016-10-25 12:19:16 -07007087#if !CONFIG_EXT_INTERP && !CONFIG_DUAL_FILTER
7088 int tmp_rs;
7089 InterpFilter best_filter = mbmi->interp_filter;
7090 rs = av1_get_switchable_rate(cpi, xd);
7091 for (i = 1; i < SWITCHABLE_FILTERS; ++i) {
7092 mbmi->interp_filter = i;
7093 tmp_rs = av1_get_switchable_rate(cpi, xd);
7094 if (tmp_rs < rs) {
7095 rs = tmp_rs;
7096 best_filter = i;
7097 }
7098 }
7099 mbmi->interp_filter = best_filter;
7100#else
7101 assert(0);
7102#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007103 }
7104 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007105 }
7106
Yaowu Xuc27fc142016-08-22 16:08:15 -07007107#if CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07007108#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007109 best_bmc_mbmi = *mbmi;
7110 rate_mv_bmc = rate_mv;
7111 rate2_bmc_nocoeff = *rate2;
7112 if (cm->interp_filter == SWITCHABLE) rate2_bmc_nocoeff += rs;
Yue Chencb60b182016-10-13 15:18:22 -07007113#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007114
7115 if (is_comp_pred && is_interinter_wedge_used(bsize)) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07007116 int rate_sum, rs2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007117 int64_t dist_sum;
7118 int64_t best_rd_nowedge = INT64_MAX;
7119 int64_t best_rd_wedge = INT64_MAX;
7120 int tmp_skip_txfm_sb;
7121 int64_t tmp_skip_sse_sb;
7122
Urvang Joshi368fbc92016-10-17 16:31:34 -07007123 rs2 = av1_cost_bit(cm->fc->wedge_interinter_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007124 mbmi->use_wedge_interinter = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07007125 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
7126 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007127 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7128 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7129 if (rd != INT64_MAX)
Urvang Joshi368fbc92016-10-17 16:31:34 -07007130 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007131 best_rd_nowedge = rd;
7132
7133 // Disbale wedge search if source variance is small
7134 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
7135 best_rd_nowedge / 3 < ref_best_rd) {
7136 uint8_t pred0[2 * MAX_SB_SQUARE];
7137 uint8_t pred1[2 * MAX_SB_SQUARE];
7138 uint8_t *preds0[1] = { pred0 };
7139 uint8_t *preds1[1] = { pred1 };
7140 int strides[1] = { bw };
7141
7142 mbmi->use_wedge_interinter = 1;
Urvang Joshi368fbc92016-10-17 16:31:34 -07007143 rs2 = av1_cost_literal(get_interinter_wedge_bits(bsize)) +
7144 av1_cost_bit(cm->fc->wedge_interinter_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007145
Yaowu Xuf883b422016-08-30 14:01:10 -07007146 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007147 xd, bsize, 0, 0, mi_row, mi_col, 0, preds0, strides);
Yaowu Xuf883b422016-08-30 14:01:10 -07007148 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007149 xd, bsize, 0, 0, mi_row, mi_col, 1, preds1, strides);
7150
7151 // Choose the best wedge
7152 best_rd_wedge = pick_interinter_wedge(cpi, x, bsize, pred0, pred1);
Urvang Joshi368fbc92016-10-17 16:31:34 -07007153 best_rd_wedge += RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007154
7155 if (have_newmv_in_inter_mode(this_mode)) {
7156 int_mv tmp_mv[2];
7157 int rate_mvs[2], tmp_rate_mv = 0;
7158 if (this_mode == NEW_NEWMV) {
7159 int mv_idxs[2] = { 0, 0 };
7160 do_masked_motion_search_indexed(
7161 cpi, x, mbmi->interinter_wedge_index, mbmi->interinter_wedge_sign,
7162 bsize, mi_row, mi_col, tmp_mv, rate_mvs, mv_idxs, 2);
7163 tmp_rate_mv = rate_mvs[0] + rate_mvs[1];
7164 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7165 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7166 } else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
7167 int mv_idxs[2] = { 0, 0 };
7168 do_masked_motion_search_indexed(
7169 cpi, x, mbmi->interinter_wedge_index, mbmi->interinter_wedge_sign,
7170 bsize, mi_row, mi_col, tmp_mv, rate_mvs, mv_idxs, 0);
7171 tmp_rate_mv = rate_mvs[0];
7172 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7173 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
7174 int mv_idxs[2] = { 0, 0 };
7175 do_masked_motion_search_indexed(
7176 cpi, x, mbmi->interinter_wedge_index, mbmi->interinter_wedge_sign,
7177 bsize, mi_row, mi_col, tmp_mv, rate_mvs, mv_idxs, 1);
7178 tmp_rate_mv = rate_mvs[1];
7179 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7180 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007181 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007182 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7183 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
Urvang Joshi368fbc92016-10-17 16:31:34 -07007184 rd =
7185 RDCOST(x->rdmult, x->rddiv, rs2 + tmp_rate_mv + rate_sum, dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007186 if (rd < best_rd_wedge) {
7187 best_rd_wedge = rd;
7188 } else {
7189 mbmi->mv[0].as_int = cur_mv[0].as_int;
7190 mbmi->mv[1].as_int = cur_mv[1].as_int;
7191 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07007192 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0, preds0,
7193 strides, preds1, strides);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007194 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007195 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 + tmp_rate_mv + rate_sum,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007201 dist_sum);
7202 best_rd_wedge = rd;
7203
7204 if (best_rd_wedge < best_rd_nowedge) {
7205 mbmi->use_wedge_interinter = 1;
7206 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
7207 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
7208 *rate2 += tmp_rate_mv - rate_mv;
7209 rate_mv = tmp_rate_mv;
7210 } else {
7211 mbmi->use_wedge_interinter = 0;
7212 mbmi->mv[0].as_int = cur_mv[0].as_int;
7213 mbmi->mv[1].as_int = cur_mv[1].as_int;
7214 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
7215 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
7216 }
7217 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07007218 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0, preds0,
7219 strides, preds1, strides);
7220 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007221 rd =
7222 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7223 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7224 if (rd != INT64_MAX)
Urvang Joshi368fbc92016-10-17 16:31:34 -07007225 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007226 best_rd_wedge = rd;
7227 if (best_rd_wedge < best_rd_nowedge) {
7228 mbmi->use_wedge_interinter = 1;
7229 } else {
7230 mbmi->use_wedge_interinter = 0;
7231 }
7232 }
7233 }
7234 if (ref_best_rd < INT64_MAX &&
Yaowu Xuf883b422016-08-30 14:01:10 -07007235 AOMMIN(best_rd_wedge, best_rd_nowedge) / 3 > ref_best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007236 return INT64_MAX;
7237
7238 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007239
7240 if (mbmi->use_wedge_interinter)
7241 *compmode_wedge_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07007242 av1_cost_literal(get_interinter_wedge_bits(bsize)) +
7243 av1_cost_bit(cm->fc->wedge_interinter_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007244 else
7245 *compmode_wedge_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07007246 av1_cost_bit(cm->fc->wedge_interinter_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007247 }
7248
7249 if (is_comp_interintra_pred) {
7250 INTERINTRA_MODE best_interintra_mode = II_DC_PRED;
7251 int64_t best_interintra_rd = INT64_MAX;
7252 int rmode, rate_sum;
7253 int64_t dist_sum;
7254 int j;
7255 int64_t best_interintra_rd_nowedge = INT64_MAX;
7256 int64_t best_interintra_rd_wedge = INT64_MAX;
7257 int rwedge;
7258 int_mv tmp_mv;
7259 int tmp_rate_mv = 0;
7260 int tmp_skip_txfm_sb;
7261 int64_t tmp_skip_sse_sb;
7262 DECLARE_ALIGNED(16, uint8_t, intrapred_[2 * MAX_SB_SQUARE]);
7263 uint8_t *intrapred;
7264
Yaowu Xuf883b422016-08-30 14:01:10 -07007265#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007266 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
7267 intrapred = CONVERT_TO_BYTEPTR(intrapred_);
7268 else
Yaowu Xuf883b422016-08-30 14:01:10 -07007269#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007270 intrapred = intrapred_;
7271
7272 mbmi->ref_frame[1] = NONE;
7273 for (j = 0; j < MAX_MB_PLANE; j++) {
7274 xd->plane[j].dst.buf = tmp_buf + j * MAX_SB_SQUARE;
7275 xd->plane[j].dst.stride = bw;
7276 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007277 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007278 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7279 mbmi->ref_frame[1] = INTRA_FRAME;
7280 mbmi->use_wedge_interintra = 0;
7281
7282 for (j = 0; j < INTERINTRA_MODES; ++j) {
7283 mbmi->interintra_mode = (INTERINTRA_MODE)j;
7284 rmode = interintra_mode_cost[mbmi->interintra_mode];
Yaowu Xuf883b422016-08-30 14:01:10 -07007285 av1_build_intra_predictors_for_interintra(xd, bsize, 0, intrapred, bw);
7286 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007287 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7288 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7289 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate_mv + rate_sum, dist_sum);
7290 if (rd < best_interintra_rd) {
7291 best_interintra_rd = rd;
7292 best_interintra_mode = mbmi->interintra_mode;
7293 }
7294 }
7295 mbmi->interintra_mode = best_interintra_mode;
7296 rmode = interintra_mode_cost[mbmi->interintra_mode];
Yaowu Xuf883b422016-08-30 14:01:10 -07007297 av1_build_intra_predictors_for_interintra(xd, bsize, 0, intrapred, bw);
7298 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
7299 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007300 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7301 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7302 if (rd != INT64_MAX)
7303 rd = RDCOST(x->rdmult, x->rddiv, rate_mv + rmode + rate_sum, dist_sum);
7304 best_interintra_rd = rd;
7305
7306 if (ref_best_rd < INT64_MAX && best_interintra_rd > 2 * ref_best_rd) {
7307 return INT64_MAX;
7308 }
7309 if (is_interintra_wedge_used(bsize)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007310 rwedge = av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007311 if (rd != INT64_MAX)
7312 rd = RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge + rate_sum,
7313 dist_sum);
7314 best_interintra_rd_nowedge = rd;
7315
7316 // Disbale wedge search if source variance is small
7317 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh) {
7318 mbmi->use_wedge_interintra = 1;
7319
Yaowu Xuf883b422016-08-30 14:01:10 -07007320 rwedge = av1_cost_literal(get_interintra_wedge_bits(bsize)) +
7321 av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007322
7323 best_interintra_rd_wedge =
7324 pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
7325
7326 best_interintra_rd_wedge +=
7327 RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge, 0);
7328 // Refine motion vector.
7329 if (have_newmv_in_inter_mode(this_mode)) {
7330 // get negative of mask
Yaowu Xuf883b422016-08-30 14:01:10 -07007331 const uint8_t *mask = av1_get_contiguous_soft_mask(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007332 mbmi->interintra_wedge_index, 1, bsize);
7333 do_masked_motion_search(cpi, x, mask, bw, bsize, mi_row, mi_col,
7334 &tmp_mv, &tmp_rate_mv, 0, mv_idx);
7335 mbmi->mv[0].as_int = tmp_mv.as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07007336 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007337 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7338 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7339 rd = RDCOST(x->rdmult, x->rddiv,
7340 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
7341 if (rd < best_interintra_rd_wedge) {
7342 best_interintra_rd_wedge = rd;
7343 } else {
7344 tmp_mv.as_int = cur_mv[0].as_int;
7345 tmp_rate_mv = rate_mv;
7346 }
7347 } else {
7348 tmp_mv.as_int = cur_mv[0].as_int;
7349 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07007350 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007351 }
7352 // Evaluate closer to true rd
Yaowu Xuf883b422016-08-30 14:01:10 -07007353 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007354 rd =
7355 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7356 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7357 if (rd != INT64_MAX)
7358 rd = RDCOST(x->rdmult, x->rddiv,
7359 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
7360 best_interintra_rd_wedge = rd;
7361 if (best_interintra_rd_wedge < best_interintra_rd_nowedge) {
7362 mbmi->use_wedge_interintra = 1;
7363 best_interintra_rd = best_interintra_rd_wedge;
7364 mbmi->mv[0].as_int = tmp_mv.as_int;
7365 *rate2 += tmp_rate_mv - rate_mv;
7366 rate_mv = tmp_rate_mv;
7367 } else {
7368 mbmi->use_wedge_interintra = 0;
7369 best_interintra_rd = best_interintra_rd_nowedge;
7370 mbmi->mv[0].as_int = cur_mv[0].as_int;
7371 }
7372 } else {
7373 mbmi->use_wedge_interintra = 0;
7374 best_interintra_rd = best_interintra_rd_nowedge;
7375 }
7376 }
7377
7378 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007379 *compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07007380 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007381 *compmode_interintra_cost += interintra_mode_cost[mbmi->interintra_mode];
7382 if (is_interintra_wedge_used(bsize)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007383 *compmode_interintra_cost += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007384 cm->fc->wedge_interintra_prob[bsize], mbmi->use_wedge_interintra);
7385 if (mbmi->use_wedge_interintra) {
7386 *compmode_interintra_cost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07007387 av1_cost_literal(get_interintra_wedge_bits(bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007388 }
7389 }
7390 } else if (is_interintra_allowed(mbmi)) {
7391 *compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07007392 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007393 }
7394
7395#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07007396 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007397#if CONFIG_DUAL_FILTER
7398 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = EIGHTTAP_REGULAR;
7399#else
7400 mbmi->interp_filter = EIGHTTAP_REGULAR;
7401#endif
7402 pred_exists = 0;
7403 }
7404#endif // CONFIG_EXT_INTERP
Angie Chiang75c22092016-10-25 12:19:16 -07007405 if (pred_exists == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007406 int tmp_rate;
7407 int64_t tmp_dist;
Yaowu Xuf883b422016-08-30 14:01:10 -07007408 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007409 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7410 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7411 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
7412 }
Angie Chiang75c22092016-10-25 12:19:16 -07007413#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07007414
7415#if CONFIG_DUAL_FILTER
7416 if (!is_comp_pred) single_filter[this_mode][refs[0]] = mbmi->interp_filter[0];
7417#else
7418 if (!is_comp_pred) single_filter[this_mode][refs[0]] = mbmi->interp_filter;
7419#endif
7420
7421#if CONFIG_EXT_INTER
7422 if (modelled_rd != NULL) {
7423 if (is_comp_pred) {
7424 const int mode0 = compound_ref0_mode(this_mode);
7425 const int mode1 = compound_ref1_mode(this_mode);
7426 int64_t mrd =
Yaowu Xuf883b422016-08-30 14:01:10 -07007427 AOMMIN(modelled_rd[mode0][refs[0]], modelled_rd[mode1][refs[1]]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007428 if (rd / 4 * 3 > mrd && ref_best_rd < INT64_MAX) {
7429 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7430 return INT64_MAX;
7431 }
7432 } else if (!is_comp_interintra_pred) {
7433 modelled_rd[this_mode][refs[0]] = rd;
7434 }
7435 }
7436#endif // CONFIG_EXT_INTER
7437
7438 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
7439 // if current pred_error modeled rd is substantially more than the best
7440 // so far, do not bother doing full rd
7441 if (rd / 2 > ref_best_rd) {
7442 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7443 return INT64_MAX;
7444 }
7445 }
7446
7447 if (cm->interp_filter == SWITCHABLE) *rate2 += rs;
Yue Chencb60b182016-10-13 15:18:22 -07007448#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007449 rate2_nocoeff = *rate2;
Yue Chencb60b182016-10-13 15:18:22 -07007450#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007451
Yue Chencb60b182016-10-13 15:18:22 -07007452#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007453 best_rd = INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007454 for (mbmi->motion_mode = SIMPLE_TRANSLATION;
7455 mbmi->motion_mode < (allow_motvar ? MOTION_MODES : 1);
7456 mbmi->motion_mode++) {
Angie Chianga2b56d32016-10-25 17:34:59 -07007457 int64_t tmp_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007458#if CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07007459 int tmp_rate2 = mbmi->motion_mode != SIMPLE_TRANSLATION ? rate2_bmc_nocoeff
7460 : rate2_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007461#else
7462 int tmp_rate2 = rate2_nocoeff;
7463#endif // CONFIG_EXT_INTER
7464#if CONFIG_EXT_INTERP
7465#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07007466 InterpFilter obmc_interp_filter[2][2] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007467 { mbmi->interp_filter[0], mbmi->interp_filter[1] }, // obmc == 0
7468 { mbmi->interp_filter[0], mbmi->interp_filter[1] } // obmc == 1
7469 };
7470#else
James Zern7b9407a2016-05-18 23:48:05 -07007471 InterpFilter obmc_interp_filter[2] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007472 mbmi->interp_filter, // obmc == 0
7473 mbmi->interp_filter // obmc == 1
7474 };
7475#endif // CONFIG_DUAL_FILTER
7476#endif // CONFIG_EXT_INTERP
7477
Yue Chencb60b182016-10-13 15:18:22 -07007478#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007479 int tmp_rate;
7480 int64_t tmp_dist;
Yue Chencb60b182016-10-13 15:18:22 -07007481 if (mbmi->motion_mode == OBMC_CAUSAL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007482#if CONFIG_EXT_INTER
7483 *mbmi = best_bmc_mbmi;
Yue Chencb60b182016-10-13 15:18:22 -07007484 mbmi->motion_mode = OBMC_CAUSAL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007485#endif // CONFIG_EXT_INTER
7486 if (!is_comp_pred && have_newmv_in_inter_mode(this_mode)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007487 int tmp_rate_mv = 0;
7488
Yue Chene9638cc2016-10-10 12:37:54 -07007489 single_motion_search(cpi, x, bsize, mi_row, mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007490#if CONFIG_EXT_INTER
Yue Chene9638cc2016-10-10 12:37:54 -07007491 0, mv_idx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007492#endif // CONFIG_EXT_INTER
Yue Chene9638cc2016-10-10 12:37:54 -07007493 &tmp_rate_mv);
7494 mbmi->mv[0].as_int = x->best_mv.as_int;
7495 if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
7496 refs[0])) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007497 tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007498 }
7499#if CONFIG_EXT_INTER
7500 tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
7501#else
7502 tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
7503#endif // CONFIG_EXT_INTER
7504#if CONFIG_EXT_INTERP
7505#if CONFIG_DUAL_FILTER
7506 if (!has_subpel_mv_component(xd->mi[0], xd, 0))
7507 obmc_interp_filter[1][0] = mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
7508 if (!has_subpel_mv_component(xd->mi[0], xd, 1))
7509 obmc_interp_filter[1][1] = mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
7510#else
Yaowu Xuf883b422016-08-30 14:01:10 -07007511 if (!av1_is_interp_needed(xd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07007512 obmc_interp_filter[1] = mbmi->interp_filter = EIGHTTAP_REGULAR;
7513#endif // CONFIG_DUAL_FILTER
7514 // This is not quite correct with CONFIG_DUAL_FILTER when a filter
7515 // is needed in only one direction
Yaowu Xuf883b422016-08-30 14:01:10 -07007516 if (!av1_is_interp_needed(xd)) tmp_rate2 -= rs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007517#endif // CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07007518 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007519#if CONFIG_EXT_INTER
7520 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07007521 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007522#endif // CONFIG_EXT_INTER
7523 }
Yue Chene9638cc2016-10-10 12:37:54 -07007524 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, above_pred_buf,
7525 above_pred_stride, left_pred_buf,
7526 left_pred_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007527 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7528 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7529 }
Yue Chencb60b182016-10-13 15:18:22 -07007530#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007531
7532#if CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07007533 if (mbmi->motion_mode == WARPED_CAUSAL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007534 // TODO(yuec): Add code
7535 }
7536#endif // CONFIG_WARPED_MOTION
7537 x->skip = 0;
7538
7539 *rate2 = tmp_rate2;
Yue Chencb60b182016-10-13 15:18:22 -07007540 if (allow_motvar) *rate2 += cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007541 *distortion = 0;
Yue Chencb60b182016-10-13 15:18:22 -07007542#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007543 if (!skip_txfm_sb) {
7544 int skippable_y, skippable_uv;
7545 int64_t sseuv = INT64_MAX;
7546 int64_t rdcosty = INT64_MAX;
7547
7548 // Y cost and distortion
Yaowu Xuf883b422016-08-30 14:01:10 -07007549 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007550#if CONFIG_VAR_TX
Jingning Han94d5bfc2016-10-21 10:14:36 -07007551 if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id]) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007552 select_tx_type_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
7553 bsize, ref_best_rd);
7554 } else {
7555 int idx, idy;
7556 super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
7557 bsize, ref_best_rd);
7558 for (idy = 0; idy < xd->n8_h; ++idy)
7559 for (idx = 0; idx < xd->n8_w; ++idx)
7560 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
7561 memset(x->blk_skip[0], skippable_y,
7562 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7563 }
7564#else
7565 super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse, bsize,
7566 ref_best_rd);
7567#endif // CONFIG_VAR_TX
7568
7569 if (*rate_y == INT_MAX) {
7570 *rate2 = INT_MAX;
7571 *distortion = INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007572#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7573 if (mbmi->motion_mode != SIMPLE_TRANSLATION) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007574 continue;
7575 } else {
Yue Chencb60b182016-10-13 15:18:22 -07007576#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007577 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7578 return INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007579#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007580 }
Yue Chencb60b182016-10-13 15:18:22 -07007581#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007582 }
7583
7584 *rate2 += *rate_y;
7585 *distortion += distortion_y;
7586
7587 rdcosty = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
Yaowu Xuf883b422016-08-30 14:01:10 -07007588 rdcosty = AOMMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, *psse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007589
7590#if CONFIG_VAR_TX
7591 if (!inter_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv,
7592 &sseuv, bsize, ref_best_rd - rdcosty))
7593#else
7594 if (!super_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv,
7595 &sseuv, bsize, ref_best_rd - rdcosty))
7596#endif // CONFIG_VAR_TX
7597 {
7598 *rate2 = INT_MAX;
7599 *distortion = INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007600#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007601 continue;
7602#else
7603 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7604 return INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007605#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007606 }
7607
7608 *psse += sseuv;
7609 *rate2 += *rate_uv;
7610 *distortion += distortion_uv;
7611 *skippable = skippable_y && skippable_uv;
Yue Chencb60b182016-10-13 15:18:22 -07007612#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007613 if (*skippable) {
7614 *rate2 -= *rate_uv + *rate_y;
7615 *rate_y = 0;
7616 *rate_uv = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07007617 *rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007618 mbmi->skip = 0;
7619 // here mbmi->skip temporarily plays a role as what this_skip2 does
7620 } else if (!xd->lossless[mbmi->segment_id] &&
7621 (RDCOST(x->rdmult, x->rddiv,
7622 *rate_y + *rate_uv +
Yaowu Xuf883b422016-08-30 14:01:10 -07007623 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Yaowu Xuc27fc142016-08-22 16:08:15 -07007624 *distortion) >=
7625 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007626 av1_cost_bit(av1_get_skip_prob(cm, xd), 1), *psse))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007627 *rate2 -= *rate_uv + *rate_y;
Yaowu Xuf883b422016-08-30 14:01:10 -07007628 *rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007629 *distortion = *psse;
7630 *rate_y = 0;
7631 *rate_uv = 0;
7632 mbmi->skip = 1;
7633 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07007634 *rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007635 mbmi->skip = 0;
7636 }
7637 *disable_skip = 0;
Yue Chencb60b182016-10-13 15:18:22 -07007638#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007639 } else {
7640 x->skip = 1;
7641 *disable_skip = 1;
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07007642 mbmi->tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007643
7644// The cost of skip bit needs to be added.
Yue Chencb60b182016-10-13 15:18:22 -07007645#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007646 mbmi->skip = 0;
Yue Chencb60b182016-10-13 15:18:22 -07007647#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuf883b422016-08-30 14:01:10 -07007648 *rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007649
7650 *distortion = skip_sse_sb;
7651 *psse = skip_sse_sb;
7652 *rate_y = 0;
7653 *rate_uv = 0;
7654 *skippable = 1;
7655 }
Sarah Parkere5299862016-08-16 14:57:37 -07007656#if CONFIG_GLOBAL_MOTION
7657 if (this_mode == ZEROMV) {
7658 *rate2 += GLOBAL_MOTION_RATE(mbmi->ref_frame[0]);
7659 if (is_comp_pred) *rate2 += GLOBAL_MOTION_RATE(mbmi->ref_frame[1]);
7660 }
7661#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007662
Yue Chencb60b182016-10-13 15:18:22 -07007663#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007664 tmp_rd = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
Yue Chencb60b182016-10-13 15:18:22 -07007665 if (mbmi->motion_mode == SIMPLE_TRANSLATION || (tmp_rd < best_rd)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007666#if CONFIG_EXT_INTERP
7667#if CONFIG_DUAL_FILTER
Yue Chencb60b182016-10-13 15:18:22 -07007668 mbmi->interp_filter[0] = obmc_interp_filter[mbmi->motion_mode][0];
7669 mbmi->interp_filter[1] = obmc_interp_filter[mbmi->motion_mode][1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007670#else
Yue Chencb60b182016-10-13 15:18:22 -07007671 mbmi->interp_filter = obmc_interp_filter[mbmi->motion_mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007672#endif // CONFIG_DUAL_FILTER
7673#endif // CONFIG_EXT_INTERP
7674 best_mbmi = *mbmi;
7675 best_rd = tmp_rd;
7676 best_rate2 = *rate2;
7677 best_rate_y = *rate_y;
7678 best_rate_uv = *rate_uv;
7679#if CONFIG_VAR_TX
7680 for (i = 0; i < MAX_MB_PLANE; ++i)
7681 memcpy(best_blk_skip[i], x->blk_skip[i],
7682 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7683#endif // CONFIG_VAR_TX
7684 best_distortion = *distortion;
7685 best_skippable = *skippable;
7686 best_xskip = x->skip;
7687 best_disable_skip = *disable_skip;
Yaowu Xuf883b422016-08-30 14:01:10 -07007688#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007689 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007690 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007691 cpi, &xd->plane[0].dst, bsize, xd->bd);
7692 } else {
7693 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07007694 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007695 }
7696#else
7697 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07007698 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
7699#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007700 }
7701 }
7702
7703 if (best_rd == INT64_MAX) {
7704 *rate2 = INT_MAX;
7705 *distortion = INT64_MAX;
7706 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7707 return INT64_MAX;
7708 }
7709 *mbmi = best_mbmi;
7710 *rate2 = best_rate2;
7711 *rate_y = best_rate_y;
7712 *rate_uv = best_rate_uv;
7713#if CONFIG_VAR_TX
7714 for (i = 0; i < MAX_MB_PLANE; ++i)
7715 memcpy(x->blk_skip[i], best_blk_skip[i],
7716 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7717#endif // CONFIG_VAR_TX
7718 *distortion = best_distortion;
7719 *skippable = best_skippable;
7720 x->skip = best_xskip;
7721 *disable_skip = best_disable_skip;
Yue Chencb60b182016-10-13 15:18:22 -07007722#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007723
7724 if (!is_comp_pred) single_skippable[this_mode][refs[0]] = *skippable;
7725
Yue Chencb60b182016-10-13 15:18:22 -07007726#if !(CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION)
Yaowu Xuf883b422016-08-30 14:01:10 -07007727#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007728 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007729 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007730 cpi, &xd->plane[0].dst, bsize, xd->bd);
7731 } else {
7732 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07007733 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007734 }
7735#else
7736 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07007737 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
7738#endif // CONFIG_AOM_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07007739#endif // !(CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007740
7741 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7742 return 0; // The rate-distortion cost will be re-calculated by caller.
7743}
7744
Urvang Joshi52648442016-10-13 17:27:51 -07007745void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
7746 RD_COST *rd_cost, BLOCK_SIZE bsize,
7747 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
7748 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007749 MACROBLOCKD *const xd = &x->e_mbd;
7750 struct macroblockd_plane *const pd = xd->plane;
7751 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
7752 int y_skip = 0, uv_skip = 0;
7753 int64_t dist_y = 0, dist_uv = 0;
7754 TX_SIZE max_uv_tx_size;
7755 ctx->skip = 0;
7756 xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
7757 xd->mi[0]->mbmi.ref_frame[1] = NONE;
7758
7759 if (bsize >= BLOCK_8X8) {
7760 if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y,
7761 &y_skip, bsize, best_rd) >= best_rd) {
7762 rd_cost->rate = INT_MAX;
7763 return;
7764 }
7765 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007766 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07007767 &dist_y, &y_skip, best_rd) >= best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007768 rd_cost->rate = INT_MAX;
7769 return;
7770 }
7771 }
Debargha Mukherjee2f123402016-08-30 17:43:38 -07007772 max_uv_tx_size = uv_txsize_lookup[bsize][xd->mi[0]->mbmi.tx_size]
7773 [pd[1].subsampling_x][pd[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007774 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007775 &uv_skip, AOMMAX(BLOCK_8X8, bsize), max_uv_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007776
7777 if (y_skip && uv_skip) {
7778 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
Yaowu Xuf883b422016-08-30 14:01:10 -07007779 av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007780 rd_cost->dist = dist_y + dist_uv;
7781 } else {
7782 rd_cost->rate =
Yaowu Xuf883b422016-08-30 14:01:10 -07007783 rate_y + rate_uv + av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007784 rd_cost->dist = dist_y + dist_uv;
7785 }
7786
7787 ctx->mic = *xd->mi[0];
7788 ctx->mbmi_ext = *x->mbmi_ext;
7789 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
7790}
7791
Yaowu Xuc27fc142016-08-22 16:08:15 -07007792// Do we have an internal image edge (e.g. formatting bars).
Urvang Joshi52648442016-10-13 17:27:51 -07007793int av1_internal_image_edge(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007794 return (cpi->oxcf.pass == 2) &&
7795 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
7796 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
7797}
7798
7799// Checks to see if a super block is on a horizontal image edge.
7800// In most cases this is the "real" edge unless there are formatting
7801// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07007802int av1_active_h_edge(const AV1_COMP *cpi, int mi_row, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007803 int top_edge = 0;
7804 int bottom_edge = cpi->common.mi_rows;
7805 int is_active_h_edge = 0;
7806
7807 // For two pass account for any formatting bars detected.
7808 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07007809 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007810
7811 // The inactive region is specified in MBs not mi units.
7812 // The image edge is in the following MB row.
7813 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
7814
7815 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07007816 bottom_edge = AOMMAX(top_edge, bottom_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007817 }
7818
7819 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
7820 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
7821 is_active_h_edge = 1;
7822 }
7823 return is_active_h_edge;
7824}
7825
7826// Checks to see if a super block is on a vertical image edge.
7827// In most cases this is the "real" edge unless there are formatting
7828// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07007829int av1_active_v_edge(const AV1_COMP *cpi, int mi_col, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007830 int left_edge = 0;
7831 int right_edge = cpi->common.mi_cols;
7832 int is_active_v_edge = 0;
7833
7834 // For two pass account for any formatting bars detected.
7835 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07007836 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007837
7838 // The inactive region is specified in MBs not mi units.
7839 // The image edge is in the following MB row.
7840 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
7841
7842 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07007843 right_edge = AOMMAX(left_edge, right_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007844 }
7845
7846 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
7847 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
7848 is_active_v_edge = 1;
7849 }
7850 return is_active_v_edge;
7851}
7852
7853// Checks to see if a super block is at the edge of the active image.
7854// In most cases this is the "real" edge unless there are formatting
7855// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07007856int av1_active_edge_sb(const AV1_COMP *cpi, int mi_row, int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007857 return av1_active_h_edge(cpi, mi_row, cpi->common.mib_size) ||
7858 av1_active_v_edge(cpi, mi_col, cpi->common.mib_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007859}
7860
Urvang Joshib100db72016-10-12 16:28:56 -07007861#if CONFIG_PALETTE
Urvang Joshi52648442016-10-13 17:27:51 -07007862static void restore_uv_color_map(const AV1_COMP *const cpi, MACROBLOCK *x) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007863 MACROBLOCKD *const xd = &x->e_mbd;
7864 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7865 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
7866 const BLOCK_SIZE bsize = mbmi->sb_type;
7867 const int rows =
7868 (4 * num_4x4_blocks_high_lookup[bsize]) >> (xd->plane[1].subsampling_y);
7869 const int cols =
7870 (4 * num_4x4_blocks_wide_lookup[bsize]) >> (xd->plane[1].subsampling_x);
7871 int src_stride = x->plane[1].src.stride;
7872 const uint8_t *const src_u = x->plane[1].src.buf;
7873 const uint8_t *const src_v = x->plane[2].src.buf;
7874 float *const data = x->palette_buffer->kmeans_data_buf;
7875 float centroids[2 * PALETTE_MAX_SIZE];
7876 uint8_t *const color_map = xd->plane[1].color_index_map;
7877 int r, c;
Yaowu Xuf883b422016-08-30 14:01:10 -07007878#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007879 const uint16_t *const src_u16 = CONVERT_TO_SHORTPTR(src_u);
7880 const uint16_t *const src_v16 = CONVERT_TO_SHORTPTR(src_v);
Yaowu Xuf883b422016-08-30 14:01:10 -07007881#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007882 (void)cpi;
7883
7884 for (r = 0; r < rows; ++r) {
7885 for (c = 0; c < cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007886#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007887 if (cpi->common.use_highbitdepth) {
7888 data[(r * cols + c) * 2] = src_u16[r * src_stride + c];
7889 data[(r * cols + c) * 2 + 1] = src_v16[r * src_stride + c];
7890 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07007891#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007892 data[(r * cols + c) * 2] = src_u[r * src_stride + c];
7893 data[(r * cols + c) * 2 + 1] = src_v[r * src_stride + c];
Yaowu Xuf883b422016-08-30 14:01:10 -07007894#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007895 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007896#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007897 }
7898 }
7899
7900 for (r = 1; r < 3; ++r) {
7901 for (c = 0; c < pmi->palette_size[1]; ++c) {
7902 centroids[c * 2 + r - 1] = pmi->palette_colors[r * PALETTE_MAX_SIZE + c];
7903 }
7904 }
7905
Yaowu Xuf883b422016-08-30 14:01:10 -07007906 av1_calc_indices(data, centroids, color_map, rows * cols,
7907 pmi->palette_size[1], 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007908}
Urvang Joshib100db72016-10-12 16:28:56 -07007909#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007910
hui su5db97432016-10-14 16:10:14 -07007911#if CONFIG_FILTER_INTRA
7912static void pick_filter_intra_interframe(
7913 const AV1_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
Urvang Joshi52648442016-10-13 17:27:51 -07007914 BLOCK_SIZE bsize, int *rate_uv_intra, int *rate_uv_tokenonly,
7915 int64_t *dist_uv, int *skip_uv, PREDICTION_MODE *mode_uv,
hui su5db97432016-10-14 16:10:14 -07007916 FILTER_INTRA_MODE_INFO *filter_intra_mode_info_uv,
7917#if CONFIG_EXT_INTRA
7918 int8_t *uv_angle_delta,
7919#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07007920#if CONFIG_PALETTE
7921 PALETTE_MODE_INFO *pmi_uv, int palette_ctx,
7922#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007923 int skip_mask, unsigned int *ref_costs_single, int64_t *best_rd,
7924 int64_t *best_intra_rd, PREDICTION_MODE *best_intra_mode,
7925 int *best_mode_index, int *best_skip2, int *best_mode_skippable,
7926#if CONFIG_SUPERTX
7927 int *returnrate_nocoef,
7928#endif // CONFIG_SUPERTX
7929 int64_t *best_pred_rd, MB_MODE_INFO *best_mbmode, RD_COST *rd_cost) {
Urvang Joshi52648442016-10-13 17:27:51 -07007930 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007931 MACROBLOCKD *const xd = &x->e_mbd;
7932 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07007933#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007934 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07007935#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007936 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
7937 int rate2 = 0, rate_y = INT_MAX, skippable = 0, rate_uv, rate_dummy, i;
7938 int dc_mode_index;
7939 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
7940 int64_t distortion2 = 0, distortion_y = 0, this_rd = *best_rd, distortion_uv;
7941 TX_SIZE uv_tx;
7942
7943 for (i = 0; i < MAX_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07007944 if (av1_mode_order[i].mode == DC_PRED &&
7945 av1_mode_order[i].ref_frame[0] == INTRA_FRAME)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007946 break;
7947 dc_mode_index = i;
7948 assert(i < MAX_MODES);
7949
7950 // TODO(huisu): use skip_mask for further speedup.
7951 (void)skip_mask;
7952 mbmi->mode = DC_PRED;
7953 mbmi->uv_mode = DC_PRED;
7954 mbmi->ref_frame[0] = INTRA_FRAME;
7955 mbmi->ref_frame[1] = NONE;
hui su5db97432016-10-14 16:10:14 -07007956 if (!rd_pick_filter_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
7957 &skippable, bsize, intra_mode_cost[mbmi->mode],
7958 &this_rd, 0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007959 return;
hui su5db97432016-10-14 16:10:14 -07007960 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007961 if (rate_y == INT_MAX) return;
7962
Debargha Mukherjee2f123402016-08-30 17:43:38 -07007963 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
7964 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007965 if (rate_uv_intra[uv_tx] == INT_MAX) {
7966 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
7967 &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx],
7968 &skip_uv[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07007969#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007970 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07007971#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07007972 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
7973#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07007974 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui su5db97432016-10-14 16:10:14 -07007975#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07007976 }
7977
7978 rate_uv = rate_uv_tokenonly[uv_tx];
7979 distortion_uv = dist_uv[uv_tx];
7980 skippable = skippable && skip_uv[uv_tx];
7981 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07007982#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007983 if (cm->allow_screen_content_tools) {
7984 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
7985 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
7986 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
7987 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
7988 }
Urvang Joshib100db72016-10-12 16:28:56 -07007989#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07007990#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07007991 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui su5db97432016-10-14 16:10:14 -07007992#endif // CONFIG_EXT_INTRA
7993 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
7994 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
7995 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
7996 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
7997 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007998 }
7999
8000 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
8001 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07008002#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008003 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07008004 rate2 += av1_cost_bit(
8005 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07008006#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008007
8008 if (!xd->lossless[mbmi->segment_id]) {
8009 // super_block_yrd above includes the cost of the tx_size in the
8010 // tokenonly rate, but for intra blocks, tx_size is always coded
8011 // (prediction granularity), so we account for it in the full rate,
8012 // not the tokenonly rate.
clang-format67948d32016-09-07 22:40:40 -07008013 rate_y -= cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
8014 [mbmi->tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008015 }
8016
hui su5db97432016-10-14 16:10:14 -07008017 rate2 += av1_cost_bit(cm->fc->filter_intra_probs[0],
8018 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
8019 rate2 += write_uniform_cost(
8020 FILTER_INTRA_MODES, mbmi->filter_intra_mode_info.filter_intra_mode[0]);
8021#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008022 if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
8023 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
8024 MAX_ANGLE_DELTAS + mbmi->angle_delta[1]);
8025 }
hui su5db97432016-10-14 16:10:14 -07008026#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008027 if (mbmi->mode == DC_PRED) {
hui su5db97432016-10-14 16:10:14 -07008028 rate2 +=
8029 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
8030 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
8031 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
8032 rate2 +=
8033 write_uniform_cost(FILTER_INTRA_MODES,
8034 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008035 }
8036 distortion2 = distortion_y + distortion_uv;
Angie Chiangff6d8902016-10-21 11:02:09 -07008037 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07008038#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008039 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008040 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008041 cpi, &xd->plane[0].dst, bsize, xd->bd);
8042 } else {
8043 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008044 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008045 }
8046#else
8047 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008048 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
8049#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008050
8051 rate2 += ref_costs_single[INTRA_FRAME];
8052
8053 if (skippable) {
8054 rate2 -= (rate_y + rate_uv);
8055 rate_y = 0;
8056 rate_uv = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07008057 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008058 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07008059 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008060 }
8061 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008062
8063 if (this_rd < *best_intra_rd) {
8064 *best_intra_rd = this_rd;
8065 *best_intra_mode = mbmi->mode;
8066 }
8067 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07008068 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008069
8070 if (this_rd < *best_rd) {
8071 *best_mode_index = dc_mode_index;
8072 mbmi->mv[0].as_int = 0;
8073 rd_cost->rate = rate2;
8074#if CONFIG_SUPERTX
8075 if (x->skip)
8076 *returnrate_nocoef = rate2;
8077 else
8078 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07008079 *returnrate_nocoef -= av1_cost_bit(av1_get_skip_prob(cm, xd), skippable);
8080 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
8081 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008082#endif // CONFIG_SUPERTX
8083 rd_cost->dist = distortion2;
8084 rd_cost->rdcost = this_rd;
8085 *best_rd = this_rd;
8086 *best_mbmode = *mbmi;
8087 *best_skip2 = 0;
8088 *best_mode_skippable = skippable;
8089 }
8090}
hui su5db97432016-10-14 16:10:14 -07008091#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008092
Yue Chencb60b182016-10-13 15:18:22 -07008093#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008094static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
8095 const MACROBLOCKD *xd, int mi_row,
8096 int mi_col, const uint8_t *above,
8097 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -07008098 int left_stride);
Yue Chencb60b182016-10-13 15:18:22 -07008099#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008100
Urvang Joshi52648442016-10-13 17:27:51 -07008101void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
Yaowu Xuf883b422016-08-30 14:01:10 -07008102 MACROBLOCK *x, int mi_row, int mi_col,
8103 RD_COST *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008104#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07008105 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008106#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07008107 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
8108 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07008109 const AV1_COMMON *const cm = &cpi->common;
8110 const RD_OPT *const rd_opt = &cpi->rd;
8111 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008112 MACROBLOCKD *const xd = &x->e_mbd;
8113 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008114#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008115 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07008116#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008117 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
8118 const struct segmentation *const seg = &cm->seg;
8119 PREDICTION_MODE this_mode;
8120 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
8121 unsigned char segment_id = mbmi->segment_id;
8122 int comp_pred, i, k;
8123 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8124 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
8125#if CONFIG_EXT_INTER
8126 int_mv single_newmvs[2][TOTAL_REFS_PER_FRAME] = { { { 0 } }, { { 0 } } };
8127 int single_newmvs_rate[2][TOTAL_REFS_PER_FRAME] = { { 0 }, { 0 } };
8128 int64_t modelled_rd[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8129#else
8130 int_mv single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
8131#endif // CONFIG_EXT_INTER
James Zern7b9407a2016-05-18 23:48:05 -07008132 InterpFilter single_inter_filter[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008133 int single_skippable[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8134 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
8135 0,
Yaowu Xuf883b422016-08-30 14:01:10 -07008136 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008137#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008138 AOM_LAST2_FLAG,
8139 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008140#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008141 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008142#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008143 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008144#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008145 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07008146 };
8147 int64_t best_rd = best_rd_so_far;
8148 int best_rate_y = INT_MAX, best_rate_uv = INT_MAX;
8149 int64_t best_pred_diff[REFERENCE_MODES];
8150 int64_t best_pred_rd[REFERENCE_MODES];
8151 MB_MODE_INFO best_mbmode;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07008152#if CONFIG_REF_MV
8153 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
8154 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8155#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008156 int best_mode_skippable = 0;
8157 int midx, best_mode_index = -1;
8158 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
8159 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -07008160 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008161 int64_t best_intra_rd = INT64_MAX;
8162 unsigned int best_pred_sse = UINT_MAX;
8163 PREDICTION_MODE best_intra_mode = DC_PRED;
8164 int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES];
Urvang Joshi368fbc92016-10-17 16:31:34 -07008165 int64_t dist_uvs[TX_SIZES];
8166 int skip_uvs[TX_SIZES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008167 PREDICTION_MODE mode_uv[TX_SIZES];
Urvang Joshib100db72016-10-12 16:28:56 -07008168#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008169 PALETTE_MODE_INFO pmi_uv[TX_SIZES];
Urvang Joshib100db72016-10-12 16:28:56 -07008170#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008171#if CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008172 int8_t uv_angle_delta[TX_SIZES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008173 int is_directional_mode, angle_stats_ready = 0;
8174 int rate_overhead, rate_dummy;
8175 uint8_t directional_mode_skip_mask[INTRA_MODES];
8176#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008177#if CONFIG_FILTER_INTRA
8178 int8_t dc_skipped = 1;
8179 FILTER_INTRA_MODE_INFO filter_intra_mode_info_uv[TX_SIZES];
8180#endif // CONFIG_FILTER_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07008181 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008182 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
8183 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
8184 int best_skip2 = 0;
8185 uint8_t ref_frame_skip_mask[2] = { 0 };
8186#if CONFIG_EXT_INTER
8187 uint32_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
8188 MV_REFERENCE_FRAME best_single_inter_ref = LAST_FRAME;
8189 int64_t best_single_inter_rd = INT64_MAX;
8190#else
8191 uint16_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
8192#endif // CONFIG_EXT_INTER
8193 int mode_skip_start = sf->mode_skip_start + 1;
8194 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
8195 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
8196 int64_t mode_threshold[MAX_MODES];
8197 int *mode_map = tile_data->mode_map[bsize];
8198 const int mode_search_skip_flags = sf->mode_search_skip_flags;
8199 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07008200#if CONFIG_PALETTE || CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008201 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
8202 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07008203#endif // CONFIG_PALETTE || CONFIG_EXT_INTRA
8204#if CONFIG_PALETTE
8205 int palette_ctx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008206 const MODE_INFO *above_mi = xd->above_mi;
8207 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshib100db72016-10-12 16:28:56 -07008208#endif // CONFIG_PALETTE
Yue Chencb60b182016-10-13 15:18:22 -07008209#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008210#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008211 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8212 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8213#else
8214 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
8215 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07008216#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008217 DECLARE_ALIGNED(16, int32_t, weighted_src_buf[MAX_SB_SQUARE]);
8218 DECLARE_ALIGNED(16, int32_t, mask2d_buf[MAX_SB_SQUARE]);
8219 uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
8220 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8221 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8222 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8223 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8224 int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8225 int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8226
Yaowu Xuf883b422016-08-30 14:01:10 -07008227#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008228 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
8229 int len = sizeof(uint16_t);
8230 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
8231 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
8232 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_SB_SQUARE * len);
8233 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
8234 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
8235 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_SB_SQUARE * len);
8236 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07008237#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008238 dst_buf1[0] = tmp_buf1;
8239 dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
8240 dst_buf1[2] = tmp_buf1 + 2 * MAX_SB_SQUARE;
8241 dst_buf2[0] = tmp_buf2;
8242 dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
8243 dst_buf2[2] = tmp_buf2 + 2 * MAX_SB_SQUARE;
Yaowu Xuf883b422016-08-30 14:01:10 -07008244#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008245 }
Yaowu Xuf883b422016-08-30 14:01:10 -07008246#endif // CONFIG_AOM_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07008247#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008248
Yaowu Xuf883b422016-08-30 14:01:10 -07008249 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008250
Urvang Joshib100db72016-10-12 16:28:56 -07008251#if CONFIG_PALETTE
8252 av1_zero(pmi_uv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008253 if (cm->allow_screen_content_tools) {
8254 if (above_mi)
8255 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
8256 if (left_mi)
8257 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
8258 }
Urvang Joshib100db72016-10-12 16:28:56 -07008259#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008260
8261#if CONFIG_EXT_INTRA
8262 memset(directional_mode_skip_mask, 0,
8263 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
8264#endif // CONFIG_EXT_INTRA
8265
8266 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
8267 &comp_mode_p);
8268
8269 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
8270 for (i = 0; i < TX_SIZES; i++) rate_uv_intra[i] = INT_MAX;
8271 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
8272 for (i = 0; i < MB_MODE_COUNT; ++i) {
8273 for (k = 0; k < TOTAL_REFS_PER_FRAME; ++k) {
8274 single_inter_filter[i][k] = SWITCHABLE;
8275 single_skippable[i][k] = 0;
8276 }
8277 }
8278
8279 rd_cost->rate = INT_MAX;
8280#if CONFIG_SUPERTX
8281 *returnrate_nocoef = INT_MAX;
8282#endif // CONFIG_SUPERTX
8283
8284 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
8285 x->pred_mv_sad[ref_frame] = INT_MAX;
8286 x->mbmi_ext->mode_context[ref_frame] = 0;
8287#if CONFIG_REF_MV && CONFIG_EXT_INTER
8288 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
8289#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
8290 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
8291 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
8292 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
8293 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
8294 }
8295 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkere5299862016-08-16 14:57:37 -07008296#if CONFIG_GLOBAL_MOTION
8297 frame_mv[ZEROMV][ref_frame].as_int =
8298 cm->global_motion[ref_frame].motion_params.wmmat[0].as_int;
8299#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008300 frame_mv[ZEROMV][ref_frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07008301#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008302#if CONFIG_EXT_INTER
8303 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
8304 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
8305 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
8306#endif // CONFIG_EXT_INTER
8307 }
8308
8309#if CONFIG_REF_MV
8310 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
8311 MODE_INFO *const mi = xd->mi[0];
8312 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
8313 x->mbmi_ext->mode_context[ref_frame] = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07008314 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
8315 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07008316#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008317 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008318#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008319 candidates, mi_row, mi_col, NULL, NULL,
8320 mbmi_ext->mode_context);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008321 }
8322#endif // CONFIG_REF_MV
8323
Yue Chencb60b182016-10-13 15:18:22 -07008324#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008325 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1,
8326 dst_width1, dst_height1, dst_stride1);
8327 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2,
8328 dst_width2, dst_height2, dst_stride2);
8329 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yue Chene9638cc2016-10-10 12:37:54 -07008330 x->mask_buf = mask2d_buf;
8331 x->wsrc_buf = weighted_src_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008332 calc_target_weighted_pred(cm, x, xd, mi_row, mi_col, dst_buf1[0],
Yue Chene9638cc2016-10-10 12:37:54 -07008333 dst_stride1[0], dst_buf2[0], dst_stride2[0]);
Yue Chencb60b182016-10-13 15:18:22 -07008334#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008335
8336 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
8337 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
8338// Skip checking missing references in both single and compound reference
8339// modes. Note that a mode will be skipped iff both reference frames
8340// are masked out.
8341#if CONFIG_EXT_REFS
8342 if (ref_frame == BWDREF_FRAME || ref_frame == ALTREF_FRAME) {
8343 ref_frame_skip_mask[0] |= (1 << ref_frame);
8344 ref_frame_skip_mask[1] |= ((1 << ref_frame) | 0x01);
8345 } else {
8346#endif // CONFIG_EXT_REFS
8347 ref_frame_skip_mask[0] |= (1 << ref_frame);
8348 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8349#if CONFIG_EXT_REFS
8350 }
8351#endif // CONFIG_EXT_REFS
8352 } else {
8353 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
8354 // Skip fixed mv modes for poor references
8355 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
8356 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
8357 break;
8358 }
8359 }
8360 }
8361 // If the segment reference frame feature is enabled....
8362 // then do nothing if the current ref frame is not allowed..
8363 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
8364 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
8365 ref_frame_skip_mask[0] |= (1 << ref_frame);
8366 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8367 }
8368 }
8369
8370 // Disable this drop out case if the ref frame
8371 // segment level feature is enabled for this segment. This is to
8372 // prevent the possibility that we end up unable to pick any mode.
8373 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
8374 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
8375 // unless ARNR filtering is enabled in which case we want
8376 // an unfiltered alternative. We allow near/nearest as well
8377 // because they may result in zero-zero MVs but be cheaper.
8378 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Sarah Parkere5299862016-08-16 14:57:37 -07008379 int_mv zeromv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008380 ref_frame_skip_mask[0] = (1 << LAST_FRAME) |
8381#if CONFIG_EXT_REFS
8382 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
8383 (1 << BWDREF_FRAME) |
8384#endif // CONFIG_EXT_REFS
8385 (1 << GOLDEN_FRAME);
8386 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
8387 // TODO(zoeliu): To further explore whether following needs to be done for
8388 // BWDREF_FRAME as well.
8389 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
Sarah Parkere5299862016-08-16 14:57:37 -07008390#if CONFIG_GLOBAL_MOTION
8391 zeromv.as_int =
8392 cm->global_motion[ALTREF_FRAME].motion_params.wmmat[0].as_int;
8393#else
8394 zeromv.as_int = 0;
8395#endif // CONFIG_GLOBAL_MOTION
8396 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008397 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008398 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008399 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
8400#if CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07008401 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008402 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008403 if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008404 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008405 if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008406 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008407 if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008408 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV);
8409#endif // CONFIG_EXT_INTER
8410 }
8411 }
8412
8413 if (cpi->rc.is_src_frame_alt_ref) {
8414 if (sf->alt_ref_search_fp) {
8415 assert(cpi->ref_frame_flags & flag_list[ALTREF_FRAME]);
8416 mode_skip_mask[ALTREF_FRAME] = 0;
8417 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
8418 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
8419 }
8420 }
8421
8422 if (sf->alt_ref_search_fp)
8423 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
8424 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
8425 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
8426
8427 if (sf->adaptive_mode_search) {
8428 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
8429 cpi->rc.frames_since_golden >= 3)
8430 if (x->pred_mv_sad[GOLDEN_FRAME] > (x->pred_mv_sad[LAST_FRAME] << 1))
8431 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
8432 }
8433
8434 if (bsize > sf->max_intra_bsize) {
8435 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
8436 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
8437 }
8438
8439 mode_skip_mask[INTRA_FRAME] |=
8440 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
8441
8442 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i) mode_threshold[i] = 0;
8443 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
8444 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
8445
8446 midx = sf->schedule_mode_search ? mode_skip_start : 0;
8447 while (midx > 4) {
8448 uint8_t end_pos = 0;
8449 for (i = 5; i < midx; ++i) {
8450 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
8451 uint8_t tmp = mode_map[i];
8452 mode_map[i] = mode_map[i - 1];
8453 mode_map[i - 1] = tmp;
8454 end_pos = i;
8455 }
8456 }
8457 midx = end_pos;
8458 }
8459
8460 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
8461 x->use_default_intra_tx_type = 1;
8462 else
8463 x->use_default_intra_tx_type = 0;
8464
8465 if (cpi->sf.tx_type_search.fast_inter_tx_type_search)
8466 x->use_default_inter_tx_type = 1;
8467 else
8468 x->use_default_inter_tx_type = 0;
8469
8470#if CONFIG_EXT_INTER
8471 for (i = 0; i < MB_MODE_COUNT; ++i)
8472 for (ref_frame = 0; ref_frame < TOTAL_REFS_PER_FRAME; ++ref_frame)
8473 modelled_rd[i][ref_frame] = INT64_MAX;
8474#endif // CONFIG_EXT_INTER
8475
8476 for (midx = 0; midx < MAX_MODES; ++midx) {
8477 int mode_index;
8478 int mode_excluded = 0;
8479 int64_t this_rd = INT64_MAX;
8480 int disable_skip = 0;
8481 int compmode_cost = 0;
8482#if CONFIG_EXT_INTER
8483 int compmode_interintra_cost = 0;
8484 int compmode_wedge_cost = 0;
8485#endif // CONFIG_EXT_INTER
8486 int rate2 = 0, rate_y = 0, rate_uv = 0;
8487 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
8488 int skippable = 0;
8489 int this_skip2 = 0;
8490 int64_t total_sse = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008491#if CONFIG_REF_MV
8492 uint8_t ref_frame_type;
8493#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008494 mode_index = mode_map[midx];
Yaowu Xuf883b422016-08-30 14:01:10 -07008495 this_mode = av1_mode_order[mode_index].mode;
8496 ref_frame = av1_mode_order[mode_index].ref_frame[0];
8497 second_ref_frame = av1_mode_order[mode_index].ref_frame[1];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07008498#if CONFIG_REF_MV
8499 mbmi->ref_mv_idx = 0;
8500#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008501
8502#if CONFIG_EXT_INTER
8503 if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
8504 // Mode must by compatible
8505 assert(is_interintra_allowed_mode(this_mode));
8506
8507 if (!is_interintra_allowed_bsize(bsize)) continue;
8508 }
8509
8510 if (is_inter_compound_mode(this_mode)) {
8511 frame_mv[this_mode][ref_frame].as_int =
8512 frame_mv[compound_ref0_mode(this_mode)][ref_frame].as_int;
8513 frame_mv[this_mode][second_ref_frame].as_int =
8514 frame_mv[compound_ref1_mode(this_mode)][second_ref_frame].as_int;
8515 }
8516#endif // CONFIG_EXT_INTER
8517
8518 // Look at the reference frame of the best mode so far and set the
8519 // skip mask to look at a subset of the remaining modes.
8520 if (midx == mode_skip_start && best_mode_index >= 0) {
8521 switch (best_mbmode.ref_frame[0]) {
8522 case INTRA_FRAME: break;
8523 case LAST_FRAME:
8524 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
8525 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8526 break;
8527#if CONFIG_EXT_REFS
8528 case LAST2_FRAME:
8529 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
8530 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8531 break;
8532 case LAST3_FRAME:
8533 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
8534 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8535 break;
8536#endif // CONFIG_EXT_REFS
8537 case GOLDEN_FRAME:
8538 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
8539 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8540 break;
8541#if CONFIG_EXT_REFS
8542 case BWDREF_FRAME:
8543 ref_frame_skip_mask[0] |= BWDREF_FRAME_MODE_MASK;
8544 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8545 break;
8546#endif // CONFIG_EXT_REFS
8547 case ALTREF_FRAME: ref_frame_skip_mask[0] |= ALTREF_FRAME_MODE_MASK;
8548#if CONFIG_EXT_REFS
8549 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8550#endif // CONFIG_EXT_REFS
8551 break;
8552 case NONE:
8553 case TOTAL_REFS_PER_FRAME:
8554 assert(0 && "Invalid Reference frame");
8555 break;
8556 }
8557 }
8558
8559 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -07008560 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -07008561 continue;
8562
8563 if (mode_skip_mask[ref_frame] & (1 << this_mode)) continue;
8564
8565 // Test best rd so far against threshold for trying this mode.
8566 if (best_mode_skippable && sf->schedule_mode_search)
8567 mode_threshold[mode_index] <<= 1;
8568
8569 if (best_rd < mode_threshold[mode_index]) continue;
8570
8571 comp_pred = second_ref_frame > INTRA_FRAME;
8572 if (comp_pred) {
8573 if (!cpi->allow_comp_inter_inter) continue;
8574
8575 // Skip compound inter modes if ARF is not available.
8576 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
8577
8578 // Do not allow compound prediction if the segment level reference frame
8579 // feature is in use as in this case there can only be one reference.
8580 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
8581
8582 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
8583 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
8584 continue;
8585
8586 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
8587 } else {
8588 if (ref_frame != INTRA_FRAME)
8589 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
8590 }
8591
8592 if (ref_frame == INTRA_FRAME) {
8593 if (sf->adaptive_mode_search)
8594 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
8595 continue;
8596
8597 if (this_mode != DC_PRED) {
8598 // Disable intra modes other than DC_PRED for blocks with low variance
8599 // Threshold for intra skipping based on source variance
8600 // TODO(debargha): Specialize the threshold for super block sizes
8601 const unsigned int skip_intra_var_thresh = 64;
8602 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
8603 x->source_variance < skip_intra_var_thresh)
8604 continue;
8605 // Only search the oblique modes if the best so far is
8606 // one of the neighboring directional modes
8607 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
8608 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
8609 if (best_mode_index >= 0 && best_mbmode.ref_frame[0] > INTRA_FRAME)
8610 continue;
8611 }
8612 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
8613 if (conditional_skipintra(this_mode, best_intra_mode)) continue;
8614 }
8615 }
Sarah Parkere5299862016-08-16 14:57:37 -07008616#if CONFIG_GLOBAL_MOTION
8617 } else if (get_gmtype(&cm->global_motion[ref_frame]) == GLOBAL_ZERO &&
8618 (!comp_pred ||
8619 get_gmtype(&cm->global_motion[second_ref_frame]) ==
8620 GLOBAL_ZERO)) {
8621#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008622 } else {
Sarah Parkere5299862016-08-16 14:57:37 -07008623#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008624 const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame };
8625 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
8626#if CONFIG_REF_MV && CONFIG_EXT_INTER
8627 mbmi_ext->compound_mode_context,
8628#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
8629 frame_mv, this_mode, ref_frames, bsize, -1))
8630 continue;
8631 }
8632
8633 mbmi->mode = this_mode;
8634 mbmi->uv_mode = DC_PRED;
8635 mbmi->ref_frame[0] = ref_frame;
8636 mbmi->ref_frame[1] = second_ref_frame;
Urvang Joshib100db72016-10-12 16:28:56 -07008637#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008638 pmi->palette_size[0] = 0;
8639 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07008640#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07008641#if CONFIG_FILTER_INTRA
8642 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
8643 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
8644#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008645 // Evaluate all sub-pel filters irrespective of whether we can use
8646 // them for this frame.
8647#if CONFIG_DUAL_FILTER
8648 for (i = 0; i < 4; ++i) {
8649 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
8650 ? EIGHTTAP_REGULAR
8651 : cm->interp_filter;
8652 }
8653#else
8654 mbmi->interp_filter =
8655 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
8656#endif
8657 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chencb60b182016-10-13 15:18:22 -07008658 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008659
8660 x->skip = 0;
8661 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
8662
8663 // Select prediction reference frames.
8664 for (i = 0; i < MAX_MB_PLANE; i++) {
8665 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
8666 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
8667 }
8668
8669#if CONFIG_EXT_INTER
Debargha Mukherjeecb603792016-10-04 13:10:23 -07008670 mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008671#endif // CONFIG_EXT_INTER
8672
8673 if (ref_frame == INTRA_FRAME) {
8674 TX_SIZE uv_tx;
8675 struct macroblockd_plane *const pd = &xd->plane[1];
8676#if CONFIG_EXT_INTRA
8677 is_directional_mode = (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED);
8678 if (is_directional_mode) {
8679 if (!angle_stats_ready) {
8680 const int src_stride = x->plane[0].src.stride;
8681 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuf883b422016-08-30 14:01:10 -07008682#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008683 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
8684 highbd_angle_estimation(src, src_stride, rows, cols,
8685 directional_mode_skip_mask);
8686 else
8687#endif
8688 angle_estimation(src, src_stride, rows, cols,
8689 directional_mode_skip_mask);
8690 angle_stats_ready = 1;
8691 }
8692 if (directional_mode_skip_mask[mbmi->mode]) continue;
8693 rate_overhead = write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0) +
8694 intra_mode_cost[mbmi->mode];
8695 rate_y = INT_MAX;
8696 this_rd =
8697 rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
8698 &skippable, bsize, rate_overhead, best_rd);
8699 } else {
8700 mbmi->angle_delta[0] = 0;
8701 super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable, NULL, bsize,
8702 best_rd);
8703 }
8704#else
8705 super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable, NULL, bsize,
8706 best_rd);
8707#endif // CONFIG_EXT_INTRA
8708
8709 if (rate_y == INT_MAX) continue;
8710
hui su5db97432016-10-14 16:10:14 -07008711#if CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008712 if (mbmi->mode == DC_PRED) dc_skipped = 0;
hui su5db97432016-10-14 16:10:14 -07008713#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008714
Debargha Mukherjee2f123402016-08-30 17:43:38 -07008715 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][pd->subsampling_x]
8716 [pd->subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008717 if (rate_uv_intra[uv_tx] == INT_MAX) {
8718 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -07008719 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
8720 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07008721#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008722 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008723#endif // CONFIG_PALETTE
8724
Yaowu Xuc27fc142016-08-22 16:08:15 -07008725#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008726 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
8727#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008728#if CONFIG_FILTER_INTRA
8729 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
8730#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008731 }
8732
8733 rate_uv = rate_uv_tokenonly[uv_tx];
Urvang Joshi368fbc92016-10-17 16:31:34 -07008734 distortion_uv = dist_uvs[uv_tx];
8735 skippable = skippable && skip_uvs[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008736 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07008737#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008738 if (cm->allow_screen_content_tools) {
8739 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
8740 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
8741 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
8742 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
8743 }
Urvang Joshib100db72016-10-12 16:28:56 -07008744#endif // CONFIG_PALETTE
8745
Yaowu Xuc27fc142016-08-22 16:08:15 -07008746#if CONFIG_EXT_INTRA
8747 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008748#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008749#if CONFIG_FILTER_INTRA
8750 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
8751 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
8752 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
8753 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
8754 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
8755 }
8756#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008757
8758 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
8759 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07008760#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008761 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07008762 rate2 += av1_cost_bit(
8763 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07008764#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008765
8766 if (!xd->lossless[mbmi->segment_id]) {
8767 // super_block_yrd above includes the cost of the tx_size in the
8768 // tokenonly rate, but for intra blocks, tx_size is always coded
8769 // (prediction granularity), so we account for it in the full rate,
8770 // not the tokenonly rate.
clang-format67948d32016-09-07 22:40:40 -07008771 rate_y -= cpi->tx_size_cost[max_tx_size - TX_8X8]
8772 [get_tx_size_context(xd)][mbmi->tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008773 }
8774#if CONFIG_EXT_INTRA
8775 if (is_directional_mode) {
8776 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07008777 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008778 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
8779 MAX_ANGLE_DELTAS + mbmi->angle_delta[0]);
8780 p_angle =
8781 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07008782 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07008783 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
8784 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008785 if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
8786 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
8787 MAX_ANGLE_DELTAS + mbmi->angle_delta[1]);
8788 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008789#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008790#if CONFIG_FILTER_INTRA
8791 if (mbmi->mode == DC_PRED) {
8792 rate2 +=
8793 av1_cost_bit(cm->fc->filter_intra_probs[0],
8794 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
8795 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
8796 rate2 += write_uniform_cost(
8797 FILTER_INTRA_MODES,
8798 mbmi->filter_intra_mode_info.filter_intra_mode[0]);
8799 }
8800 }
8801 if (mbmi->uv_mode == DC_PRED) {
8802 rate2 +=
8803 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
8804 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
8805 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
8806 rate2 += write_uniform_cost(
8807 FILTER_INTRA_MODES,
8808 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
8809 }
8810#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008811 if (this_mode != DC_PRED && this_mode != TM_PRED)
8812 rate2 += intra_cost_penalty;
8813 distortion2 = distortion_y + distortion_uv;
Angie Chiangff6d8902016-10-21 11:02:09 -07008814 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 1);
Yaowu Xuf883b422016-08-30 14:01:10 -07008815#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008816 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008817 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008818 cpi, &xd->plane[0].dst, bsize, xd->bd);
8819 } else {
8820 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008821 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008822 }
8823#else
8824 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008825 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
8826#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008827 } else {
8828#if CONFIG_REF_MV
8829 int_mv backup_ref_mv[2];
8830
8831 backup_ref_mv[0] = mbmi_ext->ref_mvs[ref_frame][0];
8832 if (comp_pred) backup_ref_mv[1] = mbmi_ext->ref_mvs[second_ref_frame][0];
8833#endif
8834#if CONFIG_EXT_INTER
8835 if (second_ref_frame == INTRA_FRAME) {
8836 if (best_single_inter_ref != ref_frame) continue;
Debargha Mukherjeecb603792016-10-04 13:10:23 -07008837 mbmi->interintra_mode = intra_to_interintra_mode[best_intra_mode];
hui su5db97432016-10-14 16:10:14 -07008838// TODO(debargha|geza.lore):
8839// Should we use ext_intra modes for interintra?
Yaowu Xuc27fc142016-08-22 16:08:15 -07008840#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008841 mbmi->angle_delta[0] = 0;
8842 mbmi->angle_delta[1] = 0;
8843 mbmi->intra_filter = INTRA_FILTER_LINEAR;
8844#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008845#if CONFIG_FILTER_INTRA
8846 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
8847 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
8848#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008849 }
8850#endif // CONFIG_EXT_INTER
8851#if CONFIG_REF_MV
8852 mbmi->ref_mv_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07008853 ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008854
8855 if (this_mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
8856 int ref;
8857 for (ref = 0; ref < 1 + comp_pred; ++ref) {
8858 int_mv this_mv =
8859 (ref == 0) ? mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv
8860 : mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
8861 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << 3, xd->n8_h << 3, xd);
8862 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
8863 }
8864 }
8865#endif
8866 this_rd = handle_inter_mode(
8867 cpi, x, bsize, &rate2, &distortion2, &skippable, &rate_y, &rate_uv,
8868 &disable_skip, frame_mv, mi_row, mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07008869#if CONFIG_MOTION_VAR
Yue Chene9638cc2016-10-10 12:37:54 -07008870 dst_buf1, dst_stride1, dst_buf2, dst_stride2,
Yue Chencb60b182016-10-13 15:18:22 -07008871#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008872#if CONFIG_EXT_INTER
8873 single_newmvs, single_newmvs_rate, &compmode_interintra_cost,
8874 &compmode_wedge_cost, modelled_rd,
8875#else
8876 single_newmv,
8877#endif // CONFIG_EXT_INTER
8878 single_inter_filter, single_skippable, &total_sse, best_rd);
8879
8880#if CONFIG_REF_MV
8881 // TODO(jingning): This needs some refactoring to improve code quality
8882 // and reduce redundant steps.
8883 if ((mbmi->mode == NEARMV &&
8884 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
8885 (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
8886 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
8887 MB_MODE_INFO backup_mbmi = *mbmi;
8888 int backup_skip = x->skip;
8889 int64_t tmp_ref_rd = this_rd;
8890 int ref_idx;
8891
8892 // TODO(jingning): This should be deprecated shortly.
8893 int idx_offset = (mbmi->mode == NEARMV) ? 1 : 0;
8894 int ref_set =
Yaowu Xuf883b422016-08-30 14:01:10 -07008895 AOMMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 1 - idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008896
8897 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07008898 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008899 // Dummy
8900 int_mv backup_fmv[2];
8901 backup_fmv[0] = frame_mv[NEWMV][ref_frame];
8902 if (comp_pred) backup_fmv[1] = frame_mv[NEWMV][second_ref_frame];
8903
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07008904 rate2 += (rate2 < INT_MAX ? cpi->drl_mode_cost0[drl_ctx][0] : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008905
8906 if (this_rd < INT64_MAX) {
8907 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
8908 RDCOST(x->rdmult, x->rddiv, 0, total_sse))
8909 tmp_ref_rd =
8910 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -07008911 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Yaowu Xuc27fc142016-08-22 16:08:15 -07008912 distortion2);
8913 else
8914 tmp_ref_rd =
8915 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -07008916 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
Yaowu Xuc27fc142016-08-22 16:08:15 -07008917 rate_y - rate_uv,
8918 total_sse);
8919 }
8920#if CONFIG_VAR_TX
8921 for (i = 0; i < MAX_MB_PLANE; ++i)
8922 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
8923 sizeof(uint8_t) * ctx->num_4x4_blk);
8924#endif
8925
8926 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
8927 int64_t tmp_alt_rd = INT64_MAX;
8928 int tmp_rate = 0, tmp_rate_y = 0, tmp_rate_uv = 0;
8929 int tmp_skip = 1;
8930 int64_t tmp_dist = 0, tmp_sse = 0;
8931 int dummy_disable_skip = 0;
8932 int ref;
8933 int_mv cur_mv;
8934
8935 mbmi->ref_mv_idx = 1 + ref_idx;
8936
8937 for (ref = 0; ref < 1 + comp_pred; ++ref) {
8938 int_mv this_mv =
8939 (ref == 0)
8940 ? mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
8941 .this_mv
8942 : mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
8943 .comp_mv;
8944 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << 3, xd->n8_h << 3, xd);
8945 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
8946 }
8947
8948 cur_mv =
8949 mbmi_ext->ref_mv_stack[ref_frame][mbmi->ref_mv_idx + idx_offset]
8950 .this_mv;
8951 clamp_mv2(&cur_mv.as_mv, xd);
8952
8953 if (!mv_check_bounds(x, &cur_mv.as_mv)) {
clang-format67948d32016-09-07 22:40:40 -07008954 int dummy_single_skippable[MB_MODE_COUNT]
8955 [TOTAL_REFS_PER_FRAME] = { { 0 } };
Yaowu Xuc27fc142016-08-22 16:08:15 -07008956#if CONFIG_EXT_INTER
8957 int_mv dummy_single_newmvs[2][TOTAL_REFS_PER_FRAME] = { { { 0 } },
8958 { { 0 } } };
8959 int dummy_single_newmvs_rate[2][TOTAL_REFS_PER_FRAME] = { { 0 },
8960 { 0 } };
8961 int dummy_compmode_interintra_cost = 0;
8962 int dummy_compmode_wedge_cost = 0;
8963#else
8964 int_mv dummy_single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
8965#endif
8966
8967 frame_mv[NEARMV][ref_frame] = cur_mv;
8968 tmp_alt_rd = handle_inter_mode(
8969 cpi, x, bsize, &tmp_rate, &tmp_dist, &tmp_skip, &tmp_rate_y,
8970 &tmp_rate_uv, &dummy_disable_skip, frame_mv, mi_row, mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07008971#if CONFIG_MOTION_VAR
Yue Chene9638cc2016-10-10 12:37:54 -07008972 dst_buf1, dst_stride1, dst_buf2, dst_stride2,
Yue Chencb60b182016-10-13 15:18:22 -07008973#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008974#if CONFIG_EXT_INTER
8975 dummy_single_newmvs, dummy_single_newmvs_rate,
8976 &dummy_compmode_interintra_cost, &dummy_compmode_wedge_cost,
8977 NULL,
8978#else
8979 dummy_single_newmv,
8980#endif
Jingning Han72120962016-10-24 09:32:41 -07008981 single_inter_filter, dummy_single_skippable, &tmp_sse, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008982 }
8983
8984 for (i = 0; i < mbmi->ref_mv_idx; ++i) {
8985 uint8_t drl1_ctx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07008986 drl1_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
8987 i + idx_offset);
Yi Luoe8e8cd82016-09-21 10:45:01 -07008988 tmp_rate +=
8989 (tmp_rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][1] : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008990 }
8991
8992 if (mbmi_ext->ref_mv_count[ref_frame_type] >
8993 mbmi->ref_mv_idx + idx_offset + 1 &&
8994 ref_idx < ref_set - 1) {
8995 uint8_t drl1_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07008996 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
8997 mbmi->ref_mv_idx + idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008998 tmp_rate += cpi->drl_mode_cost0[drl1_ctx][0];
8999 }
9000
9001 if (tmp_alt_rd < INT64_MAX) {
Yue Chencb60b182016-10-13 15:18:22 -07009002#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009003 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv, tmp_rate, tmp_dist);
9004#else
9005 if (RDCOST(x->rdmult, x->rddiv, tmp_rate_y + tmp_rate_uv,
9006 tmp_dist) < RDCOST(x->rdmult, x->rddiv, 0, tmp_sse))
Yaowu Xuf883b422016-08-30 14:01:10 -07009007 tmp_alt_rd =
9008 RDCOST(x->rdmult, x->rddiv,
9009 tmp_rate + av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
9010 tmp_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009011 else
Yaowu Xuf883b422016-08-30 14:01:10 -07009012 tmp_alt_rd =
9013 RDCOST(x->rdmult, x->rddiv,
9014 tmp_rate + av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
9015 tmp_rate_y - tmp_rate_uv,
9016 tmp_sse);
Yue Chencb60b182016-10-13 15:18:22 -07009017#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009018 }
9019
9020 if (tmp_ref_rd > tmp_alt_rd) {
9021 rate2 = tmp_rate;
9022 disable_skip = dummy_disable_skip;
9023 distortion2 = tmp_dist;
9024 skippable = tmp_skip;
9025 rate_y = tmp_rate_y;
9026 rate_uv = tmp_rate_uv;
9027 total_sse = tmp_sse;
9028 this_rd = tmp_alt_rd;
9029 tmp_ref_rd = tmp_alt_rd;
9030 backup_mbmi = *mbmi;
9031 backup_skip = x->skip;
9032#if CONFIG_VAR_TX
9033 for (i = 0; i < MAX_MB_PLANE; ++i)
9034 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
9035 sizeof(uint8_t) * ctx->num_4x4_blk);
9036#endif
9037 } else {
9038 *mbmi = backup_mbmi;
9039 x->skip = backup_skip;
9040 }
9041 }
9042
9043 frame_mv[NEARMV][ref_frame] = backup_mv;
9044 frame_mv[NEWMV][ref_frame] = backup_fmv[0];
9045 if (comp_pred) frame_mv[NEWMV][second_ref_frame] = backup_fmv[1];
9046#if CONFIG_VAR_TX
9047 for (i = 0; i < MAX_MB_PLANE; ++i)
9048 memcpy(x->blk_skip[i], x->blk_skip_drl[i],
9049 sizeof(uint8_t) * ctx->num_4x4_blk);
9050#endif
9051 }
9052 mbmi_ext->ref_mvs[ref_frame][0] = backup_ref_mv[0];
9053 if (comp_pred) mbmi_ext->ref_mvs[second_ref_frame][0] = backup_ref_mv[1];
9054#endif // CONFIG_REF_MV
9055
9056 if (this_rd == INT64_MAX) continue;
9057
Yaowu Xuf883b422016-08-30 14:01:10 -07009058 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009059
9060 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
9061 }
9062
9063#if CONFIG_EXT_INTER
9064 rate2 += compmode_interintra_cost;
9065 if (cm->reference_mode != SINGLE_REFERENCE && comp_pred)
Yue Chencb60b182016-10-13 15:18:22 -07009066#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
9067 if (mbmi->motion_mode == SIMPLE_TRANSLATION)
9068#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009069 rate2 += compmode_wedge_cost;
9070#endif // CONFIG_EXT_INTER
9071
9072 // Estimate the reference frame signaling cost and add it
9073 // to the rolling cost variable.
9074 if (comp_pred) {
9075 rate2 += ref_costs_comp[ref_frame];
9076#if CONFIG_EXT_REFS
9077 rate2 += ref_costs_comp[second_ref_frame];
9078#endif // CONFIG_EXT_REFS
9079 } else {
9080 rate2 += ref_costs_single[ref_frame];
9081 }
9082
Yue Chencb60b182016-10-13 15:18:22 -07009083#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009084 if (ref_frame == INTRA_FRAME) {
9085#else
9086 if (!disable_skip) {
Yue Chencb60b182016-10-13 15:18:22 -07009087#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009088 if (skippable) {
9089 // Back out the coefficient coding costs
9090 rate2 -= (rate_y + rate_uv);
9091 rate_y = 0;
9092 rate_uv = 0;
9093 // Cost the skip mb case
Yaowu Xuf883b422016-08-30 14:01:10 -07009094 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009095 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009096#if CONFIG_REF_MV
9097 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv + rate_skip0,
9098 distortion2) <
9099 RDCOST(x->rdmult, x->rddiv, rate_skip1, total_sse)) {
9100#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009101 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
9102 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009103#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009104 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -07009105 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009106 } else {
9107 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -07009108 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009109 distortion2 = total_sse;
9110 assert(total_sse >= 0);
9111 rate2 -= (rate_y + rate_uv);
9112 this_skip2 = 1;
9113 rate_y = 0;
9114 rate_uv = 0;
9115 }
9116 } else {
9117 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -07009118 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009119 }
9120
9121 // Calculate the final RD estimate for this mode.
9122 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yue Chencb60b182016-10-13 15:18:22 -07009123#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009124 } else {
9125 this_skip2 = mbmi->skip;
9126 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
9127 if (this_skip2) {
9128 rate_y = 0;
9129 rate_uv = 0;
9130 }
Yue Chencb60b182016-10-13 15:18:22 -07009131#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009132 }
9133
Yaowu Xuc27fc142016-08-22 16:08:15 -07009134 if (ref_frame == INTRA_FRAME) {
9135 // Keep record of best intra rd
9136 if (this_rd < best_intra_rd) {
9137 best_intra_rd = this_rd;
9138 best_intra_mode = mbmi->mode;
9139 }
9140#if CONFIG_EXT_INTER
9141 } else if (second_ref_frame == NONE) {
9142 if (this_rd < best_single_inter_rd) {
9143 best_single_inter_rd = this_rd;
9144 best_single_inter_ref = mbmi->ref_frame[0];
9145 }
9146#endif // CONFIG_EXT_INTER
9147 }
9148
9149 if (!disable_skip && ref_frame == INTRA_FRAME) {
9150 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009151 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009152 }
9153
9154 // Did this mode help.. i.e. is it the new best mode
9155 if (this_rd < best_rd || x->skip) {
9156 if (!mode_excluded) {
9157 // Note index of best mode so far
9158 best_mode_index = mode_index;
9159
9160 if (ref_frame == INTRA_FRAME) {
9161 /* required for left and above block mv */
9162 mbmi->mv[0].as_int = 0;
9163 } else {
9164 best_pred_sse = x->pred_sse[ref_frame];
9165 }
9166
9167 rd_cost->rate = rate2;
9168#if CONFIG_SUPERTX
9169 if (x->skip)
9170 *returnrate_nocoef = rate2;
9171 else
9172 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07009173 *returnrate_nocoef -= av1_cost_bit(
9174 av1_get_skip_prob(cm, xd), disable_skip || skippable || this_skip2);
9175 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
9176 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chencb60b182016-10-13 15:18:22 -07009177#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
9178 if (is_inter_block(mbmi) && is_motion_variation_allowed(mbmi))
9179 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
9180#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009181#endif // CONFIG_SUPERTX
9182 rd_cost->dist = distortion2;
9183 rd_cost->rdcost = this_rd;
9184 best_rd = this_rd;
9185 best_mbmode = *mbmi;
9186 best_skip2 = this_skip2;
9187 best_mode_skippable = skippable;
Yaowu Xuf883b422016-08-30 14:01:10 -07009188 best_rate_y = rate_y + av1_cost_bit(av1_get_skip_prob(cm, xd),
9189 this_skip2 || skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009190 best_rate_uv = rate_uv;
9191
9192#if CONFIG_VAR_TX
9193 for (i = 0; i < MAX_MB_PLANE; ++i)
9194 memcpy(ctx->blk_skip[i], x->blk_skip[i],
9195 sizeof(uint8_t) * ctx->num_4x4_blk);
9196#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009197 }
9198 }
9199
9200 /* keep record of best compound/single-only prediction */
9201 if (!disable_skip && ref_frame != INTRA_FRAME) {
9202 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
9203
9204 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
9205 single_rate = rate2 - compmode_cost;
9206 hybrid_rate = rate2;
9207 } else {
9208 single_rate = rate2;
9209 hybrid_rate = rate2 + compmode_cost;
9210 }
9211
9212 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
9213 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
9214
9215 if (!comp_pred) {
9216 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
9217 best_pred_rd[SINGLE_REFERENCE] = single_rd;
9218 } else {
9219 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
9220 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
9221 }
9222 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
9223 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
9224 }
9225
Yaowu Xuc27fc142016-08-22 16:08:15 -07009226 if (x->skip && !comp_pred) break;
9227 }
9228
9229 if (xd->lossless[mbmi->segment_id] == 0 && best_mode_index >= 0 &&
9230 ((sf->tx_type_search.fast_inter_tx_type_search == 1 &&
9231 is_inter_mode(best_mbmode.mode)) ||
9232 (sf->tx_type_search.fast_intra_tx_type_search == 1 &&
9233 !is_inter_mode(best_mbmode.mode)))) {
9234 int rate_y = 0, rate_uv = 0;
9235 int64_t dist_y = 0, dist_uv = 0;
9236 int skip_y = 0, skip_uv = 0, skip_blk = 0;
9237 int64_t sse_y = 0, sse_uv = 0;
9238
9239 x->use_default_inter_tx_type = 0;
9240 x->use_default_intra_tx_type = 0;
9241
9242 *mbmi = best_mbmode;
9243
9244 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
9245
9246 // Select prediction reference frames.
9247 for (i = 0; i < MAX_MB_PLANE; i++) {
9248 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
9249 if (has_second_ref(mbmi))
9250 xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
9251 }
9252
9253 if (is_inter_mode(mbmi->mode)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009254 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yue Chencb60b182016-10-13 15:18:22 -07009255#if CONFIG_MOTION_VAR
9256 if (mbmi->motion_mode == OBMC_CAUSAL)
Yaowu Xuf883b422016-08-30 14:01:10 -07009257 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1,
9258 dst_stride1, dst_buf2, dst_stride2);
Yue Chencb60b182016-10-13 15:18:22 -07009259#endif // CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009260 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009261#if CONFIG_VAR_TX
9262 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
9263 select_tx_type_yrd(cpi, x, &rate_y, &dist_y, &skip_y, &sse_y, bsize,
9264 INT64_MAX);
9265 } else {
9266 int idx, idy;
9267 super_block_yrd(cpi, x, &rate_y, &dist_y, &skip_y, &sse_y, bsize,
9268 INT64_MAX);
9269 for (idy = 0; idy < xd->n8_h; ++idy)
9270 for (idx = 0; idx < xd->n8_w; ++idx)
9271 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
9272 memset(x->blk_skip[0], skip_y,
9273 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
9274 }
9275
9276 inter_block_uvrd(cpi, x, &rate_uv, &dist_uv, &skip_uv, &sse_uv, bsize,
9277 INT64_MAX);
9278#else
9279 super_block_yrd(cpi, x, &rate_y, &dist_y, &skip_y, &sse_y, bsize,
9280 INT64_MAX);
9281 super_block_uvrd(cpi, x, &rate_uv, &dist_uv, &skip_uv, &sse_uv, bsize,
9282 INT64_MAX);
9283#endif // CONFIG_VAR_TX
9284 } else {
9285 super_block_yrd(cpi, x, &rate_y, &dist_y, &skip_y, &sse_y, bsize,
9286 INT64_MAX);
9287 super_block_uvrd(cpi, x, &rate_uv, &dist_uv, &skip_uv, &sse_uv, bsize,
9288 INT64_MAX);
9289 }
9290
9291 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, (dist_y + dist_uv)) >
9292 RDCOST(x->rdmult, x->rddiv, 0, (sse_y + sse_uv))) {
9293 skip_blk = 1;
Yaowu Xuf883b422016-08-30 14:01:10 -07009294 rate_y = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009295 rate_uv = 0;
9296 dist_y = sse_y;
9297 dist_uv = sse_uv;
9298 } else {
9299 skip_blk = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009300 rate_y += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009301 }
9302
9303 if (RDCOST(x->rdmult, x->rddiv, best_rate_y + best_rate_uv, rd_cost->dist) >
9304 RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, (dist_y + dist_uv))) {
9305#if CONFIG_VAR_TX
9306 int idx, idy;
9307#endif
9308 best_mbmode.tx_type = mbmi->tx_type;
9309 best_mbmode.tx_size = mbmi->tx_size;
9310#if CONFIG_VAR_TX
9311 for (idy = 0; idy < xd->n8_h; ++idy)
9312 for (idx = 0; idx < xd->n8_w; ++idx)
9313 best_mbmode.inter_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
9314
9315 for (i = 0; i < MAX_MB_PLANE; ++i)
9316 memcpy(ctx->blk_skip[i], x->blk_skip[i],
9317 sizeof(uint8_t) * ctx->num_4x4_blk);
9318#endif
9319 rd_cost->rate += (rate_y + rate_uv - best_rate_y - best_rate_uv);
9320 rd_cost->dist = dist_y + dist_uv;
9321 rd_cost->rdcost =
9322 RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
9323 best_skip2 = skip_blk;
9324 }
9325 }
9326
Urvang Joshib100db72016-10-12 16:28:56 -07009327#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009328 // Only try palette mode when the best mode so far is an intra mode.
9329 if (cm->allow_screen_content_tools && !is_inter_mode(best_mbmode.mode)) {
9330 PREDICTION_MODE mode_selected;
9331 int rate2 = 0, rate_y = 0;
9332#if CONFIG_SUPERTX
9333 int best_rate_nocoef;
9334#endif
9335 int64_t distortion2 = 0, distortion_y = 0, dummy_rd = best_rd, this_rd;
Urvang Joshi626591d2016-10-24 14:13:55 -07009336 int skippable = 0, rate_overhead_palette = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009337 TX_SIZE best_tx_size, uv_tx;
9338 TX_TYPE best_tx_type;
9339 PALETTE_MODE_INFO palette_mode_info;
9340 uint8_t *const best_palette_color_map =
9341 x->palette_buffer->best_palette_color_map;
9342 uint8_t *const color_map = xd->plane[0].color_index_map;
9343
9344 mbmi->mode = DC_PRED;
9345 mbmi->uv_mode = DC_PRED;
9346 mbmi->ref_frame[0] = INTRA_FRAME;
9347 mbmi->ref_frame[1] = NONE;
9348 palette_mode_info.palette_size[0] = 0;
Urvang Joshi626591d2016-10-24 14:13:55 -07009349 rate_overhead_palette = rd_pick_palette_intra_sby(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009350 cpi, x, bsize, palette_ctx, intra_mode_cost[DC_PRED],
9351 &palette_mode_info, best_palette_color_map, &best_tx_size,
9352 &best_tx_type, &mode_selected, &dummy_rd);
9353 if (palette_mode_info.palette_size[0] == 0) goto PALETTE_EXIT;
9354
9355 pmi->palette_size[0] = palette_mode_info.palette_size[0];
9356 if (palette_mode_info.palette_size[0] > 0) {
9357 memcpy(pmi->palette_colors, palette_mode_info.palette_colors,
9358 PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
9359 memcpy(color_map, best_palette_color_map,
9360 rows * cols * sizeof(best_palette_color_map[0]));
9361 }
9362 super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable, NULL, bsize,
9363 best_rd);
9364 if (rate_y == INT_MAX) goto PALETTE_EXIT;
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009365 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
9366 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009367 if (rate_uv_intra[uv_tx] == INT_MAX) {
9368 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -07009369 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
9370 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009371 pmi_uv[uv_tx] = *pmi;
9372#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009373 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
9374#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009375#if CONFIG_FILTER_INTRA
9376 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9377#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009378 }
9379 mbmi->uv_mode = mode_uv[uv_tx];
9380 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9381 if (pmi->palette_size[1] > 0)
9382 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9383 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9384 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9385#if CONFIG_EXT_INTRA
9386 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009387#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009388#if CONFIG_FILTER_INTRA
9389 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9390 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9391 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9392 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9393 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
9394 }
9395#endif // CONFIG_FILTER_INTRA
Yaowu Xuc287e272016-10-20 18:19:16 -07009396 skippable = skippable && skip_uvs[uv_tx];
9397 distortion2 = distortion_y + dist_uvs[uv_tx];
Urvang Joshi626591d2016-10-24 14:13:55 -07009398 rate2 = rate_y + rate_overhead_palette + rate_uv_intra[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009399 rate2 += ref_costs_single[INTRA_FRAME];
9400
9401 if (skippable) {
9402 rate2 -= (rate_y + rate_uv_tokenonly[uv_tx]);
9403#if CONFIG_SUPERTX
9404 best_rate_nocoef = rate2;
9405#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07009406 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009407 } else {
9408#if CONFIG_SUPERTX
9409 best_rate_nocoef = rate2 - (rate_y + rate_uv_tokenonly[uv_tx]);
9410#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07009411 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009412 }
9413 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
9414 if (this_rd < best_rd) {
9415 best_mode_index = 3;
9416 mbmi->mv[0].as_int = 0;
9417 rd_cost->rate = rate2;
9418#if CONFIG_SUPERTX
9419 *returnrate_nocoef = best_rate_nocoef;
9420#endif
9421 rd_cost->dist = distortion2;
9422 rd_cost->rdcost = this_rd;
9423 best_rd = this_rd;
9424 best_mbmode = *mbmi;
9425 best_skip2 = 0;
9426 best_mode_skippable = skippable;
9427 }
9428 }
9429PALETTE_EXIT:
Urvang Joshib100db72016-10-12 16:28:56 -07009430#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009431
hui su5db97432016-10-14 16:10:14 -07009432#if CONFIG_FILTER_INTRA
9433 // TODO(huisu): filter-intra is turned off in lossless mode for now to
Yaowu Xuc27fc142016-08-22 16:08:15 -07009434 // avoid a unit test failure
hui su5db97432016-10-14 16:10:14 -07009435 if (!xd->lossless[mbmi->segment_id] &&
Urvang Joshib100db72016-10-12 16:28:56 -07009436#if CONFIG_PALETTE
9437 mbmi->palette_mode_info.palette_size[0] == 0 &&
9438#endif // CONFIG_PALETTE
9439 !dc_skipped && best_mode_index >= 0 &&
9440 best_intra_rd < (best_rd + (best_rd >> 3))) {
hui su5db97432016-10-14 16:10:14 -07009441 pick_filter_intra_interframe(
Urvang Joshi368fbc92016-10-17 16:31:34 -07009442 cpi, x, ctx, bsize, rate_uv_intra, rate_uv_tokenonly, dist_uvs,
hui su5db97432016-10-14 16:10:14 -07009443 skip_uvs, mode_uv, filter_intra_mode_info_uv,
9444#if CONFIG_EXT_INTRA
9445 uv_angle_delta,
9446#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07009447#if CONFIG_PALETTE
9448 pmi_uv, palette_ctx,
9449#endif // CONFIG_PALETTE
9450 0, ref_costs_single, &best_rd, &best_intra_rd, &best_intra_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009451 &best_mode_index, &best_skip2, &best_mode_skippable,
9452#if CONFIG_SUPERTX
9453 returnrate_nocoef,
9454#endif // CONFIG_SUPERTX
9455 best_pred_rd, &best_mbmode, rd_cost);
9456 }
hui su5db97432016-10-14 16:10:14 -07009457#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009458
9459 // The inter modes' rate costs are not calculated precisely in some cases.
9460 // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
9461 // ZEROMV. Here, checks are added for those cases, and the mode decisions
9462 // are corrected.
9463 if (best_mbmode.mode == NEWMV
9464#if CONFIG_EXT_INTER
9465 || best_mbmode.mode == NEWFROMNEARMV || best_mbmode.mode == NEW_NEWMV
9466#endif // CONFIG_EXT_INTER
9467 ) {
9468 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
9469 best_mbmode.ref_frame[1] };
9470 int comp_pred_mode = refs[1] > INTRA_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -07009471 int_mv zeromv[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009472#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07009473 const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame);
Sarah Parkere5299862016-08-16 14:57:37 -07009474#endif // CONFIG_REF_MV
9475#if CONFIG_GLOBAL_MOTION
9476 zeromv[0].as_int = cm->global_motion[refs[0]].motion_params.wmmat[0].as_int;
9477 zeromv[1].as_int = cm->global_motion[refs[1]].motion_params.wmmat[0].as_int;
9478#else
9479 zeromv[0].as_int = 0;
9480 zeromv[1].as_int = 0;
9481#endif // CONFIG_GLOBAL_MOTION
9482#if CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07009483 if (!comp_pred_mode) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009484 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -07009485 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009486 : INT_MAX;
9487
9488 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
9489 int_mv cur_mv = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
9490 if (cur_mv.as_int == best_mbmode.mv[0].as_int) {
9491 best_mbmode.mode = NEARMV;
9492 best_mbmode.ref_mv_idx = i;
9493 }
9494 }
9495
9496 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
9497 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -07009498 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009499 best_mbmode.mode = ZEROMV;
9500 } else {
9501 int_mv nearestmv[2];
9502 int_mv nearmv[2];
9503
9504#if CONFIG_EXT_INTER
9505 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
9506 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][1].this_mv;
9507 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][1].comp_mv;
9508 } else {
9509 nearmv[0] = frame_mv[NEARMV][refs[0]];
9510 nearmv[1] = frame_mv[NEARMV][refs[1]];
9511 }
9512#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009513 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -07009514 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009515 : INT_MAX;
9516
9517 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
9518 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
9519 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
9520
9521 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
9522 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
9523 best_mbmode.mode = NEARMV;
9524 best_mbmode.ref_mv_idx = i;
9525 }
9526 }
9527#endif
9528 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
9529 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
9530 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
9531 } else {
9532 nearestmv[0] = frame_mv[NEARESTMV][refs[0]];
9533 nearestmv[1] = frame_mv[NEARESTMV][refs[1]];
9534 }
9535
9536 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
9537 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
9538#if CONFIG_EXT_INTER
9539 best_mbmode.mode = NEAREST_NEARESTMV;
9540 else if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
9541 nearmv[1].as_int == best_mbmode.mv[1].as_int)
9542 best_mbmode.mode = NEAREST_NEARMV;
9543 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
9544 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
9545 best_mbmode.mode = NEAR_NEARESTMV;
9546 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
9547 nearmv[1].as_int == best_mbmode.mv[1].as_int)
9548 best_mbmode.mode = NEAR_NEARMV;
9549 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
9550 best_mbmode.mode = ZERO_ZEROMV;
9551#else
9552 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -07009553 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
9554 best_mbmode.mv[1].as_int == zeromv[1].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009555 best_mbmode.mode = ZEROMV;
9556#endif // CONFIG_EXT_INTER
9557 }
9558#else
9559#if CONFIG_EXT_INTER
9560 if (!comp_pred_mode) {
9561#endif // CONFIG_EXT_INTER
9562 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
9563 ((comp_pred_mode &&
9564 frame_mv[NEARESTMV][refs[1]].as_int == best_mbmode.mv[1].as_int) ||
9565 !comp_pred_mode))
9566 best_mbmode.mode = NEARESTMV;
9567 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
9568 ((comp_pred_mode &&
9569 frame_mv[NEARMV][refs[1]].as_int ==
9570 best_mbmode.mv[1].as_int) ||
9571 !comp_pred_mode))
9572 best_mbmode.mode = NEARMV;
Sarah Parkere5299862016-08-16 14:57:37 -07009573 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
9574 ((comp_pred_mode &&
9575 best_mbmode.mv[1].as_int == zeromv[1].as_int) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07009576 !comp_pred_mode))
9577 best_mbmode.mode = ZEROMV;
9578#if CONFIG_EXT_INTER
9579 } else {
9580 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
9581 best_mbmode.ref_frame[1] };
9582
9583 if (frame_mv[NEAREST_NEARESTMV][refs[0]].as_int ==
9584 best_mbmode.mv[0].as_int &&
9585 frame_mv[NEAREST_NEARESTMV][refs[1]].as_int ==
9586 best_mbmode.mv[1].as_int)
9587 best_mbmode.mode = NEAREST_NEARESTMV;
9588 else if (frame_mv[NEAREST_NEARMV][refs[0]].as_int ==
9589 best_mbmode.mv[0].as_int &&
9590 frame_mv[NEAREST_NEARMV][refs[1]].as_int ==
9591 best_mbmode.mv[1].as_int)
9592 best_mbmode.mode = NEAREST_NEARMV;
9593 else if (frame_mv[NEAR_NEARESTMV][refs[0]].as_int ==
9594 best_mbmode.mv[0].as_int &&
9595 frame_mv[NEAR_NEARESTMV][refs[1]].as_int ==
9596 best_mbmode.mv[1].as_int)
9597 best_mbmode.mode = NEAR_NEARESTMV;
9598 else if (frame_mv[NEAR_NEARMV][refs[0]].as_int ==
9599 best_mbmode.mv[0].as_int &&
9600 frame_mv[NEAR_NEARMV][refs[1]].as_int ==
9601 best_mbmode.mv[1].as_int)
9602 best_mbmode.mode = NEAR_NEARMV;
9603 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
9604 best_mbmode.mode = ZERO_ZEROMV;
9605 }
9606#endif // CONFIG_EXT_INTER
9607#endif
9608 }
9609
9610#if CONFIG_REF_MV
9611 if (best_mbmode.ref_frame[0] > INTRA_FRAME && best_mbmode.mv[0].as_int == 0 &&
9612#if CONFIG_EXT_INTER
9613 (best_mbmode.ref_frame[1] <= INTRA_FRAME)
9614#else
9615 (best_mbmode.ref_frame[1] == NONE || best_mbmode.mv[1].as_int == 0)
9616#endif // CONFIG_EXT_INTER
9617 ) {
9618 int16_t mode_ctx = mbmi_ext->mode_context[best_mbmode.ref_frame[0]];
9619#if !CONFIG_EXT_INTER
9620 if (best_mbmode.ref_frame[1] > NONE)
9621 mode_ctx &= (mbmi_ext->mode_context[best_mbmode.ref_frame[1]] | 0x00ff);
9622#endif // !CONFIG_EXT_INTER
9623
9624 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) best_mbmode.mode = ZEROMV;
9625 }
9626#endif
9627
9628 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
9629 rd_cost->rate = INT_MAX;
9630 rd_cost->rdcost = INT64_MAX;
9631 return;
9632 }
9633
Yaowu Xuc27fc142016-08-22 16:08:15 -07009634#if CONFIG_DUAL_FILTER
9635 assert((cm->interp_filter == SWITCHABLE) ||
9636 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
9637 !is_inter_block(&best_mbmode));
9638 assert((cm->interp_filter == SWITCHABLE) ||
9639 (cm->interp_filter == best_mbmode.interp_filter[1]) ||
9640 !is_inter_block(&best_mbmode));
9641 if (best_mbmode.ref_frame[1] > INTRA_FRAME) {
9642 assert((cm->interp_filter == SWITCHABLE) ||
9643 (cm->interp_filter == best_mbmode.interp_filter[2]) ||
9644 !is_inter_block(&best_mbmode));
9645 assert((cm->interp_filter == SWITCHABLE) ||
9646 (cm->interp_filter == best_mbmode.interp_filter[3]) ||
9647 !is_inter_block(&best_mbmode));
9648 }
9649#else
9650 assert((cm->interp_filter == SWITCHABLE) ||
9651 (cm->interp_filter == best_mbmode.interp_filter) ||
9652 !is_inter_block(&best_mbmode));
9653#endif
9654
9655 if (!cpi->rc.is_src_frame_alt_ref)
Yaowu Xuf883b422016-08-30 14:01:10 -07009656 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
9657 sf->adaptive_rd_thresh, bsize, best_mode_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009658
9659 // macroblock modes
9660 *mbmi = best_mbmode;
9661 x->skip |= best_skip2;
9662
9663#if CONFIG_REF_MV
9664 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
9665 if (mbmi->mode != NEWMV)
9666 mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
9667 else
9668 mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
9669 }
9670#endif
9671
9672 for (i = 0; i < REFERENCE_MODES; ++i) {
9673 if (best_pred_rd[i] == INT64_MAX)
9674 best_pred_diff[i] = INT_MIN;
9675 else
9676 best_pred_diff[i] = best_rd - best_pred_rd[i];
9677 }
9678
9679 x->skip |= best_mode_skippable;
9680
9681 assert(best_mode_index >= 0);
9682
9683 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
9684 best_mode_skippable);
9685
Urvang Joshib100db72016-10-12 16:28:56 -07009686#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009687 if (cm->allow_screen_content_tools && pmi->palette_size[1] > 0) {
9688 restore_uv_color_map(cpi, x);
9689 }
Urvang Joshib100db72016-10-12 16:28:56 -07009690#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009691}
9692
Urvang Joshi52648442016-10-13 17:27:51 -07009693void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
9694 TileDataEnc *tile_data, MACROBLOCK *x,
9695 RD_COST *rd_cost, BLOCK_SIZE bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -07009696 PICK_MODE_CONTEXT *ctx,
9697 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07009698 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009699 MACROBLOCKD *const xd = &x->e_mbd;
9700 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
9701 unsigned char segment_id = mbmi->segment_id;
9702 const int comp_pred = 0;
9703 int i;
9704 int64_t best_pred_diff[REFERENCE_MODES];
9705 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
9706 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -07009707 aom_prob comp_mode_p;
James Zern7b9407a2016-05-18 23:48:05 -07009708 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009709 int64_t this_rd = INT64_MAX;
9710 int rate2 = 0;
9711 const int64_t distortion2 = 0;
9712
9713 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
9714 &comp_mode_p);
9715
9716 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
9717 for (i = LAST_FRAME; i < TOTAL_REFS_PER_FRAME; ++i)
9718 x->pred_mv_sad[i] = INT_MAX;
9719
9720 rd_cost->rate = INT_MAX;
9721
9722 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
9723
Urvang Joshib100db72016-10-12 16:28:56 -07009724#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009725 mbmi->palette_mode_info.palette_size[0] = 0;
9726 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07009727#endif // CONFIG_PALETTE
9728
hui su5db97432016-10-14 16:10:14 -07009729#if CONFIG_FILTER_INTRA
9730 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
9731 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
9732#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009733 mbmi->mode = ZEROMV;
Yue Chencb60b182016-10-13 15:18:22 -07009734 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009735 mbmi->uv_mode = DC_PRED;
9736 mbmi->ref_frame[0] = LAST_FRAME;
9737 mbmi->ref_frame[1] = NONE;
Sarah Parkere5299862016-08-16 14:57:37 -07009738#if CONFIG_GLOBAL_MOTION
9739 mbmi->mv[0].as_int =
9740 cm->global_motion[mbmi->ref_frame[0]].motion_params.wmmat[0].as_int;
9741#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009742 mbmi->mv[0].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07009743#endif // CONFIG_GLOBAL_MOTION
Jingning Han64088952016-07-11 11:24:24 -07009744 mbmi->tx_size = max_txsize_lookup[bsize];
Yaowu Xuee775b12016-10-18 10:00:21 -07009745 x->skip = 1;
Sarah Parkere5299862016-08-16 14:57:37 -07009746
Yaowu Xuc27fc142016-08-22 16:08:15 -07009747#if CONFIG_REF_MV
9748 mbmi->ref_mv_idx = 0;
9749 mbmi->pred_mv[0].as_int = 0;
9750#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009751
9752 if (cm->interp_filter != BILINEAR) {
9753 best_filter = EIGHTTAP_REGULAR;
9754 if (cm->interp_filter == SWITCHABLE &&
9755#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07009756 av1_is_interp_needed(xd) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07009757#endif // CONFIG_EXT_INTERP
9758 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
9759 int rs;
9760 int best_rs = INT_MAX;
9761 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
9762#if CONFIG_DUAL_FILTER
9763 int k;
9764 for (k = 0; k < 4; ++k) mbmi->interp_filter[k] = i;
9765#else
9766 mbmi->interp_filter = i;
9767#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07009768 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009769 if (rs < best_rs) {
9770 best_rs = rs;
9771#if CONFIG_DUAL_FILTER
9772 best_filter = mbmi->interp_filter[0];
9773#else
9774 best_filter = mbmi->interp_filter;
9775#endif
9776 }
9777 }
9778 }
9779 }
9780 // Set the appropriate filter
9781 if (cm->interp_filter == SWITCHABLE) {
9782#if CONFIG_DUAL_FILTER
9783 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = best_filter;
9784#else
9785 mbmi->interp_filter = best_filter;
9786#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07009787 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009788 } else {
9789#if CONFIG_DUAL_FILTER
9790 for (i = 0; i < 4; ++i) mbmi->interp_filter[0] = cm->interp_filter;
9791#else
9792 mbmi->interp_filter = cm->interp_filter;
9793#endif
9794 }
9795
9796 if (cm->reference_mode == REFERENCE_MODE_SELECT)
Yaowu Xuf883b422016-08-30 14:01:10 -07009797 rate2 += av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009798
9799 // Estimate the reference frame signaling cost and add it
9800 // to the rolling cost variable.
9801 rate2 += ref_costs_single[LAST_FRAME];
9802 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
9803
9804 rd_cost->rate = rate2;
9805 rd_cost->dist = distortion2;
9806 rd_cost->rdcost = this_rd;
9807
9808 if (this_rd >= best_rd_so_far) {
9809 rd_cost->rate = INT_MAX;
9810 rd_cost->rdcost = INT64_MAX;
9811 return;
9812 }
9813
9814#if CONFIG_DUAL_FILTER
9815 assert((cm->interp_filter == SWITCHABLE) ||
9816 (cm->interp_filter == mbmi->interp_filter[0]));
9817#else
9818 assert((cm->interp_filter == SWITCHABLE) ||
9819 (cm->interp_filter == mbmi->interp_filter));
9820#endif
9821
Yaowu Xuf883b422016-08-30 14:01:10 -07009822 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
9823 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009824
Yaowu Xuf883b422016-08-30 14:01:10 -07009825 av1_zero(best_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009826
9827 store_coding_context(x, ctx, THR_ZEROMV, best_pred_diff, 0);
9828}
9829
Urvang Joshi52648442016-10-13 17:27:51 -07009830void av1_rd_pick_inter_mode_sub8x8(const struct AV1_COMP *cpi,
9831 TileDataEnc *tile_data, struct macroblock *x,
9832 int mi_row, int mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -07009833 struct RD_COST *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009834#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009835 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009836#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009837 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
9838 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07009839 const AV1_COMMON *const cm = &cpi->common;
9840 const RD_OPT *const rd_opt = &cpi->rd;
9841 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009842 MACROBLOCKD *const xd = &x->e_mbd;
9843 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
9844 const struct segmentation *const seg = &cm->seg;
9845 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
9846 unsigned char segment_id = mbmi->segment_id;
9847 int comp_pred, i;
9848 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
9849 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
9850 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
9851 0,
Yaowu Xuf883b422016-08-30 14:01:10 -07009852 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009853#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009854 AOM_LAST2_FLAG,
9855 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009856#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009857 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009858#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009859 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009860#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009861 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07009862 };
9863 int64_t best_rd = best_rd_so_far;
9864 int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
9865 int64_t best_pred_diff[REFERENCE_MODES];
9866 int64_t best_pred_rd[REFERENCE_MODES];
9867 MB_MODE_INFO best_mbmode;
9868 int ref_index, best_ref_index = 0;
9869 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
9870 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -07009871 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009872#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07009873 InterpFilter tmp_best_filter[4] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009874#else
James Zern7b9407a2016-05-18 23:48:05 -07009875 InterpFilter tmp_best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009876#endif
Jingning Han3f167252016-06-07 16:11:42 -07009877 int rate_uv_intra, rate_uv_tokenonly = INT_MAX;
9878 int64_t dist_uv = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009879 int skip_uv;
9880 PREDICTION_MODE mode_uv = DC_PRED;
Yaowu Xuf883b422016-08-30 14:01:10 -07009881 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009882 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
9883#if CONFIG_EXT_INTER
9884 int_mv seg_mvs[4][2][TOTAL_REFS_PER_FRAME];
9885#else
9886 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME];
9887#endif // CONFIG_EXT_INTER
9888 b_mode_info best_bmodes[4];
9889 int best_skip2 = 0;
9890 int ref_frame_skip_mask[2] = { 0 };
9891 int internal_active_edge =
Yaowu Xuf883b422016-08-30 14:01:10 -07009892 av1_active_edge_sb(cpi, mi_row, mi_col) && av1_internal_image_edge(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009893
9894#if CONFIG_SUPERTX
9895 best_rd_so_far = INT64_MAX;
9896 best_rd = best_rd_so_far;
9897 best_yrd = best_rd_so_far;
9898#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009899 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009900
hui su5db97432016-10-14 16:10:14 -07009901#if CONFIG_FILTER_INTRA
9902 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
9903 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
9904#endif // CONFIG_FILTER_INTRA
Yue Chencb60b182016-10-13 15:18:22 -07009905 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009906#if CONFIG_EXT_INTER
9907 mbmi->use_wedge_interinter = 0;
9908 mbmi->use_wedge_interintra = 0;
9909#endif // CONFIG_EXT_INTER
9910
9911 for (i = 0; i < 4; i++) {
9912 int j;
9913#if CONFIG_EXT_INTER
9914 int k;
9915
9916 for (k = 0; k < 2; k++)
9917 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
9918 seg_mvs[i][k][j].as_int = INVALID_MV;
9919#else
9920 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
9921 seg_mvs[i][j].as_int = INVALID_MV;
9922#endif // CONFIG_EXT_INTER
9923 }
9924
9925 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
9926 &comp_mode_p);
9927
9928 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
9929 rate_uv_intra = INT_MAX;
9930
9931 rd_cost->rate = INT_MAX;
9932#if CONFIG_SUPERTX
9933 *returnrate_nocoef = INT_MAX;
9934#endif
9935
9936 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
9937 x->mbmi_ext->mode_context[ref_frame] = 0;
9938#if CONFIG_REF_MV && CONFIG_EXT_INTER
9939 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
9940#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
9941 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
9942 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
9943 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
9944 } else {
9945 ref_frame_skip_mask[0] |= (1 << ref_frame);
9946 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9947 }
9948 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
9949#if CONFIG_EXT_INTER
9950 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
9951#endif // CONFIG_EXT_INTER
9952 frame_mv[ZEROMV][ref_frame].as_int = 0;
9953 }
9954
Urvang Joshib100db72016-10-12 16:28:56 -07009955#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009956 mbmi->palette_mode_info.palette_size[0] = 0;
9957 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07009958#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009959
9960 for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
9961 int mode_excluded = 0;
9962 int64_t this_rd = INT64_MAX;
9963 int disable_skip = 0;
9964 int compmode_cost = 0;
9965 int rate2 = 0, rate_y = 0, rate_uv = 0;
9966 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
9967 int skippable = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009968 int this_skip2 = 0;
9969 int64_t total_sse = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009970
Yaowu Xuf883b422016-08-30 14:01:10 -07009971 ref_frame = av1_ref_order[ref_index].ref_frame[0];
9972 second_ref_frame = av1_ref_order[ref_index].ref_frame[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009973
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009974#if CONFIG_REF_MV
9975 mbmi->ref_mv_idx = 0;
9976#endif
9977
Yaowu Xuc27fc142016-08-22 16:08:15 -07009978 // Look at the reference frame of the best mode so far and set the
9979 // skip mask to look at a subset of the remaining modes.
9980 if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
9981 if (ref_index == 3) {
9982 switch (best_mbmode.ref_frame[0]) {
9983 case INTRA_FRAME: break;
9984 case LAST_FRAME:
9985 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
9986#if CONFIG_EXT_REFS
9987 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
9988 (1 << BWDREF_FRAME) |
9989#endif // CONFIG_EXT_REFS
9990 (1 << ALTREF_FRAME);
9991 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9992 break;
9993#if CONFIG_EXT_REFS
9994 case LAST2_FRAME:
9995 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST3_FRAME) |
9996 (1 << GOLDEN_FRAME) |
9997 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
9998 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9999 break;
10000 case LAST3_FRAME:
10001 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
10002 (1 << GOLDEN_FRAME) |
10003 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
10004 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10005 break;
10006#endif // CONFIG_EXT_REFS
10007 case GOLDEN_FRAME:
10008 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
10009#if CONFIG_EXT_REFS
10010 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
10011 (1 << BWDREF_FRAME) |
10012#endif // CONFIG_EXT_REFS
10013 (1 << ALTREF_FRAME);
10014 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10015 break;
10016#if CONFIG_EXT_REFS
10017 case BWDREF_FRAME:
10018 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
10019 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) |
10020 (1 << ALTREF_FRAME);
10021 ref_frame_skip_mask[1] |= (1 << ALTREF_FRAME) | 0x01;
10022 break;
10023#endif // CONFIG_EXT_REFS
10024 case ALTREF_FRAME:
10025 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
10026#if CONFIG_EXT_REFS
10027 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
10028 (1 << BWDREF_FRAME) |
10029#endif // CONFIG_EXT_REFS
10030 (1 << GOLDEN_FRAME);
10031#if CONFIG_EXT_REFS
10032 ref_frame_skip_mask[1] |= (1 << BWDREF_FRAME) | 0x01;
10033#endif // CONFIG_EXT_REFS
10034 break;
10035 case NONE:
10036 case TOTAL_REFS_PER_FRAME:
10037 assert(0 && "Invalid Reference frame");
10038 break;
10039 }
10040 }
10041 }
10042
10043 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010044 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010045 continue;
10046
10047 // Test best rd so far against threshold for trying this mode.
10048 if (!internal_active_edge &&
10049 rd_less_than_thresh(best_rd,
10050 rd_opt->threshes[segment_id][bsize][ref_index],
10051 tile_data->thresh_freq_fact[bsize][ref_index]))
10052 continue;
10053
10054 comp_pred = second_ref_frame > INTRA_FRAME;
10055 if (comp_pred) {
10056 if (!cpi->allow_comp_inter_inter) continue;
10057 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
10058 // Do not allow compound prediction if the segment level reference frame
10059 // feature is in use as in this case there can only be one reference.
10060 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
10061
10062 if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
10063 best_mbmode.ref_frame[0] == INTRA_FRAME)
10064 continue;
10065 }
10066
10067 // TODO(jingning, jkoleszar): scaling reference frame not supported for
10068 // sub8x8 blocks.
10069 if (ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010070 av1_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010071 continue;
10072
10073 if (second_ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010074 av1_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010075 continue;
10076
10077 if (comp_pred)
10078 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
10079 else if (ref_frame != INTRA_FRAME)
10080 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
10081
10082 // If the segment reference frame feature is enabled....
10083 // then do nothing if the current ref frame is not allowed..
10084 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
10085 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
10086 continue;
10087 // Disable this drop out case if the ref frame
10088 // segment level feature is enabled for this segment. This is to
10089 // prevent the possibility that we end up unable to pick any mode.
10090 } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
10091 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
10092 // unless ARNR filtering is enabled in which case we want
10093 // an unfiltered alternative. We allow near/nearest as well
10094 // because they may result in zero-zero MVs but be cheaper.
10095 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
10096 continue;
10097 }
10098
10099 mbmi->tx_size = TX_4X4;
10100 mbmi->uv_mode = DC_PRED;
10101 mbmi->ref_frame[0] = ref_frame;
10102 mbmi->ref_frame[1] = second_ref_frame;
10103// Evaluate all sub-pel filters irrespective of whether we can use
10104// them for this frame.
10105#if CONFIG_DUAL_FILTER
10106 for (i = 0; i < 4; ++i)
10107 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
10108 ? EIGHTTAP_REGULAR
10109 : cm->interp_filter;
10110#else
10111 mbmi->interp_filter =
10112 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
10113#endif
10114 x->skip = 0;
10115 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
10116
10117 // Select prediction reference frames.
10118 for (i = 0; i < MAX_MB_PLANE; i++) {
10119 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
10120 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
10121 }
10122
10123#if CONFIG_VAR_TX
10124 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
10125#endif
10126
10127 if (ref_frame == INTRA_FRAME) {
10128 int rate;
10129 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y, &distortion_y,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -070010130 NULL, best_rd) >= best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010131 continue;
10132 rate2 += rate;
10133 rate2 += intra_cost_penalty;
10134 distortion2 += distortion_y;
10135
10136 if (rate_uv_intra == INT_MAX) {
10137 choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4, &rate_uv_intra,
10138 &rate_uv_tokenonly, &dist_uv, &skip_uv, &mode_uv);
10139 }
10140 rate2 += rate_uv_intra;
10141 rate_uv = rate_uv_tokenonly;
10142 distortion2 += dist_uv;
10143 distortion_uv = dist_uv;
10144 mbmi->uv_mode = mode_uv;
10145 } else {
10146 int rate;
10147 int64_t distortion;
10148 int64_t this_rd_thresh;
10149 int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
10150 int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
10151 int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
10152 int tmp_best_skippable = 0;
10153 int switchable_filter_index;
10154 int_mv *second_ref =
10155 comp_pred ? &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL;
10156 b_mode_info tmp_best_bmodes[16]; // Should this be 4 ?
10157 MB_MODE_INFO tmp_best_mbmode;
10158#if CONFIG_DUAL_FILTER
10159#if CONFIG_EXT_INTERP
10160 BEST_SEG_INFO bsi[25];
10161#else
10162 BEST_SEG_INFO bsi[9];
10163#endif
10164#else
10165 BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
10166#endif
10167 int pred_exists = 0;
10168 int uv_skippable;
10169#if CONFIG_EXT_INTER
10170 int_mv compound_seg_newmvs[4][2];
10171 for (i = 0; i < 4; i++) {
10172 compound_seg_newmvs[i][0].as_int = INVALID_MV;
10173 compound_seg_newmvs[i][1].as_int = INVALID_MV;
10174 }
10175#endif // CONFIG_EXT_INTER
10176
10177 this_rd_thresh = (ref_frame == LAST_FRAME)
10178 ? rd_opt->threshes[segment_id][bsize][THR_LAST]
10179 : rd_opt->threshes[segment_id][bsize][THR_ALTR];
10180#if CONFIG_EXT_REFS
10181 this_rd_thresh = (ref_frame == LAST2_FRAME)
10182 ? rd_opt->threshes[segment_id][bsize][THR_LAST2]
10183 : this_rd_thresh;
10184 this_rd_thresh = (ref_frame == LAST3_FRAME)
10185 ? rd_opt->threshes[segment_id][bsize][THR_LAST3]
10186 : this_rd_thresh;
10187#endif // CONFIG_EXT_REFS
10188 this_rd_thresh = (ref_frame == GOLDEN_FRAME)
10189 ? rd_opt->threshes[segment_id][bsize][THR_GOLD]
10190 : this_rd_thresh;
10191#if CONFIG_EXT_REFS
10192// TODO(zoeliu): To explore whether this_rd_thresh should consider
10193// BWDREF_FRAME and ALTREF_FRAME
10194#endif // CONFIG_EXT_REFS
10195
10196 // TODO(any): Add search of the tx_type to improve rd performance at the
10197 // expense of speed.
10198 mbmi->tx_type = DCT_DCT;
10199
10200 if (cm->interp_filter != BILINEAR) {
10201#if CONFIG_DUAL_FILTER
10202 tmp_best_filter[0] = EIGHTTAP_REGULAR;
10203 tmp_best_filter[1] = EIGHTTAP_REGULAR;
10204 tmp_best_filter[2] = EIGHTTAP_REGULAR;
10205 tmp_best_filter[3] = EIGHTTAP_REGULAR;
10206#else
10207 tmp_best_filter = EIGHTTAP_REGULAR;
10208#endif
10209 if (x->source_variance < sf->disable_filter_search_var_thresh) {
10210#if CONFIG_DUAL_FILTER
10211 tmp_best_filter[0] = EIGHTTAP_REGULAR;
10212#else
10213 tmp_best_filter = EIGHTTAP_REGULAR;
10214#endif
10215 } else if (sf->adaptive_pred_interp_filter == 1 &&
10216 ctx->pred_interp_filter < SWITCHABLE) {
10217#if CONFIG_DUAL_FILTER
10218 tmp_best_filter[0] = ctx->pred_interp_filter;
10219#else
10220 tmp_best_filter = ctx->pred_interp_filter;
10221#endif
10222 } else if (sf->adaptive_pred_interp_filter == 2) {
10223#if CONFIG_DUAL_FILTER
10224 tmp_best_filter[0] = ctx->pred_interp_filter < SWITCHABLE
10225 ? ctx->pred_interp_filter
10226 : 0;
10227#else
10228 tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE
10229 ? ctx->pred_interp_filter
10230 : 0;
10231#endif
10232 } else {
10233#if CONFIG_DUAL_FILTER
10234 for (switchable_filter_index = 0;
10235#if CONFIG_EXT_INTERP
10236 switchable_filter_index < 25;
10237#else
10238 switchable_filter_index < 9;
10239#endif
10240 ++switchable_filter_index) {
10241#else
10242 for (switchable_filter_index = 0;
10243 switchable_filter_index < SWITCHABLE_FILTERS;
10244 ++switchable_filter_index) {
10245#endif
10246 int newbest, rs;
10247 int64_t rs_rd;
10248 MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
10249#if CONFIG_DUAL_FILTER
10250 mbmi->interp_filter[0] = filter_sets[switchable_filter_index][0];
10251 mbmi->interp_filter[1] = filter_sets[switchable_filter_index][1];
10252 mbmi->interp_filter[2] = filter_sets[switchable_filter_index][0];
10253 mbmi->interp_filter[3] = filter_sets[switchable_filter_index][1];
10254#else
10255 mbmi->interp_filter = switchable_filter_index;
10256#endif
10257 tmp_rd = rd_pick_best_sub8x8_mode(
10258 cpi, x, &mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
10259 &rate, &rate_y, &distortion, &skippable, &total_sse,
10260 (int)this_rd_thresh, seg_mvs,
10261#if CONFIG_EXT_INTER
10262 compound_seg_newmvs,
10263#endif // CONFIG_EXT_INTER
10264 bsi, switchable_filter_index, mi_row, mi_col);
10265#if CONFIG_EXT_INTERP
10266#if CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070010267 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010268 (mbmi->interp_filter[0] != EIGHTTAP_REGULAR ||
10269 mbmi->interp_filter[1] != EIGHTTAP_REGULAR)) // invalid config
10270 continue;
10271#else
Yaowu Xuf883b422016-08-30 14:01:10 -070010272 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010273 mbmi->interp_filter != EIGHTTAP_REGULAR) // invalid config
10274 continue;
10275#endif
10276#endif // CONFIG_EXT_INTERP
10277 if (tmp_rd == INT64_MAX) continue;
Yaowu Xuf883b422016-08-30 14:01:10 -070010278 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010279 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
10280 if (cm->interp_filter == SWITCHABLE) tmp_rd += rs_rd;
10281
10282 newbest = (tmp_rd < tmp_best_rd);
10283 if (newbest) {
10284#if CONFIG_DUAL_FILTER
10285 tmp_best_filter[0] = mbmi->interp_filter[0];
10286 tmp_best_filter[1] = mbmi->interp_filter[1];
10287 tmp_best_filter[2] = mbmi->interp_filter[2];
10288 tmp_best_filter[3] = mbmi->interp_filter[3];
10289#else
10290 tmp_best_filter = mbmi->interp_filter;
10291#endif
10292 tmp_best_rd = tmp_rd;
10293 }
10294 if ((newbest && cm->interp_filter == SWITCHABLE) ||
10295 (
10296#if CONFIG_DUAL_FILTER
10297 mbmi->interp_filter[0] == cm->interp_filter
10298#else
10299 mbmi->interp_filter == cm->interp_filter
10300#endif
10301 && cm->interp_filter != SWITCHABLE)) {
10302 tmp_best_rdu = tmp_rd;
10303 tmp_best_rate = rate;
10304 tmp_best_ratey = rate_y;
10305 tmp_best_distortion = distortion;
10306 tmp_best_sse = total_sse;
10307 tmp_best_skippable = skippable;
10308 tmp_best_mbmode = *mbmi;
10309 for (i = 0; i < 4; i++) {
10310 tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
10311 }
10312 pred_exists = 1;
10313 }
10314 } // switchable_filter_index loop
10315 }
10316 }
10317
10318 if (tmp_best_rdu == INT64_MAX && pred_exists) continue;
10319
10320#if CONFIG_DUAL_FILTER
10321 mbmi->interp_filter[0] =
10322 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[0]
10323 : cm->interp_filter);
10324 mbmi->interp_filter[1] =
10325 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[1]
10326 : cm->interp_filter);
10327 mbmi->interp_filter[2] =
10328 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[2]
10329 : cm->interp_filter);
10330 mbmi->interp_filter[3] =
10331 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[3]
10332 : cm->interp_filter);
10333#else
10334 mbmi->interp_filter =
10335 (cm->interp_filter == SWITCHABLE ? tmp_best_filter
10336 : cm->interp_filter);
10337#endif
10338
10339 if (!pred_exists) {
10340 // Handles the special case when a filter that is not in the
10341 // switchable list (bilinear) is indicated at the frame level
10342 tmp_rd = rd_pick_best_sub8x8_mode(
10343 cpi, x, &x->mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
10344 &rate, &rate_y, &distortion, &skippable, &total_sse,
10345 (int)this_rd_thresh, seg_mvs,
10346#if CONFIG_EXT_INTER
10347 compound_seg_newmvs,
10348#endif // CONFIG_EXT_INTER
10349 bsi, 0, mi_row, mi_col);
10350#if CONFIG_EXT_INTERP
10351#if CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070010352 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010353 (mbmi->interp_filter[0] != EIGHTTAP_REGULAR ||
10354 mbmi->interp_filter[1] != EIGHTTAP_REGULAR)) {
10355 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
10356 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
10357 }
10358#else
Yaowu Xuf883b422016-08-30 14:01:10 -070010359 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010360 mbmi->interp_filter != EIGHTTAP_REGULAR)
10361 mbmi->interp_filter = EIGHTTAP_REGULAR;
10362#endif // CONFIG_DUAL_FILTER
10363#endif // CONFIG_EXT_INTERP
10364 if (tmp_rd == INT64_MAX) continue;
10365 } else {
10366 total_sse = tmp_best_sse;
10367 rate = tmp_best_rate;
10368 rate_y = tmp_best_ratey;
10369 distortion = tmp_best_distortion;
10370 skippable = tmp_best_skippable;
10371 *mbmi = tmp_best_mbmode;
10372 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
10373 }
10374 // Add in the cost of the transform type
10375 if (!xd->lossless[mbmi->segment_id]) {
10376 int rate_tx_type = 0;
10377#if CONFIG_EXT_TX
10378 if (get_ext_tx_types(mbmi->tx_size, bsize, 1) > 1) {
10379 const int eset = get_ext_tx_set(mbmi->tx_size, bsize, 1);
10380 rate_tx_type =
10381 cpi->inter_tx_type_costs[eset][mbmi->tx_size][mbmi->tx_type];
10382 }
10383#else
10384 if (mbmi->tx_size < TX_32X32) {
10385 rate_tx_type = cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
10386 }
10387#endif
10388 rate += rate_tx_type;
10389 rate_y += rate_tx_type;
10390 }
10391
10392 rate2 += rate;
10393 distortion2 += distortion;
10394
10395 if (cm->interp_filter == SWITCHABLE)
Yaowu Xuf883b422016-08-30 14:01:10 -070010396 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010397
10398 if (!mode_excluded)
10399 mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
10400 : cm->reference_mode == COMPOUND_REFERENCE;
10401
Yaowu Xuf883b422016-08-30 14:01:10 -070010402 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010403
10404 tmp_best_rdu =
Yaowu Xuf883b422016-08-30 14:01:10 -070010405 best_rd - AOMMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
Yaowu Xuc27fc142016-08-22 16:08:15 -070010406 RDCOST(x->rdmult, x->rddiv, 0, total_sse));
10407
10408 if (tmp_best_rdu > 0) {
10409 // If even the 'Y' rd value of split is higher than best so far
10410 // then dont bother looking at UV
Yaowu Xuf883b422016-08-30 14:01:10 -070010411 av1_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col, BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010412#if CONFIG_VAR_TX
10413 if (!inter_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
10414 &uv_sse, BLOCK_8X8, tmp_best_rdu))
10415 continue;
10416#else
10417 if (!super_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
10418 &uv_sse, BLOCK_8X8, tmp_best_rdu))
10419 continue;
10420#endif
10421 rate2 += rate_uv;
10422 distortion2 += distortion_uv;
10423 skippable = skippable && uv_skippable;
10424 total_sse += uv_sse;
10425 } else {
10426 continue;
10427 }
10428 }
10429
10430 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
10431
10432 // Estimate the reference frame signaling cost and add it
10433 // to the rolling cost variable.
10434 if (second_ref_frame > INTRA_FRAME) {
10435 rate2 += ref_costs_comp[ref_frame];
10436#if CONFIG_EXT_REFS
10437 rate2 += ref_costs_comp[second_ref_frame];
10438#endif // CONFIG_EXT_REFS
10439 } else {
10440 rate2 += ref_costs_single[ref_frame];
10441 }
10442
10443 if (!disable_skip) {
10444 // Skip is never coded at the segment level for sub8x8 blocks and instead
10445 // always coded in the bitstream at the mode info level.
10446
10447 if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
10448 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
10449 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
10450 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010451 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010452 } else {
10453 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070010454 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010455 distortion2 = total_sse;
10456 assert(total_sse >= 0);
10457 rate2 -= (rate_y + rate_uv);
10458 rate_y = 0;
10459 rate_uv = 0;
10460 this_skip2 = 1;
10461 }
10462 } else {
10463 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010464 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010465 }
10466
10467 // Calculate the final RD estimate for this mode.
10468 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10469 }
10470
10471 if (!disable_skip && ref_frame == INTRA_FRAME) {
10472 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070010473 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010474 }
10475
10476 // Did this mode help.. i.e. is it the new best mode
10477 if (this_rd < best_rd || x->skip) {
10478 if (!mode_excluded) {
10479 // Note index of best mode so far
10480 best_ref_index = ref_index;
10481
10482 if (ref_frame == INTRA_FRAME) {
10483 /* required for left and above block mv */
10484 mbmi->mv[0].as_int = 0;
10485 }
10486
10487 rd_cost->rate = rate2;
10488#if CONFIG_SUPERTX
10489 *returnrate_nocoef = rate2 - rate_y - rate_uv;
10490 if (!disable_skip)
10491 *returnrate_nocoef -=
Yaowu Xuf883b422016-08-30 14:01:10 -070010492 av1_cost_bit(av1_get_skip_prob(cm, xd), this_skip2);
10493 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
10494 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010495 assert(*returnrate_nocoef > 0);
10496#endif // CONFIG_SUPERTX
10497 rd_cost->dist = distortion2;
10498 rd_cost->rdcost = this_rd;
10499 best_rd = this_rd;
10500 best_yrd =
10501 best_rd - RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
10502 best_mbmode = *mbmi;
10503 best_skip2 = this_skip2;
10504
10505#if CONFIG_VAR_TX
10506 for (i = 0; i < MAX_MB_PLANE; ++i)
10507 memset(ctx->blk_skip[i], 0, sizeof(uint8_t) * ctx->num_4x4_blk);
10508#endif
10509
10510 for (i = 0; i < 4; i++) best_bmodes[i] = xd->mi[0]->bmi[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010511 }
10512 }
10513
10514 /* keep record of best compound/single-only prediction */
10515 if (!disable_skip && ref_frame != INTRA_FRAME) {
10516 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
10517
10518 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
10519 single_rate = rate2 - compmode_cost;
10520 hybrid_rate = rate2;
10521 } else {
10522 single_rate = rate2;
10523 hybrid_rate = rate2 + compmode_cost;
10524 }
10525
10526 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
10527 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
10528
10529 if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE])
10530 best_pred_rd[SINGLE_REFERENCE] = single_rd;
10531 else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE])
10532 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
10533
10534 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
10535 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
10536 }
10537
Yaowu Xuc27fc142016-08-22 16:08:15 -070010538 if (x->skip && !comp_pred) break;
10539 }
10540
10541 if (best_rd >= best_rd_so_far) {
10542 rd_cost->rate = INT_MAX;
10543 rd_cost->rdcost = INT64_MAX;
10544#if CONFIG_SUPERTX
10545 *returnrate_nocoef = INT_MAX;
10546#endif // CONFIG_SUPERTX
10547 return;
10548 }
10549
Yaowu Xuc27fc142016-08-22 16:08:15 -070010550 if (best_rd == INT64_MAX) {
10551 rd_cost->rate = INT_MAX;
10552 rd_cost->dist = INT64_MAX;
10553 rd_cost->rdcost = INT64_MAX;
10554#if CONFIG_SUPERTX
10555 *returnrate_nocoef = INT_MAX;
10556#endif // CONFIG_SUPERTX
10557 return;
10558 }
10559
10560#if CONFIG_DUAL_FILTER
10561 assert((cm->interp_filter == SWITCHABLE) ||
10562 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
10563 !is_inter_block(&best_mbmode));
10564#else
10565 assert((cm->interp_filter == SWITCHABLE) ||
10566 (cm->interp_filter == best_mbmode.interp_filter) ||
10567 !is_inter_block(&best_mbmode));
10568#endif
10569
Yaowu Xuf883b422016-08-30 14:01:10 -070010570 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
10571 sf->adaptive_rd_thresh, bsize, best_ref_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010572
10573 // macroblock modes
10574 *mbmi = best_mbmode;
10575#if CONFIG_VAR_TX && CONFIG_EXT_TX && CONFIG_RECT_TX
10576 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
10577#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
10578
10579 x->skip |= best_skip2;
10580 if (!is_inter_block(&best_mbmode)) {
10581 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
10582 } else {
10583 for (i = 0; i < 4; ++i)
10584 memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
10585
Yaowu Xuc27fc142016-08-22 16:08:15 -070010586#if CONFIG_REF_MV
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -070010587 mbmi->pred_mv[0].as_int = xd->mi[0]->bmi[3].pred_mv[0].as_int;
10588 mbmi->pred_mv[1].as_int = xd->mi[0]->bmi[3].pred_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010589#endif
Yaowu Xu4306b6e2016-09-27 12:55:32 -070010590 mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
10591 mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010592 }
10593
10594 for (i = 0; i < REFERENCE_MODES; ++i) {
10595 if (best_pred_rd[i] == INT64_MAX)
10596 best_pred_diff[i] = INT_MIN;
10597 else
10598 best_pred_diff[i] = best_rd - best_pred_rd[i];
10599 }
10600
10601 store_coding_context(x, ctx, best_ref_index, best_pred_diff, 0);
10602}
10603
Yue Chencb60b182016-10-13 15:18:22 -070010604#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070010605// This function has a structure similar to av1_build_obmc_inter_prediction
Yaowu Xuc27fc142016-08-22 16:08:15 -070010606//
10607// The OBMC predictor is computed as:
10608//
10609// PObmc(x,y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070010610// AOM_BLEND_A64(Mh(x),
10611// AOM_BLEND_A64(Mv(y), P(x,y), PAbove(x,y)),
Yaowu Xuc27fc142016-08-22 16:08:15 -070010612// PLeft(x, y))
10613//
Yaowu Xuf883b422016-08-30 14:01:10 -070010614// Scaling up by AOM_BLEND_A64_MAX_ALPHA ** 2 and omitting the intermediate
Yaowu Xuc27fc142016-08-22 16:08:15 -070010615// rounding, this can be written as:
10616//
Yaowu Xuf883b422016-08-30 14:01:10 -070010617// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * Pobmc(x,y) =
Yaowu Xuc27fc142016-08-22 16:08:15 -070010618// Mh(x) * Mv(y) * P(x,y) +
10619// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070010620// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010621//
10622// Where :
10623//
Yaowu Xuf883b422016-08-30 14:01:10 -070010624// Cv(y) = AOM_BLEND_A64_MAX_ALPHA - Mv(y)
10625// Ch(y) = AOM_BLEND_A64_MAX_ALPHA - Mh(y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010626//
10627// This function computes 'wsrc' and 'mask' as:
10628//
10629// wsrc(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070010630// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * src(x, y) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070010631// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070010632// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010633//
10634// mask(x, y) = Mh(x) * Mv(y)
10635//
10636// These can then be used to efficiently approximate the error for any
10637// predictor P in the context of the provided neighbouring predictors by
10638// computing:
10639//
10640// error(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070010641// wsrc(x, y) - mask(x, y) * P(x, y) / (AOM_BLEND_A64_MAX_ALPHA ** 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010642//
Yaowu Xuf883b422016-08-30 14:01:10 -070010643static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010644 const MACROBLOCKD *xd, int mi_row,
10645 int mi_col, const uint8_t *above,
10646 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -070010647 int left_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010648 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
10649 int row, col, i;
10650 const int bw = 8 * xd->n8_w;
10651 const int bh = 8 * xd->n8_h;
Yue Chene9638cc2016-10-10 12:37:54 -070010652 int32_t *mask_buf = x->mask_buf;
10653 int32_t *wsrc_buf = x->wsrc_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010654 const int wsrc_stride = bw;
10655 const int mask_stride = bw;
Yaowu Xuf883b422016-08-30 14:01:10 -070010656 const int src_scale = AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA;
10657#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010658 const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
10659#else
10660 const int is_hbd = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010661#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010662
10663 // plane 0 should not be subsampled
10664 assert(xd->plane[0].subsampling_x == 0);
10665 assert(xd->plane[0].subsampling_y == 0);
10666
Yaowu Xuf883b422016-08-30 14:01:10 -070010667 av1_zero_array(wsrc_buf, bw * bh);
10668 for (i = 0; i < bw * bh; ++i) mask_buf[i] = AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010669
10670 // handle above row
10671 if (xd->up_available) {
10672 const int overlap = num_4x4_blocks_high_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070010673 const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010674 const int mi_row_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070010675 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010676
10677 assert(miw > 0);
10678
10679 i = 0;
10680 do { // for each mi in the above row
10681 const int mi_col_offset = i;
10682 const MB_MODE_INFO *const above_mbmi =
10683 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
10684 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -070010685 AOMMIN(xd->n8_w, num_8x8_blocks_wide_lookup[above_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010686 const int neighbor_bw = mi_step * MI_SIZE;
10687
10688 if (is_neighbor_overlappable(above_mbmi)) {
10689 const int tmp_stride = above_stride;
10690 int32_t *wsrc = wsrc_buf + (i * MI_SIZE);
10691 int32_t *mask = mask_buf + (i * MI_SIZE);
10692
10693 if (!is_hbd) {
10694 const uint8_t *tmp = above;
10695
10696 for (row = 0; row < overlap; ++row) {
10697 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070010698 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010699 for (col = 0; col < neighbor_bw; ++col) {
10700 wsrc[col] = m1 * tmp[col];
10701 mask[col] = m0;
10702 }
10703 wsrc += wsrc_stride;
10704 mask += mask_stride;
10705 tmp += tmp_stride;
10706 }
Yaowu Xuf883b422016-08-30 14:01:10 -070010707#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010708 } else {
10709 const uint16_t *tmp = CONVERT_TO_SHORTPTR(above);
10710
10711 for (row = 0; row < overlap; ++row) {
10712 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070010713 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010714 for (col = 0; col < neighbor_bw; ++col) {
10715 wsrc[col] = m1 * tmp[col];
10716 mask[col] = m0;
10717 }
10718 wsrc += wsrc_stride;
10719 mask += mask_stride;
10720 tmp += tmp_stride;
10721 }
Yaowu Xuf883b422016-08-30 14:01:10 -070010722#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010723 }
10724 }
10725
10726 above += neighbor_bw;
10727 i += mi_step;
10728 } while (i < miw);
10729 }
10730
10731 for (i = 0; i < bw * bh; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -070010732 wsrc_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
10733 mask_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010734 }
10735
10736 // handle left column
10737 if (xd->left_available) {
10738 const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070010739 const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010740 const int mi_col_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070010741 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010742
10743 assert(mih > 0);
10744
10745 i = 0;
10746 do { // for each mi in the left column
10747 const int mi_row_offset = i;
10748 const MB_MODE_INFO *const left_mbmi =
10749 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
10750 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -070010751 AOMMIN(xd->n8_h, num_8x8_blocks_high_lookup[left_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010752 const int neighbor_bh = mi_step * MI_SIZE;
10753
10754 if (is_neighbor_overlappable(left_mbmi)) {
10755 const int tmp_stride = left_stride;
10756 int32_t *wsrc = wsrc_buf + (i * MI_SIZE * wsrc_stride);
10757 int32_t *mask = mask_buf + (i * MI_SIZE * mask_stride);
10758
10759 if (!is_hbd) {
10760 const uint8_t *tmp = left;
10761
10762 for (row = 0; row < neighbor_bh; ++row) {
10763 for (col = 0; col < overlap; ++col) {
10764 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070010765 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
10766 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
10767 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
10768 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010769 }
10770 wsrc += wsrc_stride;
10771 mask += mask_stride;
10772 tmp += tmp_stride;
10773 }
Yaowu Xuf883b422016-08-30 14:01:10 -070010774#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010775 } else {
10776 const uint16_t *tmp = CONVERT_TO_SHORTPTR(left);
10777
10778 for (row = 0; row < neighbor_bh; ++row) {
10779 for (col = 0; col < overlap; ++col) {
10780 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070010781 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
10782 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
10783 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
10784 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010785 }
10786 wsrc += wsrc_stride;
10787 mask += mask_stride;
10788 tmp += tmp_stride;
10789 }
Yaowu Xuf883b422016-08-30 14:01:10 -070010790#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010791 }
10792 }
10793
10794 left += neighbor_bh * left_stride;
10795 i += mi_step;
10796 } while (i < mih);
10797 }
10798
10799 if (!is_hbd) {
10800 const uint8_t *src = x->plane[0].src.buf;
10801
10802 for (row = 0; row < bh; ++row) {
10803 for (col = 0; col < bw; ++col) {
10804 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
10805 }
10806 wsrc_buf += wsrc_stride;
10807 src += x->plane[0].src.stride;
10808 }
Yaowu Xuf883b422016-08-30 14:01:10 -070010809#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010810 } else {
10811 const uint16_t *src = CONVERT_TO_SHORTPTR(x->plane[0].src.buf);
10812
10813 for (row = 0; row < bh; ++row) {
10814 for (col = 0; col < bw; ++col) {
10815 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
10816 }
10817 wsrc_buf += wsrc_stride;
10818 src += x->plane[0].src.stride;
10819 }
Yaowu Xuf883b422016-08-30 14:01:10 -070010820#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010821 }
10822}
Yue Chencb60b182016-10-13 15:18:22 -070010823#endif // CONFIG_MOTION_VAR